aicm 0.14.4 → 0.14.5

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.
Files changed (46) hide show
  1. package/dist/commands/install.js +5 -5
  2. package/package.json +1 -1
  3. package/dist/api_v2.d.ts +0 -9
  4. package/dist/api_v2.js +0 -12
  5. package/dist/bin/aicm_v2.d.ts +0 -2
  6. package/dist/bin/aicm_v2.js +0 -8
  7. package/dist/cli_v2.d.ts +0 -2
  8. package/dist/cli_v2.js +0 -94
  9. package/dist/commands/install/install-package.d.ts +0 -53
  10. package/dist/commands/install/install-package.js +0 -122
  11. package/dist/commands/install/install-single-package.d.ts +0 -53
  12. package/dist/commands/install/install-single-package.js +0 -139
  13. package/dist/commands/install/install-workspaces.d.ts +0 -9
  14. package/dist/commands/install/install-workspaces.js +0 -172
  15. package/dist/commands/install_new.d.ts +0 -17
  16. package/dist/commands/install_new.js +0 -457
  17. package/dist/commands/install_v2.d.ts +0 -52
  18. package/dist/commands/install_v2.js +0 -505
  19. package/dist/commands/install_/327/2242.d.ts +0 -59
  20. package/dist/commands/install_/327/2242.js +0 -546
  21. package/dist/commands/workspaces/discovery.d.ts +0 -7
  22. package/dist/commands/workspaces/discovery.js +0 -50
  23. package/dist/commands/workspaces/workspaces-install.d.ts +0 -9
  24. package/dist/commands/workspaces/workspaces-install.js +0 -48
  25. package/dist/index.d.ts +0 -2
  26. package/dist/index.js +0 -76
  27. package/dist/types/index.d.ts +0 -64
  28. package/dist/types/index.js +0 -2
  29. package/dist/utils/config_new.d.ts +0 -64
  30. package/dist/utils/config_new.js +0 -228
  31. package/dist/utils/config_v2.d.ts +0 -64
  32. package/dist/utils/config_v2.js +0 -250
  33. package/dist/utils/glob-handler.d.ts +0 -35
  34. package/dist/utils/glob-handler.js +0 -125
  35. package/dist/utils/mcp-writer.d.ts +0 -14
  36. package/dist/utils/mcp-writer.js +0 -69
  37. package/dist/utils/mdc-parser.d.ts +0 -9
  38. package/dist/utils/mdc-parser.js +0 -59
  39. package/dist/utils/rule-collector.d.ts +0 -33
  40. package/dist/utils/rule-collector.js +0 -169
  41. package/dist/utils/rule-detector.d.ts +0 -4
  42. package/dist/utils/rule-detector.js +0 -31
  43. package/dist/utils/rule-status.d.ts +0 -8
  44. package/dist/utils/rule-status.js +0 -53
  45. package/dist/utils/rule-writer.d.ts +0 -6
  46. package/dist/utils/rule-writer.js +0 -118
