cursor-kit-cli 1.0.3 → 1.1.0-beta.2

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 CHANGED
@@ -25,6 +25,15 @@ npm install -g cursor-kit-cli
25
25
  npx cursor-kit-cli init
26
26
  ```
27
27
 
28
+ **CLI Aliases:** `cursor-kit`, `cursorkit`, or `ck`
29
+
30
+ ```bash
31
+ # All of these work
32
+ cursor-kit init
33
+ cursorkit init
34
+ ck init
35
+ ```
36
+
28
37
  ## ✨ Features
29
38
 
30
39
  - **📜 Commands** - Reusable prompt templates for common tasks
@@ -95,43 +104,53 @@ After running `cursor-kit init`, your project will have:
95
104
  ```
96
105
  your-project/
97
106
  └── .cursor/
98
- ├── commands/ # Prompt templates
107
+ ├── commands/ # Prompt templates (.md)
108
+ │ ├── debug.md
109
+ │ ├── docs.md
110
+ │ ├── explain.md
111
+ │ ├── fix.md
99
112
  │ ├── implementation.md
100
113
  │ ├── refactor.md
101
114
  │ ├── review.md
102
- │ ├── debug.md
103
- │ ├── explain.md
104
115
  │ └── test.md
105
- └── rules/ # AI behavior rules
106
- ├── typescript.mdc
107
- ├── react.mdc
108
- ├── testing.mdc
116
+ └── rules/ # AI behavior rules (.mdc)
117
+ ├── coding-style.mdc
118
+ ├── frontend-design-skills.mdc
109
119
  ├── git.mdc
120
+ ├── performance.mdc
121
+ ├── react.mdc
110
122
  ├── security.mdc
111
- └── performance.mdc
123
+ ├── testing.mdc
124
+ └── typescript.mdc
112
125
  ```
113
126
 
114
127
  ## 🎯 Included Templates
115
128
 
116
129
  ### Commands
130
+
117
131
  | Command | Description |
118
132
  |---------|-------------|
133
+ | `debug` | Systematic bug investigation |
134
+ | `docs` | Create or update documentation |
135
+ | `explain` | Clear technical explanations |
136
+ | `fix` | Diagnose and fix bugs with root cause analysis |
119
137
  | `implementation` | Convert feature ideas into actionable plans |
120
138
  | `refactor` | Improve code quality without changing behavior |
121
139
  | `review` | Comprehensive code review checklist |
122
- | `debug` | Systematic bug investigation |
123
- | `explain` | Clear technical explanations |
124
140
  | `test` | Generate comprehensive test suites |
125
141
 
126
142
  ### Rules
143
+
127
144
  | Rule | Description |
128
145
  |------|-------------|
129
- | `typescript` | TypeScript best practices |
130
- | `react` | React component patterns |
131
- | `testing` | Testing standards |
146
+ | `coding-style` | Core coding conventions and best practices |
147
+ | `frontend-design-skills` | Typography, aesthetics, and UI guidelines |
132
148
  | `git` | Commit and branching conventions |
149
+ | `performance` | Performance optimization patterns |
150
+ | `react` | React component patterns |
133
151
  | `security` | Security guidelines |
134
- | `performance` | Performance optimization |
152
+ | `testing` | Testing standards |
153
+ | `typescript` | TypeScript best practices |
135
154
 
136
155
  ## 🛠️ Development
137
156
 
@@ -141,15 +160,22 @@ git clone https://github.com/duongductrong/cursor-kit.git
141
160
  cd cursor-kit
142
161
 
143
162
  # Install dependencies
144
- npm install
163
+ pnpm install
145
164
 
146
165
  # Build
147
- npm run build
166
+ pnpm build
148
167
 
149
168
  # Run locally
150
- node dist/cli.mjs
169
+ node dist/cli.js
170
+
171
+ # Development mode (watch)
172
+ pnpm dev
151
173
  ```
152
174
 
175
+ ### Requirements
176
+
177
+ - Node.js >= 18.0.0
178
+
153
179
  ## 📄 License
154
180
 
155
181
  MIT © [duongductrong](https://github.com/duongductrong)
@@ -159,4 +185,3 @@ MIT © [duongductrong](https://github.com/duongductrong)
159
185
  <p align="center">
160
186
  Made with ♥ for the Cursor community
161
187
  </p>
162
-
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(" v") + cursorGradient(version) + import_picocolors.default.dim(" \u2022 Made with \u2665")
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 import_giget = require("giget");
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
- 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");
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
- 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");
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
- 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
- });
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 (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
- });
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 import_node_path2 = require("path");
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, import_node_path2.join)(targetDir, `${slug}${extension}`);
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 import_giget2 = require("giget");
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, import_giget2.downloadTemplate)(`${REPO_URL}/templates/commands#${REPO_REF}`, {
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, import_giget2.downloadTemplate)(`${REPO_URL}/templates/rules#${REPO_REF}`, {
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 import_node_path3 = require("path");
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, import_node_path3.join)(dir, file);
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 import_node_path4 = require("path");
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, import_node_path4.join)(dir, `${itemName}${extension}`);
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: "0.1.0",
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("0.1.0");
953
+ printVersion(pkg.version);
699
954
  },
700
955
  subCommands: {
701
956
  init: initCommand,