@adobe-commerce/aio-toolkit 1.0.13 → 1.0.15
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/CHANGELOG.md +116 -0
- package/README.md +122 -9
- package/dist/aio-toolkit-cursor-context/bin/cli.js +1089 -0
- package/dist/aio-toolkit-cursor-context/bin/cli.js.map +1 -0
- package/dist/index.d.mts +43 -16
- package/dist/index.d.ts +43 -16
- package/dist/index.js +1030 -166
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1034 -167
- package/dist/index.mjs.map +1 -1
- package/files/cursor-context/commands/aio-toolkit-create-event-consumer-action.md +562 -0
- package/files/cursor-context/commands/aio-toolkit-create-graphql-action.md +531 -0
- package/files/cursor-context/commands/aio-toolkit-create-runtime-action.md +293 -0
- package/files/cursor-context/commands/aio-toolkit-create-webhook-action.md +439 -0
- package/files/cursor-context/rules/aio-toolkit-create-adobe-commerce-client.mdc +1321 -0
- package/files/cursor-context/rules/aio-toolkit-oop-best-practices.mdc +331 -0
- package/files/cursor-context/rules/aio-toolkit-setup-new-relic-telemetry.mdc +354 -0
- package/package.json +6 -1
|
@@ -0,0 +1,1089 @@
|
|
|
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 __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
10
|
+
var __esm = (fn, res) => function __init() {
|
|
11
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
12
|
+
};
|
|
13
|
+
var __export = (target, all) => {
|
|
14
|
+
for (var name in all)
|
|
15
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
16
|
+
};
|
|
17
|
+
var __copyProps = (to, from, except, desc) => {
|
|
18
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
19
|
+
for (let key of __getOwnPropNames(from))
|
|
20
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
21
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
22
|
+
}
|
|
23
|
+
return to;
|
|
24
|
+
};
|
|
25
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
26
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
27
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
28
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
29
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
30
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
31
|
+
mod
|
|
32
|
+
));
|
|
33
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
34
|
+
|
|
35
|
+
// src/commands/framework/command/base-context-help/index.ts
|
|
36
|
+
var _BaseContextHelp, BaseContextHelp;
|
|
37
|
+
var init_base_context_help = __esm({
|
|
38
|
+
"src/commands/framework/command/base-context-help/index.ts"() {
|
|
39
|
+
"use strict";
|
|
40
|
+
_BaseContextHelp = class _BaseContextHelp {
|
|
41
|
+
/**
|
|
42
|
+
* Static method to get the commands - must be implemented by subclasses
|
|
43
|
+
*
|
|
44
|
+
* @returns {CommandDescriptor[]} The commands
|
|
45
|
+
*/
|
|
46
|
+
static getCliName() {
|
|
47
|
+
throw new Error("getCliName() must be implemented by subclass");
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get the commands dynamically
|
|
51
|
+
*
|
|
52
|
+
* @returns {CommandDescriptor[]} The commands array
|
|
53
|
+
*/
|
|
54
|
+
static getCommands() {
|
|
55
|
+
throw new Error("getCommands() must be implemented by subclass");
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Static execute method that returns the help text
|
|
59
|
+
*
|
|
60
|
+
* @returns {CommandResult} The command result with help text
|
|
61
|
+
*/
|
|
62
|
+
static execute() {
|
|
63
|
+
const helpText = [
|
|
64
|
+
this.getUsageSection(),
|
|
65
|
+
this.getCommandsSection(),
|
|
66
|
+
this.getExamplesSection(),
|
|
67
|
+
this.getFooterSection()
|
|
68
|
+
].join("\n");
|
|
69
|
+
return {
|
|
70
|
+
success: true,
|
|
71
|
+
message: helpText
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get the usage section
|
|
76
|
+
*
|
|
77
|
+
* @returns {string} The usage section
|
|
78
|
+
*/
|
|
79
|
+
static getUsageSection() {
|
|
80
|
+
return `Usage: npx ${this.getCliName()} <command>`;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get the commands section
|
|
84
|
+
*
|
|
85
|
+
* @returns {string} The commands section
|
|
86
|
+
*/
|
|
87
|
+
static getCommandsSection() {
|
|
88
|
+
const commands = this.getCommands();
|
|
89
|
+
const maxNameLength = Math.max(...commands.map((cmd) => cmd.name.length));
|
|
90
|
+
const commandsList = commands.map((cmd) => ` ${cmd.name.padEnd(maxNameLength + 2)}${cmd.description}`).join("\n");
|
|
91
|
+
return `
|
|
92
|
+
Commands:
|
|
93
|
+
${commandsList}`;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get the examples section
|
|
97
|
+
*
|
|
98
|
+
* @returns {string} The examples section
|
|
99
|
+
*/
|
|
100
|
+
static getExamplesSection() {
|
|
101
|
+
const commands = this.getCommands();
|
|
102
|
+
const examples = commands.map((cmd) => ` npx ${this.getCliName()} ${cmd.name}`).join("\n");
|
|
103
|
+
return `
|
|
104
|
+
Examples:
|
|
105
|
+
${examples}`;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get the footer section with additional information
|
|
109
|
+
*
|
|
110
|
+
* @returns {string} The footer section
|
|
111
|
+
*/
|
|
112
|
+
static getFooterSection() {
|
|
113
|
+
return `
|
|
114
|
+
For more information, visit:
|
|
115
|
+
${this.repositoryUrl}
|
|
116
|
+
`;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
__name(_BaseContextHelp, "BaseContextHelp");
|
|
120
|
+
/**
|
|
121
|
+
* Static command name
|
|
122
|
+
*/
|
|
123
|
+
_BaseContextHelp.NAME = "help";
|
|
124
|
+
/**
|
|
125
|
+
* Static command description
|
|
126
|
+
*/
|
|
127
|
+
_BaseContextHelp.DESCRIPTION = "Show help for the rules commands";
|
|
128
|
+
/**
|
|
129
|
+
* Static repository URL
|
|
130
|
+
*/
|
|
131
|
+
_BaseContextHelp.repositoryUrl = "https://github.com/adobe-commerce/aio-toolkit";
|
|
132
|
+
BaseContextHelp = _BaseContextHelp;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// src/commands/cursor-context/lib/help/index.ts
|
|
137
|
+
var _CursorContextHelp, CursorContextHelp;
|
|
138
|
+
var init_help = __esm({
|
|
139
|
+
"src/commands/cursor-context/lib/help/index.ts"() {
|
|
140
|
+
"use strict";
|
|
141
|
+
init_base_context_help();
|
|
142
|
+
_CursorContextHelp = class _CursorContextHelp extends BaseContextHelp {
|
|
143
|
+
/**
|
|
144
|
+
* Get the CLI name
|
|
145
|
+
* This is used to display the correct help text for the CLI.
|
|
146
|
+
*
|
|
147
|
+
* @returns {string} The CLI name
|
|
148
|
+
*/
|
|
149
|
+
static getCliName() {
|
|
150
|
+
return "aio-toolkit-cursor-context";
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get commands dynamically to avoid circular dependency
|
|
154
|
+
* This will be populated when CursorRules is initialized
|
|
155
|
+
*
|
|
156
|
+
* @returns {CommandDescriptor[]} The commands array
|
|
157
|
+
*/
|
|
158
|
+
static getCommands() {
|
|
159
|
+
const { CursorRules: CursorRules2 } = (init_lib(), __toCommonJS(lib_exports));
|
|
160
|
+
return CursorRules2.getCommands();
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
__name(_CursorContextHelp, "CursorContextHelp");
|
|
164
|
+
CursorContextHelp = _CursorContextHelp;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// src/commands/framework/helpers/package-rules-path/index.ts
|
|
169
|
+
var fs, path, _PackageRulesPath, PackageRulesPath;
|
|
170
|
+
var init_package_rules_path = __esm({
|
|
171
|
+
"src/commands/framework/helpers/package-rules-path/index.ts"() {
|
|
172
|
+
"use strict";
|
|
173
|
+
fs = __toESM(require("fs"));
|
|
174
|
+
path = __toESM(require("path"));
|
|
175
|
+
_PackageRulesPath = class _PackageRulesPath {
|
|
176
|
+
/**
|
|
177
|
+
* Get the package rules path
|
|
178
|
+
* @param {string} rulesPath - The relative path to rules within the package (e.g., 'src/cursor/rules')
|
|
179
|
+
* @returns {string | null} The absolute path to rules in the installed package, or null if not found
|
|
180
|
+
*/
|
|
181
|
+
static get(rulesPath) {
|
|
182
|
+
try {
|
|
183
|
+
const packageRoot = this.findPackageRoot();
|
|
184
|
+
if (packageRoot) {
|
|
185
|
+
const fullRulesPath = path.join(packageRoot, rulesPath);
|
|
186
|
+
if (fs.existsSync(fullRulesPath)) {
|
|
187
|
+
return fullRulesPath;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
} catch {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Find the package root directory
|
|
197
|
+
* @returns {string | null} The package root path or null if not found
|
|
198
|
+
*/
|
|
199
|
+
static findPackageRoot() {
|
|
200
|
+
let currentDir = __dirname;
|
|
201
|
+
for (let i = 0; i < 10; i++) {
|
|
202
|
+
const packageJsonPath = path.join(currentDir, "package.json");
|
|
203
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
204
|
+
try {
|
|
205
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
206
|
+
if (packageJson.name === "@adobe-commerce/aio-toolkit") {
|
|
207
|
+
return currentDir;
|
|
208
|
+
}
|
|
209
|
+
} catch {
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const parentDir = path.dirname(currentDir);
|
|
213
|
+
if (parentDir === currentDir) break;
|
|
214
|
+
currentDir = parentDir;
|
|
215
|
+
}
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
__name(_PackageRulesPath, "PackageRulesPath");
|
|
220
|
+
PackageRulesPath = _PackageRulesPath;
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// src/commands/framework/helpers/rule-files/index.ts
|
|
225
|
+
var fs2, _RuleFiles, RuleFiles;
|
|
226
|
+
var init_rule_files = __esm({
|
|
227
|
+
"src/commands/framework/helpers/rule-files/index.ts"() {
|
|
228
|
+
"use strict";
|
|
229
|
+
fs2 = __toESM(require("fs"));
|
|
230
|
+
_RuleFiles = class _RuleFiles {
|
|
231
|
+
/**
|
|
232
|
+
* Get all rule files from a directory
|
|
233
|
+
* @param {string} dirPath - The path to the directory containing rule files
|
|
234
|
+
* @returns {string[]} Array of rule file names
|
|
235
|
+
*/
|
|
236
|
+
static get(dirPath) {
|
|
237
|
+
try {
|
|
238
|
+
if (!fs2.existsSync(dirPath)) {
|
|
239
|
+
return [];
|
|
240
|
+
}
|
|
241
|
+
const files = fs2.readdirSync(dirPath);
|
|
242
|
+
return files.filter((file) => this.ruleExtensions.some((ext) => file.endsWith(ext)));
|
|
243
|
+
} catch {
|
|
244
|
+
return [];
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
__name(_RuleFiles, "RuleFiles");
|
|
249
|
+
_RuleFiles.ruleExtensions = [".mdc", ".md"];
|
|
250
|
+
RuleFiles = _RuleFiles;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// src/commands/framework/helpers/directory-exists/index.ts
|
|
255
|
+
var fs3, _DirectoryExists, DirectoryExists;
|
|
256
|
+
var init_directory_exists = __esm({
|
|
257
|
+
"src/commands/framework/helpers/directory-exists/index.ts"() {
|
|
258
|
+
"use strict";
|
|
259
|
+
fs3 = __toESM(require("fs"));
|
|
260
|
+
_DirectoryExists = class _DirectoryExists {
|
|
261
|
+
/**
|
|
262
|
+
* Check if a directory exists
|
|
263
|
+
* @param {string} dirPath - The directory path to check
|
|
264
|
+
* @returns {boolean} True if directory exists and is a directory
|
|
265
|
+
*/
|
|
266
|
+
static is(dirPath) {
|
|
267
|
+
try {
|
|
268
|
+
return fs3.existsSync(dirPath) && fs3.statSync(dirPath).isDirectory();
|
|
269
|
+
} catch {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Ensure a directory exists, create if it doesn't
|
|
275
|
+
* @param {string} dirPath - The directory path to ensure
|
|
276
|
+
* @returns {void}
|
|
277
|
+
*/
|
|
278
|
+
static ensure(dirPath) {
|
|
279
|
+
if (!this.is(dirPath)) {
|
|
280
|
+
fs3.mkdirSync(dirPath, { recursive: true });
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
__name(_DirectoryExists, "DirectoryExists");
|
|
285
|
+
DirectoryExists = _DirectoryExists;
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
// src/commands/framework/helpers/format-messages/index.ts
|
|
290
|
+
var _FormatMessages, FormatMessages;
|
|
291
|
+
var init_format_messages = __esm({
|
|
292
|
+
"src/commands/framework/helpers/format-messages/index.ts"() {
|
|
293
|
+
"use strict";
|
|
294
|
+
_FormatMessages = class _FormatMessages {
|
|
295
|
+
/**
|
|
296
|
+
* Format an array of messages into a single string
|
|
297
|
+
* @param {string[]} messages - Array of message lines
|
|
298
|
+
* @returns {string} Formatted message string
|
|
299
|
+
*/
|
|
300
|
+
static execute(messages) {
|
|
301
|
+
return messages.join("\n");
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
__name(_FormatMessages, "FormatMessages");
|
|
305
|
+
FormatMessages = _FormatMessages;
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
// src/commands/framework/helpers/package-path/index.ts
|
|
310
|
+
var fs4, path2, _PackagePath, PackagePath;
|
|
311
|
+
var init_package_path = __esm({
|
|
312
|
+
"src/commands/framework/helpers/package-path/index.ts"() {
|
|
313
|
+
"use strict";
|
|
314
|
+
fs4 = __toESM(require("fs"));
|
|
315
|
+
path2 = __toESM(require("path"));
|
|
316
|
+
_PackagePath = class _PackagePath {
|
|
317
|
+
/**
|
|
318
|
+
* Find the path to a package in node_modules
|
|
319
|
+
*
|
|
320
|
+
* @param {string} packageName - The name of the package to find (e.g., '@adobe-commerce/commerce-extensibility-tools')
|
|
321
|
+
* @param {string} projectPath - The project root path (defaults to current directory)
|
|
322
|
+
* @returns {string | null} The absolute path to the package, or null if not found
|
|
323
|
+
*/
|
|
324
|
+
static find(packageName, projectPath = process.cwd()) {
|
|
325
|
+
try {
|
|
326
|
+
let currentDir = projectPath;
|
|
327
|
+
const maxIterations = 10;
|
|
328
|
+
for (let i = 0; i < maxIterations; i++) {
|
|
329
|
+
const nodeModulesPath = path2.join(currentDir, "node_modules");
|
|
330
|
+
if (fs4.existsSync(nodeModulesPath)) {
|
|
331
|
+
const packagePath = path2.join(nodeModulesPath, packageName);
|
|
332
|
+
if (fs4.existsSync(packagePath)) {
|
|
333
|
+
return packagePath;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
const parentDir = path2.dirname(currentDir);
|
|
337
|
+
if (parentDir === currentDir) {
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
currentDir = parentDir;
|
|
341
|
+
}
|
|
342
|
+
return null;
|
|
343
|
+
} catch (error) {
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Get the entry point file path for a package
|
|
349
|
+
*
|
|
350
|
+
* @param {string} packageName - The name of the package
|
|
351
|
+
* @param {string} projectPath - The project root path (defaults to current directory)
|
|
352
|
+
* @returns {string | null} The relative path from project root to the package entry point, or null if not found
|
|
353
|
+
*/
|
|
354
|
+
static getEntryPoint(packageName, projectPath = process.cwd()) {
|
|
355
|
+
try {
|
|
356
|
+
const packagePath = this.find(packageName, projectPath);
|
|
357
|
+
if (!packagePath) {
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
const packageJsonPath = path2.join(packagePath, "package.json");
|
|
361
|
+
if (!fs4.existsSync(packageJsonPath)) {
|
|
362
|
+
const defaultEntry = path2.join(packagePath, "index.js");
|
|
363
|
+
if (fs4.existsSync(defaultEntry)) {
|
|
364
|
+
return path2.relative(projectPath, defaultEntry);
|
|
365
|
+
}
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
const packageJson = JSON.parse(fs4.readFileSync(packageJsonPath, "utf-8"));
|
|
369
|
+
const entryPoint = packageJson.main || "index.js";
|
|
370
|
+
const entryPointPath = path2.join(packagePath, entryPoint);
|
|
371
|
+
if (!fs4.existsSync(entryPointPath)) {
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
return path2.relative(projectPath, entryPointPath);
|
|
375
|
+
} catch (error) {
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
__name(_PackagePath, "PackagePath");
|
|
381
|
+
PackagePath = _PackagePath;
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// src/commands/framework/helpers/mcp-config/index.ts
|
|
386
|
+
var fs5, path3, _McpConfig, McpConfig;
|
|
387
|
+
var init_mcp_config = __esm({
|
|
388
|
+
"src/commands/framework/helpers/mcp-config/index.ts"() {
|
|
389
|
+
"use strict";
|
|
390
|
+
fs5 = __toESM(require("fs"));
|
|
391
|
+
path3 = __toESM(require("path"));
|
|
392
|
+
init_package_path();
|
|
393
|
+
_McpConfig = class _McpConfig {
|
|
394
|
+
/**
|
|
395
|
+
* Create or update MCP configuration file
|
|
396
|
+
*
|
|
397
|
+
* @param {string} projectPath - The project root path (defaults to current directory)
|
|
398
|
+
* @returns {McpConfigResult} Result object with success status and reason
|
|
399
|
+
*/
|
|
400
|
+
static createOrUpdate(projectPath = process.cwd()) {
|
|
401
|
+
try {
|
|
402
|
+
const mcpFilePath = path3.join(projectPath, ".cursor", "mcp.json");
|
|
403
|
+
const packageName = "@adobe-commerce/commerce-extensibility-tools";
|
|
404
|
+
const packageEntryPoint = PackagePath.getEntryPoint(packageName, projectPath);
|
|
405
|
+
if (!packageEntryPoint) {
|
|
406
|
+
return {
|
|
407
|
+
success: false,
|
|
408
|
+
reason: "peer-dependency-missing",
|
|
409
|
+
message: `Package '${packageName}' not found. Install it to enable MCP server integration:
|
|
410
|
+
npm install ${packageName}`
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
const commerceExtensibilityConfig = {
|
|
414
|
+
command: "node",
|
|
415
|
+
args: [packageEntryPoint.replace(/\\/g, "/")],
|
|
416
|
+
// Normalize path separators for cross-platform
|
|
417
|
+
env: {}
|
|
418
|
+
};
|
|
419
|
+
let existingConfig = null;
|
|
420
|
+
const fileExists = fs5.existsSync(mcpFilePath);
|
|
421
|
+
if (fileExists) {
|
|
422
|
+
try {
|
|
423
|
+
const existingContent = fs5.readFileSync(mcpFilePath, "utf-8");
|
|
424
|
+
existingConfig = JSON.parse(existingContent);
|
|
425
|
+
} catch (error) {
|
|
426
|
+
existingConfig = null;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
const mcpConfig = {
|
|
430
|
+
mcpServers: existingConfig?.mcpServers ? {
|
|
431
|
+
...existingConfig.mcpServers,
|
|
432
|
+
"commerce-extensibility": commerceExtensibilityConfig
|
|
433
|
+
} : {
|
|
434
|
+
"commerce-extensibility": commerceExtensibilityConfig
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
fs5.writeFileSync(mcpFilePath, JSON.stringify(mcpConfig, null, 2) + "\n", "utf-8");
|
|
438
|
+
return {
|
|
439
|
+
success: true,
|
|
440
|
+
reason: fileExists ? "updated" : "created",
|
|
441
|
+
message: fileExists ? "MCP configuration updated at .cursor/mcp.json" : "MCP configuration created at .cursor/mcp.json"
|
|
442
|
+
};
|
|
443
|
+
} catch (error) {
|
|
444
|
+
return {
|
|
445
|
+
success: false,
|
|
446
|
+
reason: "error",
|
|
447
|
+
message: `Failed to create MCP config: ${error instanceof Error ? error.message : String(error)}`
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Check if MCP configuration exists
|
|
453
|
+
*
|
|
454
|
+
* @param {string} projectPath - The project root path (defaults to current directory)
|
|
455
|
+
* @returns {boolean} True if mcp.json exists, false otherwise
|
|
456
|
+
*/
|
|
457
|
+
static exists(projectPath = process.cwd()) {
|
|
458
|
+
const mcpFilePath = path3.join(projectPath, ".cursor", "mcp.json");
|
|
459
|
+
return fs5.existsSync(mcpFilePath);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Get the path to the MCP configuration file
|
|
463
|
+
*
|
|
464
|
+
* @param {string} projectPath - The project root path (defaults to current directory)
|
|
465
|
+
* @returns {string} The path to mcp.json
|
|
466
|
+
*/
|
|
467
|
+
static getPath(projectPath = process.cwd()) {
|
|
468
|
+
return path3.join(projectPath, ".cursor", "mcp.json");
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
__name(_McpConfig, "McpConfig");
|
|
472
|
+
McpConfig = _McpConfig;
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
// src/commands/framework/helpers/cursor-ide-detector/index.ts
|
|
477
|
+
var os, _CursorIdeDetector, CursorIdeDetector;
|
|
478
|
+
var init_cursor_ide_detector = __esm({
|
|
479
|
+
"src/commands/framework/helpers/cursor-ide-detector/index.ts"() {
|
|
480
|
+
"use strict";
|
|
481
|
+
os = __toESM(require("os"));
|
|
482
|
+
_CursorIdeDetector = class _CursorIdeDetector {
|
|
483
|
+
/**
|
|
484
|
+
* Check if Cursor IDE is being used
|
|
485
|
+
* @returns {boolean} True if Cursor IDE is detected, false otherwise
|
|
486
|
+
*/
|
|
487
|
+
static isCursorIde() {
|
|
488
|
+
try {
|
|
489
|
+
if (process.env.CURSOR || process.env.CURSOR_IDE || process.env.CURSOR_TRACE_ID || process.env.CURSOR_AGENT || process.env.__CFBundleIdentifier && process.env.__CFBundleIdentifier.startsWith("com.todesktop.")) {
|
|
490
|
+
return true;
|
|
491
|
+
}
|
|
492
|
+
const execPath = process.execPath.toLowerCase();
|
|
493
|
+
const cursorPaths = ["cursor.app", "cursor.exe"];
|
|
494
|
+
const isMacOsSpecificPath = execPath.includes("/applications/cursor.app/contents");
|
|
495
|
+
if (cursorPaths.some((cursorPath) => execPath.includes(cursorPath)) && !isMacOsSpecificPath) {
|
|
496
|
+
return true;
|
|
497
|
+
}
|
|
498
|
+
if (process.env._) {
|
|
499
|
+
const parentProcess = process.env._.toLowerCase();
|
|
500
|
+
if (parentProcess.includes("cursor.app") || parentProcess.includes("cursor.exe") || parentProcess.endsWith("/cursor")) {
|
|
501
|
+
return true;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
const platform2 = os.platform();
|
|
505
|
+
if (platform2 === "darwin") {
|
|
506
|
+
if (execPath.includes("/applications/cursor.app/contents")) {
|
|
507
|
+
return true;
|
|
508
|
+
}
|
|
509
|
+
} else if (platform2 === "win32") {
|
|
510
|
+
if (execPath.includes("cursor") && (execPath.includes("program files") || execPath.includes("localappdata") || execPath.includes("appdata"))) {
|
|
511
|
+
return true;
|
|
512
|
+
}
|
|
513
|
+
} else if (platform2 === "linux") {
|
|
514
|
+
if (execPath.includes("cursor") && (execPath.includes("/opt/cursor") || execPath.includes("/usr/share/cursor") || execPath.includes("/.local/share/cursor"))) {
|
|
515
|
+
return true;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return false;
|
|
519
|
+
} catch {
|
|
520
|
+
return false;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Get a user-friendly message about Cursor IDE detection
|
|
525
|
+
* @returns {string} Message about Cursor IDE status
|
|
526
|
+
*/
|
|
527
|
+
static getDetectionMessage() {
|
|
528
|
+
if (this.isCursorIde()) {
|
|
529
|
+
return "\u2705 Cursor IDE detected";
|
|
530
|
+
}
|
|
531
|
+
return "\u26A0\uFE0F Cursor IDE not detected - cursor rules may not work in other IDEs";
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
__name(_CursorIdeDetector, "CursorIdeDetector");
|
|
535
|
+
CursorIdeDetector = _CursorIdeDetector;
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
// src/commands/framework/helpers/index.ts
|
|
540
|
+
var init_helpers = __esm({
|
|
541
|
+
"src/commands/framework/helpers/index.ts"() {
|
|
542
|
+
"use strict";
|
|
543
|
+
init_package_rules_path();
|
|
544
|
+
init_rule_files();
|
|
545
|
+
init_directory_exists();
|
|
546
|
+
init_format_messages();
|
|
547
|
+
init_package_path();
|
|
548
|
+
init_mcp_config();
|
|
549
|
+
init_cursor_ide_detector();
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
// src/commands/framework/command/base-context-check/index.ts
|
|
554
|
+
var path4, _BaseContextCheck, BaseContextCheck;
|
|
555
|
+
var init_base_context_check = __esm({
|
|
556
|
+
"src/commands/framework/command/base-context-check/index.ts"() {
|
|
557
|
+
"use strict";
|
|
558
|
+
path4 = __toESM(require("path"));
|
|
559
|
+
init_helpers();
|
|
560
|
+
_BaseContextCheck = class _BaseContextCheck {
|
|
561
|
+
/**
|
|
562
|
+
* Get the directory paths to check
|
|
563
|
+
* This is used to check if the context directories exist.
|
|
564
|
+
*
|
|
565
|
+
* @returns {string[]} Array of directory paths relative to project root
|
|
566
|
+
*/
|
|
567
|
+
static getDirs() {
|
|
568
|
+
throw new Error("getDirs() must be implemented by subclass");
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Static execute method to check and return the result
|
|
572
|
+
*
|
|
573
|
+
* @param {string} projectPath - The path to the project root (defaults to current directory)
|
|
574
|
+
* @returns {Promise<CommandResult>} The check result
|
|
575
|
+
*/
|
|
576
|
+
static async execute(projectPath = process.cwd()) {
|
|
577
|
+
const dirs = this.getDirs();
|
|
578
|
+
const missingDirs = [];
|
|
579
|
+
const existingDirs = [];
|
|
580
|
+
const allContextFiles = [];
|
|
581
|
+
for (const dir of dirs) {
|
|
582
|
+
const contextPath = path4.join(projectPath, dir);
|
|
583
|
+
if (!DirectoryExists.is(contextPath)) {
|
|
584
|
+
missingDirs.push(dir);
|
|
585
|
+
} else {
|
|
586
|
+
existingDirs.push(dir);
|
|
587
|
+
const contextFiles = RuleFiles.get(contextPath);
|
|
588
|
+
if (contextFiles.length > 0) {
|
|
589
|
+
allContextFiles.push({ dir, files: contextFiles });
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
if (existingDirs.length === 0) {
|
|
594
|
+
return {
|
|
595
|
+
success: false,
|
|
596
|
+
message: FormatMessages.execute([
|
|
597
|
+
"\u274C Context directories not found",
|
|
598
|
+
"--------------------------------",
|
|
599
|
+
CursorIdeDetector.getDetectionMessage(),
|
|
600
|
+
"",
|
|
601
|
+
`The following directories do not exist:`,
|
|
602
|
+
...missingDirs.map((dir) => ` - ${dir}`),
|
|
603
|
+
"Run: npx aio-toolkit-cursor-context apply"
|
|
604
|
+
])
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
if (allContextFiles.length === 0) {
|
|
608
|
+
return {
|
|
609
|
+
success: false,
|
|
610
|
+
message: FormatMessages.execute([
|
|
611
|
+
"\u274C No context files found",
|
|
612
|
+
"--------------------------------",
|
|
613
|
+
CursorIdeDetector.getDetectionMessage(),
|
|
614
|
+
"",
|
|
615
|
+
`No context files (.mdc, .md) found in:`,
|
|
616
|
+
...existingDirs.map((dir) => ` - ${dir}`),
|
|
617
|
+
"Run: npx aio-toolkit-cursor-context apply"
|
|
618
|
+
])
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
const totalFiles = allContextFiles.reduce((sum, item) => sum + item.files.length, 0);
|
|
622
|
+
const messages = [
|
|
623
|
+
"\u2705 Contexts are applied to the project",
|
|
624
|
+
"--------------------------------",
|
|
625
|
+
CursorIdeDetector.getDetectionMessage(),
|
|
626
|
+
"",
|
|
627
|
+
`Found ${totalFiles} context file${totalFiles > 1 ? "s" : ""} across ${allContextFiles.length} director${allContextFiles.length > 1 ? "ies" : "y"}:`
|
|
628
|
+
];
|
|
629
|
+
for (const { dir, files } of allContextFiles) {
|
|
630
|
+
messages.push(`
|
|
631
|
+
${dir}:`);
|
|
632
|
+
files.forEach((file) => messages.push(` - ${file}`));
|
|
633
|
+
}
|
|
634
|
+
if (missingDirs.length > 0) {
|
|
635
|
+
messages.push("\n\u26A0\uFE0F Missing directories:");
|
|
636
|
+
missingDirs.forEach((dir) => messages.push(` - ${dir}`));
|
|
637
|
+
}
|
|
638
|
+
const mcpExists = McpConfig.exists(projectPath);
|
|
639
|
+
messages.push("");
|
|
640
|
+
if (mcpExists) {
|
|
641
|
+
messages.push("\u2705 MCP server configuration found at .cursor/mcp.json");
|
|
642
|
+
} else {
|
|
643
|
+
messages.push("\u26A0\uFE0F MCP server configuration not found");
|
|
644
|
+
messages.push(" Run: npx aio-toolkit-cursor-context apply");
|
|
645
|
+
}
|
|
646
|
+
return {
|
|
647
|
+
success: true,
|
|
648
|
+
message: FormatMessages.execute(messages)
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
__name(_BaseContextCheck, "BaseContextCheck");
|
|
653
|
+
/**
|
|
654
|
+
* Static command name
|
|
655
|
+
*/
|
|
656
|
+
_BaseContextCheck.NAME = "check";
|
|
657
|
+
/**
|
|
658
|
+
* Static command description
|
|
659
|
+
*/
|
|
660
|
+
_BaseContextCheck.DESCRIPTION = "Check contexts are applied to the project";
|
|
661
|
+
BaseContextCheck = _BaseContextCheck;
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
// src/commands/cursor-context/lib/check/index.ts
|
|
666
|
+
var path5, _CursorContextCheck, CursorContextCheck;
|
|
667
|
+
var init_check = __esm({
|
|
668
|
+
"src/commands/cursor-context/lib/check/index.ts"() {
|
|
669
|
+
"use strict";
|
|
670
|
+
path5 = __toESM(require("path"));
|
|
671
|
+
init_base_context_check();
|
|
672
|
+
_CursorContextCheck = class _CursorContextCheck extends BaseContextCheck {
|
|
673
|
+
/**
|
|
674
|
+
* Get the directory paths to check
|
|
675
|
+
* This is used to check if the context directories exist.
|
|
676
|
+
*
|
|
677
|
+
* @returns {string[]} Array of directory paths relative to project root
|
|
678
|
+
*/
|
|
679
|
+
static getDirs() {
|
|
680
|
+
return [path5.join(".cursor", "rules"), path5.join(".cursor", "commands")];
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
__name(_CursorContextCheck, "CursorContextCheck");
|
|
684
|
+
CursorContextCheck = _CursorContextCheck;
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
// src/commands/framework/command/base-rule-apply/index.ts
|
|
689
|
+
var fs6, path6, _BaseRuleApply, BaseRuleApply;
|
|
690
|
+
var init_base_rule_apply = __esm({
|
|
691
|
+
"src/commands/framework/command/base-rule-apply/index.ts"() {
|
|
692
|
+
"use strict";
|
|
693
|
+
fs6 = __toESM(require("fs"));
|
|
694
|
+
path6 = __toESM(require("path"));
|
|
695
|
+
init_format_messages();
|
|
696
|
+
init_helpers();
|
|
697
|
+
_BaseRuleApply = class _BaseRuleApply {
|
|
698
|
+
/**
|
|
699
|
+
* Get the copy directories configuration
|
|
700
|
+
* @returns {Record<string, { from: string; to: string }>} Object with directory pairs to copy
|
|
701
|
+
*/
|
|
702
|
+
static getCopyDirs() {
|
|
703
|
+
throw new Error("getCopyDirs() must be implemented by subclass");
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Check if IDE detection is required before applying contexts
|
|
707
|
+
* Override this method in subclasses to enable IDE detection
|
|
708
|
+
* @returns {boolean} True if IDE detection should be performed
|
|
709
|
+
*/
|
|
710
|
+
static shouldCheckIde() {
|
|
711
|
+
return false;
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Static execute method to apply contexts
|
|
715
|
+
* @param {string} projectPath - The path to the project root (defaults to current directory)
|
|
716
|
+
* @param {string[]} args - Command arguments
|
|
717
|
+
* @returns {Promise<CommandResult>} The apply result
|
|
718
|
+
*/
|
|
719
|
+
static async execute(projectPath = process.cwd(), args2 = []) {
|
|
720
|
+
let actualProjectPath = projectPath;
|
|
721
|
+
let actualArgs = args2;
|
|
722
|
+
if (projectPath.startsWith("-")) {
|
|
723
|
+
actualProjectPath = process.cwd();
|
|
724
|
+
actualArgs = [projectPath, ...args2];
|
|
725
|
+
}
|
|
726
|
+
const forceOverwrite = actualArgs.includes("--force") || actualArgs.includes("-f");
|
|
727
|
+
if (!forceOverwrite && this.shouldCheckIde() && !CursorIdeDetector.isCursorIde()) {
|
|
728
|
+
return {
|
|
729
|
+
success: false,
|
|
730
|
+
message: FormatMessages.execute([
|
|
731
|
+
"\u274C Cursor IDE not detected",
|
|
732
|
+
"--------------------------------",
|
|
733
|
+
CursorIdeDetector.getDetectionMessage(),
|
|
734
|
+
"",
|
|
735
|
+
"Cursor contexts can only be applied when using Cursor IDE.",
|
|
736
|
+
"Please run this command from within Cursor IDE.",
|
|
737
|
+
"",
|
|
738
|
+
"\u2139\uFE0F Use --force or -f to bypass this check and apply contexts anyway."
|
|
739
|
+
])
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
try {
|
|
743
|
+
const copyDirs = this.getCopyDirs();
|
|
744
|
+
const dirKeys = Object.keys(copyDirs);
|
|
745
|
+
if (dirKeys.length === 0) {
|
|
746
|
+
return {
|
|
747
|
+
success: false,
|
|
748
|
+
message: FormatMessages.execute([
|
|
749
|
+
"\u274C No directories configured",
|
|
750
|
+
"--------------------------------",
|
|
751
|
+
"The getCopyDirs() method must return at least one directory pair"
|
|
752
|
+
])
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
const allResults = {};
|
|
756
|
+
for (const dirKey of dirKeys) {
|
|
757
|
+
const dirConfig = copyDirs[dirKey];
|
|
758
|
+
if (!dirConfig) {
|
|
759
|
+
continue;
|
|
760
|
+
}
|
|
761
|
+
const { from: sourceRelativePath, to: destRelativePath } = dirConfig;
|
|
762
|
+
const sourcePath = PackageRulesPath.get(sourceRelativePath);
|
|
763
|
+
if (!sourcePath) {
|
|
764
|
+
return {
|
|
765
|
+
success: false,
|
|
766
|
+
message: FormatMessages.execute([
|
|
767
|
+
"\u274C Could not find contexts in package",
|
|
768
|
+
"--------------------------------",
|
|
769
|
+
"The package context directory does not exist",
|
|
770
|
+
`Expected at: ${sourceRelativePath}`
|
|
771
|
+
])
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
const contextFiles = RuleFiles.get(sourcePath);
|
|
775
|
+
if (contextFiles.length === 0) {
|
|
776
|
+
return {
|
|
777
|
+
success: false,
|
|
778
|
+
message: FormatMessages.execute([
|
|
779
|
+
"\u274C No contexts found to apply",
|
|
780
|
+
"--------------------------------",
|
|
781
|
+
"The package does not contain any context files",
|
|
782
|
+
`Checked directory: ${sourceRelativePath}`
|
|
783
|
+
])
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
const destPath = path6.join(actualProjectPath, destRelativePath);
|
|
787
|
+
DirectoryExists.ensure(destPath);
|
|
788
|
+
allResults[dirKey] = {
|
|
789
|
+
copiedFiles: [],
|
|
790
|
+
skippedFiles: [],
|
|
791
|
+
overwrittenFiles: [],
|
|
792
|
+
sourcePath,
|
|
793
|
+
destPath: destRelativePath
|
|
794
|
+
};
|
|
795
|
+
for (const file of contextFiles) {
|
|
796
|
+
const sourceFilePath = path6.join(sourcePath, file);
|
|
797
|
+
const destFilePath = path6.join(destPath, file);
|
|
798
|
+
const fileExists = fs6.existsSync(destFilePath);
|
|
799
|
+
if (forceOverwrite) {
|
|
800
|
+
fs6.copyFileSync(sourceFilePath, destFilePath);
|
|
801
|
+
if (fileExists) {
|
|
802
|
+
allResults[dirKey].overwrittenFiles.push(file);
|
|
803
|
+
} else {
|
|
804
|
+
allResults[dirKey].copiedFiles.push(file);
|
|
805
|
+
}
|
|
806
|
+
} else {
|
|
807
|
+
if (!fileExists) {
|
|
808
|
+
fs6.copyFileSync(sourceFilePath, destFilePath);
|
|
809
|
+
allResults[dirKey].copiedFiles.push(file);
|
|
810
|
+
} else {
|
|
811
|
+
allResults[dirKey].skippedFiles.push(file);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
const mcpResult = McpConfig.createOrUpdate(actualProjectPath);
|
|
817
|
+
const messages = [];
|
|
818
|
+
const totalCopied = Object.values(allResults).reduce(
|
|
819
|
+
(sum, r) => sum + r.copiedFiles.length,
|
|
820
|
+
0
|
|
821
|
+
);
|
|
822
|
+
const totalSkipped = Object.values(allResults).reduce(
|
|
823
|
+
(sum, r) => sum + r.skippedFiles.length,
|
|
824
|
+
0
|
|
825
|
+
);
|
|
826
|
+
if (forceOverwrite) {
|
|
827
|
+
messages.push(
|
|
828
|
+
"\u2705 Contexts applied successfully (force mode)!",
|
|
829
|
+
"--------------------------------"
|
|
830
|
+
);
|
|
831
|
+
for (const dirKey of dirKeys) {
|
|
832
|
+
const result = allResults[dirKey];
|
|
833
|
+
if (!result) {
|
|
834
|
+
continue;
|
|
835
|
+
}
|
|
836
|
+
if (result.copiedFiles.length > 0 || result.overwrittenFiles.length > 0) {
|
|
837
|
+
messages.push(`
|
|
838
|
+
${dirKey.toUpperCase()}:`);
|
|
839
|
+
if (result.copiedFiles.length > 0) {
|
|
840
|
+
messages.push(
|
|
841
|
+
` Copied ${result.copiedFiles.length} new context file${result.copiedFiles.length > 1 ? "s" : ""} to ${result.destPath}:`,
|
|
842
|
+
...result.copiedFiles.map((file) => ` \u2713 ${file}`)
|
|
843
|
+
);
|
|
844
|
+
}
|
|
845
|
+
if (result.overwrittenFiles.length > 0) {
|
|
846
|
+
if (result.copiedFiles.length > 0) {
|
|
847
|
+
messages.push("");
|
|
848
|
+
}
|
|
849
|
+
messages.push(
|
|
850
|
+
` Overwritten ${result.overwrittenFiles.length} existing context file${result.overwrittenFiles.length > 1 ? "s" : ""}:`,
|
|
851
|
+
...result.overwrittenFiles.map((file) => ` \u21BB ${file}`)
|
|
852
|
+
);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
messages.push("");
|
|
857
|
+
if (mcpResult.success) {
|
|
858
|
+
messages.push(`\u2713 ${mcpResult.message}`, "");
|
|
859
|
+
} else if (mcpResult.reason === "peer-dependency-missing") {
|
|
860
|
+
messages.push(`\u26A0\uFE0F ${mcpResult.message}`, "");
|
|
861
|
+
}
|
|
862
|
+
messages.push("\u26A0\uFE0F Please restart your IDE to load the updated contexts");
|
|
863
|
+
} else {
|
|
864
|
+
if (totalCopied === 0 && totalSkipped > 0) {
|
|
865
|
+
messages.push("\u2705 All contexts are already applied!", "--------------------------------");
|
|
866
|
+
for (const dirKey of dirKeys) {
|
|
867
|
+
const result = allResults[dirKey];
|
|
868
|
+
if (!result) {
|
|
869
|
+
continue;
|
|
870
|
+
}
|
|
871
|
+
if (result.skippedFiles.length > 0) {
|
|
872
|
+
messages.push(
|
|
873
|
+
`
|
|
874
|
+
${dirKey.toUpperCase()}:`,
|
|
875
|
+
` All ${result.skippedFiles.length} context file${result.skippedFiles.length > 1 ? "s" : ""} already exist in ${result.destPath}:`,
|
|
876
|
+
...result.skippedFiles.map((file) => ` \u229D ${file}`)
|
|
877
|
+
);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
if (mcpResult.success) {
|
|
881
|
+
messages.push("", `\u2713 ${mcpResult.message}`);
|
|
882
|
+
} else if (mcpResult.reason === "peer-dependency-missing") {
|
|
883
|
+
messages.push("", `\u26A0\uFE0F ${mcpResult.message}`);
|
|
884
|
+
}
|
|
885
|
+
messages.push("", "\u2139\uFE0F Use --force or -f to overwrite existing contexts");
|
|
886
|
+
} else {
|
|
887
|
+
messages.push("\u2705 Contexts applied successfully!", "--------------------------------");
|
|
888
|
+
for (const dirKey of dirKeys) {
|
|
889
|
+
const result = allResults[dirKey];
|
|
890
|
+
if (!result) {
|
|
891
|
+
continue;
|
|
892
|
+
}
|
|
893
|
+
if (result.copiedFiles.length > 0 || result.skippedFiles.length > 0) {
|
|
894
|
+
messages.push(`
|
|
895
|
+
${dirKey.toUpperCase()}:`);
|
|
896
|
+
if (result.copiedFiles.length > 0) {
|
|
897
|
+
messages.push(
|
|
898
|
+
` Copied ${result.copiedFiles.length} new context file${result.copiedFiles.length > 1 ? "s" : ""} to ${result.destPath}:`,
|
|
899
|
+
...result.copiedFiles.map((file) => ` \u2713 ${file}`)
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
if (result.skippedFiles.length > 0) {
|
|
903
|
+
if (result.copiedFiles.length > 0) {
|
|
904
|
+
messages.push("");
|
|
905
|
+
}
|
|
906
|
+
messages.push(
|
|
907
|
+
` Skipped ${result.skippedFiles.length} existing context file${result.skippedFiles.length > 1 ? "s" : ""}:`,
|
|
908
|
+
...result.skippedFiles.map((file) => ` \u229D ${file}`),
|
|
909
|
+
"",
|
|
910
|
+
" \u2139\uFE0F Use --force or -f to overwrite existing contexts"
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
if (totalCopied > 0) {
|
|
916
|
+
messages.push("");
|
|
917
|
+
if (mcpResult.success) {
|
|
918
|
+
messages.push(`\u2713 ${mcpResult.message}`, "");
|
|
919
|
+
} else if (mcpResult.reason === "peer-dependency-missing") {
|
|
920
|
+
messages.push(`\u26A0\uFE0F ${mcpResult.message}`, "");
|
|
921
|
+
}
|
|
922
|
+
messages.push("\u26A0\uFE0F Please restart your IDE to load the new contexts");
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
return {
|
|
927
|
+
success: true,
|
|
928
|
+
message: FormatMessages.execute(messages)
|
|
929
|
+
};
|
|
930
|
+
} catch (error) {
|
|
931
|
+
return {
|
|
932
|
+
success: false,
|
|
933
|
+
message: FormatMessages.execute([
|
|
934
|
+
"\u274C Failed to apply contexts to the project",
|
|
935
|
+
"--------------------------------",
|
|
936
|
+
`Error: ${error instanceof Error ? error.message : String(error)}`
|
|
937
|
+
])
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
};
|
|
942
|
+
__name(_BaseRuleApply, "BaseRuleApply");
|
|
943
|
+
/**
|
|
944
|
+
* Static command name
|
|
945
|
+
*/
|
|
946
|
+
_BaseRuleApply.NAME = "apply";
|
|
947
|
+
/**
|
|
948
|
+
* Static command description
|
|
949
|
+
*/
|
|
950
|
+
_BaseRuleApply.DESCRIPTION = "Apply contexts to your project (use --force or -f to overwrite existing)";
|
|
951
|
+
BaseRuleApply = _BaseRuleApply;
|
|
952
|
+
}
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
// src/commands/cursor-context/lib/apply/index.ts
|
|
956
|
+
var path7, _CursorRuleApply, CursorRuleApply;
|
|
957
|
+
var init_apply = __esm({
|
|
958
|
+
"src/commands/cursor-context/lib/apply/index.ts"() {
|
|
959
|
+
"use strict";
|
|
960
|
+
path7 = __toESM(require("path"));
|
|
961
|
+
init_base_rule_apply();
|
|
962
|
+
_CursorRuleApply = class _CursorRuleApply extends BaseRuleApply {
|
|
963
|
+
/**
|
|
964
|
+
* Enable IDE detection for Cursor-specific contexts
|
|
965
|
+
* @returns {boolean} True to enable IDE detection
|
|
966
|
+
*/
|
|
967
|
+
static shouldCheckIde() {
|
|
968
|
+
return true;
|
|
969
|
+
}
|
|
970
|
+
/**
|
|
971
|
+
* Get the rules directory path
|
|
972
|
+
* @returns {string} The rules directory path
|
|
973
|
+
*/
|
|
974
|
+
static getCopyDirs() {
|
|
975
|
+
return {
|
|
976
|
+
rules: {
|
|
977
|
+
from: path7.join("files", "cursor-context", "rules"),
|
|
978
|
+
to: path7.join(".cursor", "rules")
|
|
979
|
+
},
|
|
980
|
+
commands: {
|
|
981
|
+
from: path7.join("files", "cursor-context", "commands"),
|
|
982
|
+
to: path7.join(".cursor", "commands")
|
|
983
|
+
}
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
__name(_CursorRuleApply, "CursorRuleApply");
|
|
988
|
+
CursorRuleApply = _CursorRuleApply;
|
|
989
|
+
}
|
|
990
|
+
});
|
|
991
|
+
|
|
992
|
+
// src/commands/framework/command/base-rules/index.ts
|
|
993
|
+
var _BaseRules, BaseRules;
|
|
994
|
+
var init_base_rules = __esm({
|
|
995
|
+
"src/commands/framework/command/base-rules/index.ts"() {
|
|
996
|
+
"use strict";
|
|
997
|
+
_BaseRules = class _BaseRules {
|
|
998
|
+
/**
|
|
999
|
+
* Static method to get the commands - must be implemented by subclasses
|
|
1000
|
+
*
|
|
1001
|
+
* @returns {CommandDescriptor[]} The commands
|
|
1002
|
+
*/
|
|
1003
|
+
static getCommands() {
|
|
1004
|
+
throw new Error("getCommands() must be implemented by subclass");
|
|
1005
|
+
}
|
|
1006
|
+
/**
|
|
1007
|
+
* Static execute method to execute a command
|
|
1008
|
+
*
|
|
1009
|
+
* @param {string} type - The name of the command to execute
|
|
1010
|
+
* @param {...any} args - The arguments to pass to the command
|
|
1011
|
+
* @returns {Promise<CommandResult>} The execution result
|
|
1012
|
+
*/
|
|
1013
|
+
static async execute(type = "help", ...args2) {
|
|
1014
|
+
const command2 = this.getCommands().find((cmd) => cmd.name === type);
|
|
1015
|
+
if (!command2) {
|
|
1016
|
+
return {
|
|
1017
|
+
success: false,
|
|
1018
|
+
message: `Unknown command: ${type}`
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
return await command2.execute(...args2);
|
|
1022
|
+
}
|
|
1023
|
+
};
|
|
1024
|
+
__name(_BaseRules, "BaseRules");
|
|
1025
|
+
BaseRules = _BaseRules;
|
|
1026
|
+
}
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
// src/commands/cursor-context/lib/index.ts
|
|
1030
|
+
var lib_exports = {};
|
|
1031
|
+
__export(lib_exports, {
|
|
1032
|
+
CursorRules: () => CursorRules
|
|
1033
|
+
});
|
|
1034
|
+
var _CursorRules, CursorRules;
|
|
1035
|
+
var init_lib = __esm({
|
|
1036
|
+
"src/commands/cursor-context/lib/index.ts"() {
|
|
1037
|
+
"use strict";
|
|
1038
|
+
init_help();
|
|
1039
|
+
init_check();
|
|
1040
|
+
init_apply();
|
|
1041
|
+
init_base_rules();
|
|
1042
|
+
_CursorRules = class _CursorRules extends BaseRules {
|
|
1043
|
+
/**
|
|
1044
|
+
* Static commands array
|
|
1045
|
+
*
|
|
1046
|
+
* @returns {CommandDescriptor[]} The commands array
|
|
1047
|
+
*/
|
|
1048
|
+
static getCommands() {
|
|
1049
|
+
return [
|
|
1050
|
+
{
|
|
1051
|
+
name: CursorContextHelp.NAME,
|
|
1052
|
+
description: CursorContextHelp.DESCRIPTION,
|
|
1053
|
+
execute: CursorContextHelp.execute.bind(CursorContextHelp)
|
|
1054
|
+
},
|
|
1055
|
+
{
|
|
1056
|
+
name: CursorContextCheck.NAME,
|
|
1057
|
+
description: CursorContextCheck.DESCRIPTION,
|
|
1058
|
+
execute: CursorContextCheck.execute.bind(CursorContextCheck)
|
|
1059
|
+
},
|
|
1060
|
+
{
|
|
1061
|
+
name: CursorRuleApply.NAME,
|
|
1062
|
+
description: CursorRuleApply.DESCRIPTION,
|
|
1063
|
+
execute: CursorRuleApply.execute.bind(CursorRuleApply)
|
|
1064
|
+
}
|
|
1065
|
+
];
|
|
1066
|
+
}
|
|
1067
|
+
};
|
|
1068
|
+
__name(_CursorRules, "CursorRules");
|
|
1069
|
+
CursorRules = _CursorRules;
|
|
1070
|
+
}
|
|
1071
|
+
});
|
|
1072
|
+
|
|
1073
|
+
// src/commands/cursor-context/bin/cli.ts
|
|
1074
|
+
init_lib();
|
|
1075
|
+
var command = process.argv[2] || "help";
|
|
1076
|
+
var args = process.argv.slice(3);
|
|
1077
|
+
async function main() {
|
|
1078
|
+
const result = await CursorRules.execute(command, ...args);
|
|
1079
|
+
console.log(result.message);
|
|
1080
|
+
if (!result.success) {
|
|
1081
|
+
process.exit(1);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
__name(main, "main");
|
|
1085
|
+
main().catch((error) => {
|
|
1086
|
+
console.error("Error:", error.message);
|
|
1087
|
+
process.exit(1);
|
|
1088
|
+
});
|
|
1089
|
+
//# sourceMappingURL=cli.js.map
|