@@ -1,250 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SUPPORTED_TARGETS = void 0;
7
- exports.applyDefaults = applyDefaults;
8
- exports.validateConfig = validateConfig;
9
- exports.loadRulesFromDirectory = loadRulesFromDirectory;
10
- exports.resolvePresetPath = resolvePresetPath;
11
- exports.loadPreset = loadPreset;
12
- exports.loadAllRules = loadAllRules;
13
- exports.applyOverrides = applyOverrides;
14
- exports.loadConfigFile = loadConfigFile;
15
- exports.loadConfig = loadConfig;
16
- exports.saveConfig = saveConfig;
17
- const fs_extra_1 = __importDefault(require("fs-extra"));
18
- const node_path_1 = __importDefault(require("node:path"));
19
- const cosmiconfig_1 = require("cosmiconfig");
20
- const fast_glob_1 = __importDefault(require("fast-glob"));
21
- exports.SUPPORTED_TARGETS = ["cursor", "windsurf", "codex"];
22
- function applyDefaults(config) {
23
- return {
24
- rulesDir: config.rulesDir,
25
- targets: config.targets || ["cursor"],
26
- presets: config.presets || [],
27
- overrides: config.overrides || {},
28
- mcpServers: config.mcpServers || {},
29
- workspaces: config.workspaces || false,
30
- };
31
- }
32
- function validateConfig(config, configFilePath, cwd) {
33
- if (typeof config !== "object" || config === null) {
34
- throw new Error(`Config is not an object at ${configFilePath}`);
35
- }
36
- if (!("rulesDir" in config)) {
37
- throw new Error(`rulesDir is not specified in config at ${configFilePath}`);
38
- }
39
- if (typeof config.rulesDir !== "string") {
40
- throw new Error(`rulesDir is not a string in config at ${configFilePath}`);
41
- }
42
- const rulesPath = node_path_1.default.resolve(cwd, config.rulesDir);
43
- if (!fs_extra_1.default.existsSync(rulesPath)) {
44
- throw new Error(`Rules directory does not exist: ${rulesPath}`);
45
- }
46
- if (!fs_extra_1.default.statSync(rulesPath).isDirectory()) {
47
- throw new Error(`Rules path is not a directory: ${rulesPath}`);
48
- }
49
- if ("targets" in config) {
50
- if (!Array.isArray(config.targets)) {
51
- throw new Error(`targets must be an array in config at ${configFilePath}`);
52
- }
53
- if (config.targets.length === 0) {
54
- throw new Error(`targets must not be empty in config at ${configFilePath}`);
55
- }
56
- for (const target of config.targets) {
57
- if (!exports.SUPPORTED_TARGETS.includes(target)) {
58
- throw new Error(`Unsupported target: ${target}. Supported targets: ${exports.SUPPORTED_TARGETS.join(", ")}`);
59
- }
60
- }
61
- }
62
- // Validate override rule names will be checked after rule resolution
63
- }
64
- async function loadRulesFromDirectory(rulesDir, source, presetName) {
65
- const rules = [];
66
- if (!fs_extra_1.default.existsSync(rulesDir)) {
67
- return rules;
68
- }
69
- const pattern = node_path_1.default.join(rulesDir, "**/*.mdc").replace(/\\/g, "/");
70
- const filePaths = await (0, fast_glob_1.default)(pattern, {
71
- onlyFiles: true,
72
- absolute: true,
73
- });
74
- for (const filePath of filePaths) {
75
- const content = await fs_extra_1.default.readFile(filePath, "utf8");
76
- // Preserve directory structure by using relative path from rulesDir
77
- const relativePath = node_path_1.default.relative(rulesDir, filePath);
78
- const ruleName = relativePath.replace(/\.mdc$/, "").replace(/\\/g, "/");
79
- rules.push({
80
- name: ruleName,
81
- content,
82
- sourcePath: filePath,
83
- source,
84
- presetName,
85
- });
86
- }
87
- return rules;
88
- }
89
- function resolvePresetPath(presetPath, cwd) {
90
- // Support specifying aicm.json directory and load the config from it
91
- if (!presetPath.endsWith(".json")) {
92
- presetPath = node_path_1.default.join(presetPath, "aicm.json");
93
- }
94
- // Support local or absolute paths
95
- const absolutePath = node_path_1.default.isAbsolute(presetPath)
96
- ? presetPath
97
- : node_path_1.default.resolve(cwd, presetPath);
98
- if (fs_extra_1.default.existsSync(absolutePath)) {
99
- return absolutePath;
100
- }
101
- try {
102
- // Support npm packages
103
- const resolvedPath = require.resolve(presetPath, {
104
- paths: [cwd, __dirname],
105
- });
106
- return fs_extra_1.default.existsSync(resolvedPath) ? resolvedPath : null;
107
- }
108
- catch (_a) {
109
- return null;
110
- }
111
- }
112
- async function loadPreset(presetPath, cwd) {
113
- const resolvedPresetPath = resolvePresetPath(presetPath, cwd);
114
- if (!resolvedPresetPath) {
115
- throw new Error(`Preset not found: "${presetPath}". Make sure the package is installed or the path is correct.`);
116
- }
117
- let presetConfig;
118
- try {
119
- const content = await fs_extra_1.default.readFile(resolvedPresetPath, "utf8");
120
- presetConfig = JSON.parse(content);
121
- }
122
- catch (error) {
123
- throw new Error(`Failed to load preset "${presetPath}": ${error instanceof Error ? error.message : "Unknown error"}`);
124
- }
125
- // Resolve preset's rules directory relative to the preset file
126
- const presetDir = node_path_1.default.dirname(resolvedPresetPath);
127
- const presetRulesDir = node_path_1.default.resolve(presetDir, presetConfig.rulesDir);
128
- return {
129
- config: presetConfig,
130
- rulesDir: presetRulesDir,
131
- };
132
- }
133
- async function loadAllRules(config, cwd) {
134
- const allRules = [];
135
- let mergedMcpServers = { ...config.mcpServers };
136
- // Load local rules
137
- const localRulesPath = node_path_1.default.resolve(cwd, config.rulesDir);
138
- const localRules = await loadRulesFromDirectory(localRulesPath, "local");
139
- allRules.push(...localRules);
140
- if (config.presets) {
141
- for (const presetPath of config.presets) {
142
- const preset = await loadPreset(presetPath, cwd);
143
- const presetRules = await loadRulesFromDirectory(preset.rulesDir, "preset", presetPath);
144
- allRules.push(...presetRules);
145
- // Merge MCP servers from preset
146
- if (preset.config.mcpServers) {
147
- mergedMcpServers = mergePresetMcpServers(mergedMcpServers, preset.config.mcpServers);
148
- }
149
- }
150
- }
151
- return {
152
- rules: allRules,
153
- mcpServers: mergedMcpServers,
154
- };
155
- }
156
- function applyOverrides(rules, overrides, cwd) {
157
- // Validate that all override rule names exist in the resolved rules
158
- for (const ruleName of Object.keys(overrides)) {
159
- // TODO: support better error messages with edit distance, helping the user in case of a typo
160
- // TODO: or shows a list of potential rules to override
161
- if (!rules.some((rule) => rule.name === ruleName)) {
162
- throw new Error(`Override rule "${ruleName}" does not exist in resolved rules`);
163
- }
164
- }
165
- const ruleMap = new Map();
166
- for (const rule of rules) {
167
- ruleMap.set(rule.name, rule);
168
- }
169
- for (const [ruleName, override] of Object.entries(overrides)) {
170
- if (override === false) {
171
- ruleMap.delete(ruleName);
172
- }
173
- else if (typeof override === "string") {
174
- const overridePath = node_path_1.default.resolve(cwd, override);
175
- if (!fs_extra_1.default.existsSync(overridePath)) {
176
- throw new Error(`Override rule file not found: ${override} in ${cwd}`);
177
- }
178
- const content = fs_extra_1.default.readFileSync(overridePath, "utf8");
179
- ruleMap.set(ruleName, {
180
- name: ruleName,
181
- content,
182
- sourcePath: overridePath,
183
- source: "local",
184
- });
185
- }
186
- }
187
- return Array.from(ruleMap.values());
188
- }
189
- /**
190
- * Merge preset MCP servers with local config MCP servers
191
- * Local config takes precedence over preset config
192
- */
193
- function mergePresetMcpServers(configMcpServers, presetMcpServers) {
194
- const newMcpServers = { ...configMcpServers };
195
- for (const [serverName, serverConfig] of Object.entries(presetMcpServers)) {
196
- // Cancel if set to false in config
197
- if (Object.prototype.hasOwnProperty.call(newMcpServers, serverName) &&
198
- newMcpServers[serverName] === false) {
199
- delete newMcpServers[serverName];
200
- continue;
201
- }
202
- // Only add if not already defined in config (override handled by config)
203
- if (!Object.prototype.hasOwnProperty.call(newMcpServers, serverName)) {
204
- newMcpServers[serverName] = serverConfig;
205
- }
206
- }
207
- return newMcpServers;
208
- }
209
- async function loadConfigFile(searchFrom) {
210
- const explorer = (0, cosmiconfig_1.cosmiconfig)("aicm", {
211
- searchPlaces: ["aicm.json", "package.json"],
212
- });
213
- try {
214
- const result = await explorer.search(searchFrom);
215
- return result;
216
- }
217
- catch (error) {
218
- throw new Error(`Failed to load configuration: ${error instanceof Error ? error.message : "Unknown error"}`);
219
- }
220
- }
221
- async function loadConfig(cwd) {
222
- const workingDir = cwd || process.cwd();
223
- const configResult = await loadConfigFile(workingDir);
224
- if (!(configResult === null || configResult === void 0 ? void 0 : configResult.config)) {
225
- return null;
226
- }
227
- validateConfig(configResult.config, configResult.filepath, workingDir);
228
- const config = applyDefaults(configResult.config);
229
- const { rules, mcpServers } = await loadAllRules(config, workingDir);
230
- let rulesWithOverrides = rules;
231
- if (config.overrides) {
232
- rulesWithOverrides = applyOverrides(rules, config.overrides, workingDir);
233
- }
234
- return {
235
- config,
236
- rules: rulesWithOverrides,
237
- mcpServers,
238
- };
239
- }
240
- function saveConfig(config, cwd) {
241
- const workingDir = cwd || process.cwd();
242
- const configPath = node_path_1.default.join(workingDir, "aicm.json");
243
- try {
244
- fs_extra_1.default.writeFileSync(configPath, JSON.stringify(config, null, 2));
245
- return true;
246
- }
247
- catch (_a) {
248
- return false;
249
- }
250
- }
@@ -1,35 +0,0 @@
1
- /**
2
- * Check if a rule source string contains glob patterns
3
- */
4
- export declare function isGlobPattern(source: string): boolean;
5
- /**
6
- * Expand a glob pattern to matching .mdc files
7
- * @param pattern The glob pattern to expand
8
- * @param basePath The base path to resolve relative patterns from
9
- * @returns Array of file paths that match the pattern
10
- */
11
- export declare function expandGlobPattern(pattern: string, basePath?: string): Promise<string[]>;
12
- /**
13
- * Generate a rule key from a file path and base key
14
- * @param filePath The discovered file path
15
- * @param baseKey The base key from the object notation
16
- * @param patternBase The base directory of the glob pattern
17
- * @returns Generated rule key with namespace
18
- */
19
- export declare function generateGlobRuleKey(filePath: string, baseKey: string, patternBase: string): string;
20
- /**
21
- * Get the base directory from a glob pattern
22
- * @param pattern The glob pattern
23
- * @returns The base directory path without glob characters
24
- */
25
- export declare function getGlobBase(pattern: string): string;
26
- /**
27
- * Expand glob patterns in rules object and return normalized rules
28
- * @param rules The rules object that may contain glob patterns
29
- * @param basePath The base path to resolve relative patterns from
30
- * @returns Object with expanded rules and metadata about sources
31
- */
32
- export declare function expandRulesGlobPatterns(rules: Record<string, string | false>, basePath?: string): Promise<{
33
- expandedRules: Record<string, string>;
34
- globSources: Record<string, string>;
35
- }>;
@@ -1,125 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.isGlobPattern = isGlobPattern;
7
- exports.expandGlobPattern = expandGlobPattern;
8
- exports.generateGlobRuleKey = generateGlobRuleKey;
9
- exports.getGlobBase = getGlobBase;
10
- exports.expandRulesGlobPatterns = expandRulesGlobPatterns;
11
- const node_path_1 = __importDefault(require("node:path"));
12
- const fast_glob_1 = __importDefault(require("fast-glob"));
13
- /**
14
- * Check if a rule source string contains glob patterns
15
- */
16
- function isGlobPattern(source) {
17
- return /[*?{}[\]]/.test(source);
18
- }
19
- /**
20
- * Expand a glob pattern to matching .mdc files
21
- * @param pattern The glob pattern to expand
22
- * @param basePath The base path to resolve relative patterns from
23
- * @returns Array of file paths that match the pattern
24
- */
25
- async function expandGlobPattern(pattern, basePath) {
26
- // Normalize the pattern to use forward slashes for consistent behavior
27
- const normalizedPattern = pattern.replace(/\\/g, "/");
28
- try {
29
- const matches = await (0, fast_glob_1.default)(normalizedPattern, {
30
- ignore: ["**/.*"], // Ignore hidden files
31
- absolute: false,
32
- onlyFiles: true,
33
- // Set the working directory if basePath is provided
34
- cwd: basePath,
35
- });
36
- // Filter to only .mdc files, normalize paths, and sort for deterministic behavior
37
- return matches
38
- .filter((file) => file.endsWith(".mdc"))
39
- .map((file) => file.replace(/\\/g, "/")) // Normalize Windows backslashes to forward slashes
40
- .sort((a, b) => a.localeCompare(b));
41
- }
42
- catch (error) {
43
- throw new Error(`Error expanding glob pattern "${pattern}": ${error instanceof Error ? error.message : String(error)}`);
44
- }
45
- }
46
- /**
47
- * Generate a rule key from a file path and base key
48
- * @param filePath The discovered file path
49
- * @param baseKey The base key from the object notation
50
- * @param patternBase The base directory of the glob pattern
51
- * @returns Generated rule key with namespace
52
- */
53
- function generateGlobRuleKey(filePath, baseKey, patternBase) {
54
- // Normalize paths to use forward slashes for consistent behavior
55
- const normalizedFilePath = filePath.replace(/\\/g, "/");
56
- const normalizedPatternBase = patternBase.replace(/\\/g, "/");
57
- // Get the relative path from the pattern base to the file
58
- const relativePath = node_path_1.default.posix.relative(normalizedPatternBase, normalizedFilePath);
59
- // Remove .mdc extension
60
- const withoutExtension = relativePath.replace(/\.mdc$/, "");
61
- // Return the combined key
62
- return `${baseKey}/${withoutExtension}`;
63
- }
64
- /**
65
- * Get the base directory from a glob pattern
66
- * @param pattern The glob pattern
67
- * @returns The base directory path without glob characters
68
- */
69
- function getGlobBase(pattern) {
70
- // Normalize path separators to forward slashes for consistent behavior
71
- const normalizedPattern = pattern.replace(/\\/g, "/");
72
- // Find the first occurrence of glob characters
73
- const globIndex = normalizedPattern.search(/[*?{}[\]]/);
74
- if (globIndex === -1) {
75
- // No glob characters, return the directory
76
- return node_path_1.default.dirname(normalizedPattern);
77
- }
78
- // Get the path up to the first glob character
79
- const basePath = normalizedPattern.substring(0, globIndex);
80
- // Find the last path separator before the glob
81
- const lastSeparator = basePath.lastIndexOf("/");
82
- if (lastSeparator === -1) {
83
- return ".";
84
- }
85
- return basePath.substring(0, lastSeparator);
86
- }
87
- /**
88
- * Expand glob patterns in rules object and return normalized rules
89
- * @param rules The rules object that may contain glob patterns
90
- * @param basePath The base path to resolve relative patterns from
91
- * @returns Object with expanded rules and metadata about sources
92
- */
93
- async function expandRulesGlobPatterns(rules, basePath) {
94
- const expandedRules = {};
95
- const globSources = {};
96
- for (const [key, source] of Object.entries(rules)) {
97
- if (source === false) {
98
- continue; // Skip canceled rules
99
- }
100
- if (isGlobPattern(source)) {
101
- // Expand glob pattern
102
- try {
103
- const matchedFiles = await expandGlobPattern(source, basePath);
104
- if (matchedFiles.length === 0) {
105
- console.warn(`Warning: Glob pattern "${source}" matched no files`);
106
- continue;
107
- }
108
- const patternBase = getGlobBase(source);
109
- for (const filePath of matchedFiles) {
110
- const generatedKey = generateGlobRuleKey(filePath, key, patternBase);
111
- expandedRules[generatedKey] = filePath;
112
- globSources[generatedKey] = source;
113
- }
114
- }
115
- catch (error) {
116
- throw new Error(`Error processing glob pattern for key "${key}": ${error instanceof Error ? error.message : String(error)}`);
117
- }
118
- }
119
- else {
120
- // Regular file path
121
- expandedRules[key] = source;
122
- }
123
- }
124
- return { expandedRules, globSources };
125
- }
@@ -1,14 +0,0 @@
1
- import { NormalizedConfig } from "../types";
2
- /**
3
- * Write MCP servers configuration to IDE targets
4
- * @param mcpServers The MCP servers configuration
5
- * @param ides The IDEs to write to
6
- * @param cwd The current working directory
7
- */
8
- export declare function writeMcpServersToTargets(mcpServers: NormalizedConfig["mcpServers"], ides: string[], cwd: string): void;
9
- /**
10
- * Write MCP servers configuration to a specific file
11
- * @param mcpServers The MCP servers configuration
12
- * @param mcpPath The path to the mcp.json file
13
- */
14
- export declare function writeMcpServersToFile(mcpServers: NormalizedConfig["mcpServers"], mcpPath: string): void;
@@ -1,69 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.writeMcpServersToTargets = writeMcpServersToTargets;
7
- exports.writeMcpServersToFile = writeMcpServersToFile;
8
- const fs_extra_1 = __importDefault(require("fs-extra"));
9
- const node_path_1 = __importDefault(require("node:path"));
10
- /**
11
- * Write MCP servers configuration to IDE targets
12
- * @param mcpServers The MCP servers configuration
13
- * @param ides The IDEs to write to
14
- * @param cwd The current working directory
15
- */
16
- function writeMcpServersToTargets(mcpServers, ides, cwd) {
17
- if (!mcpServers)
18
- return;
19
- for (const ide of ides) {
20
- if (ide === "cursor") {
21
- const mcpPath = node_path_1.default.join(cwd, ".cursor", "mcp.json");
22
- writeMcpServersToFile(mcpServers, mcpPath);
23
- }
24
- // Windsurf does not support project mcpServers, so skip
25
- }
26
- }
27
- /**
28
- * Write MCP servers configuration to a specific file
29
- * @param mcpServers The MCP servers configuration
30
- * @param mcpPath The path to the mcp.json file
31
- */
32
- function writeMcpServersToFile(mcpServers, mcpPath) {
33
- var _a;
34
- if (!mcpServers)
35
- return;
36
- fs_extra_1.default.ensureDirSync(node_path_1.default.dirname(mcpPath));
37
- const existingConfig = fs_extra_1.default.existsSync(mcpPath)
38
- ? fs_extra_1.default.readJsonSync(mcpPath)
39
- : {};
40
- const existingMcpServers = (_a = existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.mcpServers) !== null && _a !== void 0 ? _a : {};
41
- // Filter out any existing aicm-managed servers (with aicm: true)
42
- // This removes stale aicm servers that are no longer in the configuration
43
- const userMcpServers = {};
44
- for (const [key, value] of Object.entries(existingMcpServers)) {
45
- if (typeof value === "object" && value !== null && value.aicm !== true) {
46
- userMcpServers[key] = value;
47
- }
48
- }
49
- // Mark new aicm servers as managed and filter out canceled servers
50
- const aicmMcpServers = {};
51
- for (const [key, value] of Object.entries(mcpServers)) {
52
- if (value !== false) {
53
- aicmMcpServers[key] = {
54
- ...value,
55
- aicm: true,
56
- };
57
- }
58
- }
59
- // Merge user servers with aicm servers (aicm servers override user servers with same key)
60
- const mergedMcpServers = {
61
- ...userMcpServers,
62
- ...aicmMcpServers,
63
- };
64
- const mergedConfig = {
65
- ...existingConfig,
66
- mcpServers: mergedMcpServers,
67
- };
68
- fs_extra_1.default.writeJsonSync(mcpPath, mergedConfig, { spaces: 2 });
69
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * Parse an MDC file and extract its content
3
- * MDC files are Markdown files with metadata
4
- * https://docs.cursor.com/context/rules
5
- */
6
- export declare function parseMdcFile(filePath: string): {
7
- metadata: Record<string, boolean | string | string[]>;
8
- content: string;
9
- };
@@ -1,59 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.parseMdcFile = parseMdcFile;
7
- const fs_extra_1 = __importDefault(require("fs-extra"));
8
- /**
9
- * Parse an MDC file and extract its content
10
- * MDC files are Markdown files with metadata
11
- * https://docs.cursor.com/context/rules
12
- */
13
- function parseMdcFile(filePath) {
14
- const fileContent = fs_extra_1.default.readFileSync(filePath, "utf8");
15
- if (!fileContent.startsWith("---")) {
16
- return {
17
- metadata: {},
18
- content: fileContent,
19
- };
20
- }
21
- const endOfMetadata = fileContent.indexOf("---", 3);
22
- if (endOfMetadata === -1) {
23
- return {
24
- metadata: {},
25
- content: fileContent,
26
- };
27
- }
28
- const metadataStr = fileContent.substring(3, endOfMetadata).trim();
29
- const content = fileContent.substring(endOfMetadata + 3).trim();
30
- const metadata = {};
31
- metadataStr.split("\n").forEach((line) => {
32
- const colonIndex = line.indexOf(":");
33
- if (colonIndex !== -1) {
34
- const key = line.substring(0, colonIndex).trim();
35
- const valueStr = line.substring(colonIndex + 1).trim();
36
- // Handle different value types
37
- let value = "";
38
- if (valueStr === "true") {
39
- value = true;
40
- }
41
- else if (valueStr === "false") {
42
- value = false;
43
- }
44
- else if (valueStr.startsWith('"') && valueStr.endsWith('"')) {
45
- // Remove quotes from string values
46
- value = valueStr.substring(1, valueStr.length - 1);
47
- }
48
- else {
49
- // Default to using the string value as is
50
- value = valueStr;
51
- }
52
- metadata[key] = value;
53
- }
54
- });
55
- return {
56
- metadata,
57
- content,
58
- };
59
- }
@@ -1,33 +0,0 @@
1
- import { RuleCollection, RuleContent } from "../types";
2
- /**
3
- * Find the root directory of a package by name
4
- * @param packageName The name of the package
5
- * @returns The absolute path to the package's root directory
6
- */
7
- export declare function findPackageRoot(packageName: string): string;
8
- /**
9
- * Initialize an empty rule collection
10
- */
11
- export declare function initRuleCollection(): RuleCollection;
12
- /**
13
- * Add a rule to the collection
14
- * @param collection The rule collection to add to
15
- * @param rule The rule content to add
16
- * @param ides The IDEs to add the rule for
17
- */
18
- export declare function addRuleToCollection(collection: RuleCollection, rule: RuleContent, ides: string[]): void;
19
- /**
20
- * Collect a rule from a local file source
21
- * @param ruleName The name of the rule
22
- * @param source The source path (relative or absolute)
23
- * @param ruleBasePath Optional base path for resolving relative paths
24
- * @returns The rule content
25
- */
26
- export declare function collectLocalRule(ruleName: string, source: string | false, ruleBasePath?: string): RuleContent;
27
- /**
28
- * Collect a rule from an npm package
29
- * @param ruleName The name of the rule
30
- * @param source The npm package source (can include path)
31
- * @returns The rule content
32
- */
33
- export declare function collectNpmRule(ruleName: string, source: string | false): RuleContent;