aicm 0.14.4 → 0.15.0
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 +18 -1
- package/dist/commands/install.js +61 -93
- package/dist/utils/config.d.ts +3 -1
- package/dist/utils/config.js +2 -0
- package/dist/utils/rules-file-writer.d.ts +5 -0
- package/dist/utils/rules-file-writer.js +46 -1
- package/package.json +1 -1
- package/dist/api_v2.d.ts +0 -9
- package/dist/api_v2.js +0 -12
- package/dist/bin/aicm_v2.d.ts +0 -2
- package/dist/bin/aicm_v2.js +0 -8
- package/dist/cli_v2.d.ts +0 -2
- package/dist/cli_v2.js +0 -94
- package/dist/commands/install/install-package.d.ts +0 -53
- package/dist/commands/install/install-package.js +0 -122
- package/dist/commands/install/install-single-package.d.ts +0 -53
- package/dist/commands/install/install-single-package.js +0 -139
- package/dist/commands/install/install-workspaces.d.ts +0 -9
- package/dist/commands/install/install-workspaces.js +0 -172
- package/dist/commands/install_new.d.ts +0 -17
- package/dist/commands/install_new.js +0 -457
- package/dist/commands/install_v2.d.ts +0 -52
- package/dist/commands/install_v2.js +0 -505
- package/dist/commands/install_/327/2242.d.ts +0 -59
- package/dist/commands/install_/327/2242.js +0 -546
- package/dist/commands/workspaces/discovery.d.ts +0 -7
- package/dist/commands/workspaces/discovery.js +0 -50
- package/dist/commands/workspaces/workspaces-install.d.ts +0 -9
- package/dist/commands/workspaces/workspaces-install.js +0 -48
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -76
- package/dist/types/index.d.ts +0 -64
- package/dist/types/index.js +0 -2
- package/dist/utils/config_new.d.ts +0 -64
- package/dist/utils/config_new.js +0 -228
- package/dist/utils/config_v2.d.ts +0 -64
- package/dist/utils/config_v2.js +0 -250
- package/dist/utils/glob-handler.d.ts +0 -35
- package/dist/utils/glob-handler.js +0 -125
- package/dist/utils/mcp-writer.d.ts +0 -14
- package/dist/utils/mcp-writer.js +0 -69
- package/dist/utils/mdc-parser.d.ts +0 -9
- package/dist/utils/mdc-parser.js +0 -59
- package/dist/utils/rule-collector.d.ts +0 -33
- package/dist/utils/rule-collector.js +0 -169
- package/dist/utils/rule-detector.d.ts +0 -4
- package/dist/utils/rule-detector.js +0 -31
- package/dist/utils/rule-status.d.ts +0 -8
- package/dist/utils/rule-status.js +0 -53
- package/dist/utils/rule-writer.d.ts +0 -6
- package/dist/utils/rule-writer.js +0 -118
package/README.md
CHANGED
|
@@ -160,6 +160,7 @@ aicm automatically detects workspaces if your `package.json` contains a `workspa
|
|
|
160
160
|
|
|
161
161
|
1. **Discover packages**: Automatically find all directories containing `aicm.json` files in your repository
|
|
162
162
|
2. **Install per package**: Install rules and MCPs for each package individually in their respective directories
|
|
163
|
+
3. **Merge MCP servers**: Write a merged `.cursor/mcp.json` at the repository root containing all MCP servers from every package
|
|
163
164
|
|
|
164
165
|
### How It Works
|
|
165
166
|
|
|
@@ -185,6 +186,20 @@ Running `npx aicm install` will install rules for each package in their respecti
|
|
|
185
186
|
- `packages/backend/.cursor/rules/aicm/`
|
|
186
187
|
- `services/api/.cursor/rules/aicm/`
|
|
187
188
|
|
|
189
|
+
### Preset Packages in Workspaces
|
|
190
|
+
|
|
191
|
+
When you have a preset package within your workspace (a package that provides rules to be consumed by others), you can prevent aicm from installing rules into it by setting `skipInstall: true`:
|
|
192
|
+
|
|
193
|
+
```json
|
|
194
|
+
{
|
|
195
|
+
"skipInstall": true,
|
|
196
|
+
"rulesDir": "./rules",
|
|
197
|
+
"targets": ["cursor"]
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
This is useful when your workspace contains both consumer packages (that need rules installed) and provider packages (that only export rules).
|
|
202
|
+
|
|
188
203
|
## Configuration
|
|
189
204
|
|
|
190
205
|
Create an `aicm.json` file in your project root, or an `aicm` key in your project's `package.json`.
|
|
@@ -195,7 +210,8 @@ Create an `aicm.json` file in your project root, or an `aicm` key in your projec
|
|
|
195
210
|
"targets": ["cursor"],
|
|
196
211
|
"presets": [],
|
|
197
212
|
"overrides": {},
|
|
198
|
-
"mcpServers": {}
|
|
213
|
+
"mcpServers": {},
|
|
214
|
+
"skipInstall": false
|
|
199
215
|
}
|
|
200
216
|
```
|
|
201
217
|
|
|
@@ -205,6 +221,7 @@ Create an `aicm.json` file in your project root, or an `aicm` key in your projec
|
|
|
205
221
|
- **overrides**: Map of rule names to `false` (disable) or a replacement file path.
|
|
206
222
|
- **mcpServers**: MCP server configurations.
|
|
207
223
|
- **workspaces**: Set to `true` to enable workspace mode. If not specified, aicm will automatically detect workspaces from your `package.json`.
|
|
224
|
+
- **skipInstall**: Set to `true` to skip rule installation for this package. Useful for preset packages that provide rules but shouldn't have rules installed into them.
|
|
208
225
|
|
|
209
226
|
### MCP Server Installation
|
|
210
227
|
|
package/dist/commands/install.js
CHANGED
|
@@ -13,6 +13,7 @@ const child_process_1 = require("child_process");
|
|
|
13
13
|
const config_1 = require("../utils/config");
|
|
14
14
|
const working_directory_1 = require("../utils/working-directory");
|
|
15
15
|
const is_ci_1 = require("../utils/is-ci");
|
|
16
|
+
const rules_file_writer_1 = require("../utils/rules-file-writer");
|
|
16
17
|
function getTargetPaths() {
|
|
17
18
|
const projectDir = process.cwd();
|
|
18
19
|
return {
|
|
@@ -50,80 +51,6 @@ function extractNamespaceFromPresetPath(presetPath) {
|
|
|
50
51
|
const parts = presetPath.split(node_path_1.default.sep);
|
|
51
52
|
return parts.filter((part) => part.length > 0); // Filter out empty segments
|
|
52
53
|
}
|
|
53
|
-
function generateRulesFileContent(ruleFiles) {
|
|
54
|
-
const alwaysApplyRules = [];
|
|
55
|
-
const optInRules = [];
|
|
56
|
-
for (const rule of ruleFiles) {
|
|
57
|
-
// Parse metadata to determine rule type
|
|
58
|
-
const metadata = rule.content.match(/^---\n([\s\S]*?)\n---/);
|
|
59
|
-
let alwaysApply = false;
|
|
60
|
-
if (metadata) {
|
|
61
|
-
try {
|
|
62
|
-
const frontmatter = metadata[1];
|
|
63
|
-
// Simple YAML parsing for alwaysApply field
|
|
64
|
-
const alwaysApplyMatch = frontmatter.match(/alwaysApply:\s*(true|false)/);
|
|
65
|
-
if (alwaysApplyMatch) {
|
|
66
|
-
alwaysApply = alwaysApplyMatch[1] === "true";
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
catch (_a) {
|
|
70
|
-
// If parsing fails, default to false
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
if (alwaysApply) {
|
|
74
|
-
alwaysApplyRules.push(`- ${rule.path}`);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
optInRules.push(`- ${rule.path}`);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
let content = "<!-- AICM:BEGIN -->\n";
|
|
81
|
-
if (alwaysApplyRules.length > 0) {
|
|
82
|
-
content +=
|
|
83
|
-
"The following rules always apply to all files in the project:\n";
|
|
84
|
-
content += alwaysApplyRules.join("\n") + "\n\n";
|
|
85
|
-
}
|
|
86
|
-
if (optInRules.length > 0) {
|
|
87
|
-
content +=
|
|
88
|
-
"The following rules are available for the AI to include when needed:\n";
|
|
89
|
-
content += optInRules.join("\n") + "\n\n";
|
|
90
|
-
}
|
|
91
|
-
content += "<!-- AICM:END -->";
|
|
92
|
-
return content;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Write rules file content to a file, preserving existing content outside markers
|
|
96
|
-
*/
|
|
97
|
-
function writeRulesFile(rulesContent, rulesFilePath) {
|
|
98
|
-
const RULES_BEGIN = "<!-- AICM:BEGIN -->";
|
|
99
|
-
const RULES_END = "<!-- AICM:END -->";
|
|
100
|
-
let fileContent;
|
|
101
|
-
if (fs_extra_1.default.existsSync(rulesFilePath)) {
|
|
102
|
-
const existingContent = fs_extra_1.default.readFileSync(rulesFilePath, "utf8");
|
|
103
|
-
if (existingContent.includes(RULES_BEGIN) &&
|
|
104
|
-
existingContent.includes(RULES_END)) {
|
|
105
|
-
const beforeMarker = existingContent.split(RULES_BEGIN)[0];
|
|
106
|
-
const afterMarker = existingContent.split(RULES_END)[1];
|
|
107
|
-
fileContent = beforeMarker + rulesContent + afterMarker;
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
// Preserve the existing content and append markers
|
|
111
|
-
let separator = "";
|
|
112
|
-
if (!existingContent.endsWith("\n")) {
|
|
113
|
-
separator += "\n";
|
|
114
|
-
}
|
|
115
|
-
if (!existingContent.endsWith("\n\n")) {
|
|
116
|
-
separator += "\n";
|
|
117
|
-
}
|
|
118
|
-
fileContent = existingContent + separator + rulesContent;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
// Create new file with markers and content
|
|
123
|
-
fileContent = rulesContent + "\n";
|
|
124
|
-
}
|
|
125
|
-
fs_extra_1.default.writeFileSync(rulesFilePath, fileContent);
|
|
126
|
-
}
|
|
127
54
|
/**
|
|
128
55
|
* Write rules to a shared directory and update the given rules file
|
|
129
56
|
*/
|
|
@@ -161,11 +88,11 @@ function writeRulesForFile(rules, ruleDir, rulesFile) {
|
|
|
161
88
|
return {
|
|
162
89
|
name: rule.name,
|
|
163
90
|
path: windsurfPathPosix,
|
|
164
|
-
|
|
91
|
+
metadata: (0, rules_file_writer_1.parseRuleFrontmatter)(rule.content),
|
|
165
92
|
};
|
|
166
93
|
});
|
|
167
|
-
const rulesContent = generateRulesFileContent(ruleFiles);
|
|
168
|
-
writeRulesFile(rulesContent, node_path_1.default.join(process.cwd(), rulesFile));
|
|
94
|
+
const rulesContent = (0, rules_file_writer_1.generateRulesFileContent)(ruleFiles);
|
|
95
|
+
(0, rules_file_writer_1.writeRulesFile)(rulesContent, node_path_1.default.join(process.cwd(), rulesFile));
|
|
169
96
|
}
|
|
170
97
|
/**
|
|
171
98
|
* Write all collected rules to their respective IDE targets
|
|
@@ -245,6 +172,37 @@ function writeMcpServersToFile(mcpServers, mcpPath) {
|
|
|
245
172
|
};
|
|
246
173
|
fs_extra_1.default.writeJsonSync(mcpPath, mergedConfig, { spaces: 2 });
|
|
247
174
|
}
|
|
175
|
+
function mergeWorkspaceMcpServers(packages) {
|
|
176
|
+
const merged = {};
|
|
177
|
+
const info = {};
|
|
178
|
+
for (const pkg of packages) {
|
|
179
|
+
for (const [key, value] of Object.entries(pkg.config.mcpServers)) {
|
|
180
|
+
if (value === false)
|
|
181
|
+
continue;
|
|
182
|
+
const json = JSON.stringify(value);
|
|
183
|
+
if (!info[key]) {
|
|
184
|
+
info[key] = {
|
|
185
|
+
configs: new Set([json]),
|
|
186
|
+
packages: [pkg.relativePath],
|
|
187
|
+
chosen: pkg.relativePath,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
info[key].packages.push(pkg.relativePath);
|
|
192
|
+
info[key].configs.add(json);
|
|
193
|
+
info[key].chosen = pkg.relativePath;
|
|
194
|
+
}
|
|
195
|
+
merged[key] = value;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const conflicts = [];
|
|
199
|
+
for (const [key, data] of Object.entries(info)) {
|
|
200
|
+
if (data.configs.size > 1) {
|
|
201
|
+
conflicts.push({ key, packages: data.packages, chosen: data.chosen });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return { merged, conflicts };
|
|
205
|
+
}
|
|
248
206
|
/**
|
|
249
207
|
* Discover all packages with aicm configurations using git ls-files
|
|
250
208
|
*/
|
|
@@ -310,17 +268,12 @@ async function installPackage(options = {}) {
|
|
|
310
268
|
};
|
|
311
269
|
}
|
|
312
270
|
const { config, rules, mcpServers } = resolvedConfig;
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
error: new Error("No rules defined in configuration"),
|
|
320
|
-
installedRuleCount: 0,
|
|
321
|
-
packagesCount: 0,
|
|
322
|
-
};
|
|
323
|
-
}
|
|
271
|
+
if (config.skipInstall === true) {
|
|
272
|
+
return {
|
|
273
|
+
success: true,
|
|
274
|
+
installedRuleCount: 0,
|
|
275
|
+
packagesCount: 0,
|
|
276
|
+
};
|
|
324
277
|
}
|
|
325
278
|
try {
|
|
326
279
|
if (!options.dryRun) {
|
|
@@ -396,6 +349,9 @@ async function installWorkspaces(cwd, installOnCI, verbose = false, dryRun = fal
|
|
|
396
349
|
}
|
|
397
350
|
const allPackages = await discoverPackagesWithAicm(cwd);
|
|
398
351
|
const packages = allPackages.filter((pkg) => {
|
|
352
|
+
if (pkg.config.config.skipInstall === true) {
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
399
355
|
const isRoot = pkg.relativePath === ".";
|
|
400
356
|
if (!isRoot)
|
|
401
357
|
return true;
|
|
@@ -424,6 +380,15 @@ async function installWorkspaces(cwd, installOnCI, verbose = false, dryRun = fal
|
|
|
424
380
|
verbose,
|
|
425
381
|
dryRun,
|
|
426
382
|
});
|
|
383
|
+
const { merged: rootMcp, conflicts } = mergeWorkspaceMcpServers(packages);
|
|
384
|
+
const hasCursorTarget = packages.some((p) => p.config.config.targets.includes("cursor"));
|
|
385
|
+
if (!dryRun && hasCursorTarget && Object.keys(rootMcp).length > 0) {
|
|
386
|
+
const mcpPath = node_path_1.default.join(cwd, ".cursor", "mcp.json");
|
|
387
|
+
writeMcpServersToFile(rootMcp, mcpPath);
|
|
388
|
+
}
|
|
389
|
+
for (const conflict of conflicts) {
|
|
390
|
+
console.warn(`Warning: MCP configuration conflict detected\n Key: "${conflict.key}"\n Packages: ${conflict.packages.join(", ")}\n Using configuration from: ${conflict.chosen}`);
|
|
391
|
+
}
|
|
427
392
|
if (verbose) {
|
|
428
393
|
result.packages.forEach((pkg) => {
|
|
429
394
|
if (pkg.success) {
|
|
@@ -451,7 +416,6 @@ async function installWorkspaces(cwd, installOnCI, verbose = false, dryRun = fal
|
|
|
451
416
|
packagesCount: result.packages.length,
|
|
452
417
|
};
|
|
453
418
|
}
|
|
454
|
-
console.log(`Successfully installed ${result.totalRuleCount} rules across ${result.packages.length} packages`);
|
|
455
419
|
return {
|
|
456
420
|
success: true,
|
|
457
421
|
installedRuleCount: result.totalRuleCount,
|
|
@@ -500,19 +464,23 @@ async function installCommand(installOnCI, verbose, dryRun) {
|
|
|
500
464
|
throw (_a = result.error) !== null && _a !== void 0 ? _a : new Error("Installation failed with unknown error");
|
|
501
465
|
}
|
|
502
466
|
else {
|
|
467
|
+
const rulesInstalledMessage = `${result.installedRuleCount} rule${result.installedRuleCount === 1 ? "" : "s"}`;
|
|
503
468
|
if (dryRun) {
|
|
504
469
|
if (result.packagesCount > 1) {
|
|
505
|
-
console.log(`Dry run: ${
|
|
470
|
+
console.log(`Dry run: validated ${rulesInstalledMessage} across ${result.packagesCount} packages`);
|
|
506
471
|
}
|
|
507
472
|
else {
|
|
508
|
-
console.log(
|
|
473
|
+
console.log(`Dry run: validated ${rulesInstalledMessage}`);
|
|
509
474
|
}
|
|
510
475
|
}
|
|
476
|
+
else if (result.installedRuleCount === 0) {
|
|
477
|
+
console.log("No rules installed");
|
|
478
|
+
}
|
|
511
479
|
else if (result.packagesCount > 1) {
|
|
512
|
-
console.log(`Successfully installed ${
|
|
480
|
+
console.log(`Successfully installed ${rulesInstalledMessage} across ${result.packagesCount} packages`);
|
|
513
481
|
}
|
|
514
482
|
else {
|
|
515
|
-
console.log(
|
|
483
|
+
console.log(`Successfully installed ${rulesInstalledMessage}`);
|
|
516
484
|
}
|
|
517
485
|
}
|
|
518
486
|
}
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface RawConfig {
|
|
|
6
6
|
overrides?: Record<string, string | false>;
|
|
7
7
|
mcpServers?: MCPServers;
|
|
8
8
|
workspaces?: boolean;
|
|
9
|
+
skipInstall?: boolean;
|
|
9
10
|
}
|
|
10
11
|
export interface Config {
|
|
11
12
|
rulesDir?: string;
|
|
@@ -14,6 +15,7 @@ export interface Config {
|
|
|
14
15
|
overrides?: Record<string, string | false>;
|
|
15
16
|
mcpServers?: MCPServers;
|
|
16
17
|
workspaces?: boolean;
|
|
18
|
+
skipInstall?: boolean;
|
|
17
19
|
}
|
|
18
20
|
export type MCPServer = {
|
|
19
21
|
command: string;
|
|
@@ -44,7 +46,7 @@ export interface ResolvedConfig {
|
|
|
44
46
|
rules: RuleFile[];
|
|
45
47
|
mcpServers: MCPServers;
|
|
46
48
|
}
|
|
47
|
-
export declare const ALLOWED_CONFIG_KEYS: readonly ["rulesDir", "targets", "presets", "overrides", "mcpServers", "workspaces"];
|
|
49
|
+
export declare const ALLOWED_CONFIG_KEYS: readonly ["rulesDir", "targets", "presets", "overrides", "mcpServers", "workspaces", "skipInstall"];
|
|
48
50
|
export declare const SUPPORTED_TARGETS: readonly ["cursor", "windsurf", "codex"];
|
|
49
51
|
export type SupportedTarget = (typeof SUPPORTED_TARGETS)[number];
|
|
50
52
|
export declare function detectWorkspacesFromPackageJson(cwd: string): boolean;
|
package/dist/utils/config.js
CHANGED
|
@@ -27,6 +27,7 @@ exports.ALLOWED_CONFIG_KEYS = [
|
|
|
27
27
|
"overrides",
|
|
28
28
|
"mcpServers",
|
|
29
29
|
"workspaces",
|
|
30
|
+
"skipInstall",
|
|
30
31
|
];
|
|
31
32
|
exports.SUPPORTED_TARGETS = ["cursor", "windsurf", "codex"];
|
|
32
33
|
function detectWorkspacesFromPackageJson(cwd) {
|
|
@@ -60,6 +61,7 @@ function applyDefaults(config, workspaces) {
|
|
|
60
61
|
overrides: config.overrides || {},
|
|
61
62
|
mcpServers: config.mcpServers || {},
|
|
62
63
|
workspaces,
|
|
64
|
+
skipInstall: config.skipInstall || false,
|
|
63
65
|
};
|
|
64
66
|
}
|
|
65
67
|
function validateConfig(config, configFilePath, cwd, isWorkspaceMode = false) {
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export type RuleMetadata = Record<string, string | boolean | string[]>;
|
|
2
|
+
/**
|
|
3
|
+
* Parse YAML frontmatter blocks from a rule file and return a flat metadata object
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseRuleFrontmatter(content: string): RuleMetadata;
|
|
1
6
|
/**
|
|
2
7
|
* Write rules to the .windsurfrules file
|
|
3
8
|
* This will update the content between the RULES_BEGIN and RULES_END markers
|
|
@@ -3,10 +3,55 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseRuleFrontmatter = parseRuleFrontmatter;
|
|
6
7
|
exports.writeRulesFile = writeRulesFile;
|
|
7
8
|
exports.generateRulesFileContent = generateRulesFileContent;
|
|
8
9
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
10
|
const path_1 = __importDefault(require("path"));
|
|
11
|
+
/**
|
|
12
|
+
* Parse YAML frontmatter blocks from a rule file and return a flat metadata object
|
|
13
|
+
*/
|
|
14
|
+
function parseRuleFrontmatter(content) {
|
|
15
|
+
const metadata = {};
|
|
16
|
+
// Support both LF and CRLF line endings
|
|
17
|
+
const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---/gm;
|
|
18
|
+
let match;
|
|
19
|
+
while ((match = frontmatterRegex.exec(content)) !== null) {
|
|
20
|
+
const lines = match[1].split("\n");
|
|
21
|
+
for (const line of lines) {
|
|
22
|
+
const trimmed = line.trim();
|
|
23
|
+
if (!trimmed)
|
|
24
|
+
continue;
|
|
25
|
+
const [key, ...rest] = trimmed.split(":");
|
|
26
|
+
if (!key)
|
|
27
|
+
continue;
|
|
28
|
+
const raw = rest.join(":").trim();
|
|
29
|
+
if (raw === "") {
|
|
30
|
+
metadata[key] = "";
|
|
31
|
+
}
|
|
32
|
+
else if (raw === "true" || raw === "false") {
|
|
33
|
+
metadata[key] = raw === "true";
|
|
34
|
+
}
|
|
35
|
+
else if (raw.startsWith("[") && raw.endsWith("]")) {
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(raw.replace(/'/g, '"'));
|
|
38
|
+
metadata[key] = parsed;
|
|
39
|
+
}
|
|
40
|
+
catch (_a) {
|
|
41
|
+
metadata[key] = raw;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if ((raw.startsWith('"') && raw.endsWith('"')) ||
|
|
45
|
+
(raw.startsWith("'") && raw.endsWith("'"))) {
|
|
46
|
+
metadata[key] = raw.slice(1, -1);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
metadata[key] = raw;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return metadata;
|
|
54
|
+
}
|
|
10
55
|
const RULES_BEGIN = "<!-- AICM:BEGIN -->";
|
|
11
56
|
const RULES_END = "<!-- AICM:END -->";
|
|
12
57
|
const WARNING = "<!-- WARNING: Everything between these markers will be overwritten during installation -->";
|
|
@@ -118,7 +163,7 @@ function generateRulesFileContent(ruleFiles) {
|
|
|
118
163
|
// Agent Requested rules
|
|
119
164
|
if (agentRequestedRules.length > 0) {
|
|
120
165
|
content +=
|
|
121
|
-
"The following rules
|
|
166
|
+
"The following rules can be loaded when relevant. Check each file's description:\n";
|
|
122
167
|
agentRequestedRules.forEach((rule) => {
|
|
123
168
|
content += `- ${rule}\n`;
|
|
124
169
|
});
|
package/package.json
CHANGED
package/dist/api_v2.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { InstallOptions, InstallResult } from "./commands/install";
|
|
2
|
-
/**
|
|
3
|
-
* Install AICM rules based on configuration (v2)
|
|
4
|
-
* @param options Installation options
|
|
5
|
-
* @returns Result of the install operation
|
|
6
|
-
*/
|
|
7
|
-
export declare function install(options?: InstallOptions): Promise<InstallResult>;
|
|
8
|
-
export type { InstallOptions, InstallResult } from "./commands/install";
|
|
9
|
-
export type { ResolvedConfig, Config, RuleFile, MCPServers, } from "./utils/config";
|
package/dist/api_v2.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.install = install;
|
|
4
|
-
const install_1 = require("./commands/install");
|
|
5
|
-
/**
|
|
6
|
-
* Install AICM rules based on configuration (v2)
|
|
7
|
-
* @param options Installation options
|
|
8
|
-
* @returns Result of the install operation
|
|
9
|
-
*/
|
|
10
|
-
async function install(options = {}) {
|
|
11
|
-
return (0, install_1.install)(options);
|
|
12
|
-
}
|
package/dist/bin/aicm_v2.d.ts
DELETED
package/dist/bin/aicm_v2.js
DELETED
package/dist/cli_v2.d.ts
DELETED
package/dist/cli_v2.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
-
};
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.runCliV2 = runCliV2;
|
|
8
|
-
const arg_1 = __importDefault(require("arg"));
|
|
9
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
-
const init_1 = require("./commands/init");
|
|
11
|
-
const install_1 = require("./commands/install");
|
|
12
|
-
const list_1 = require("./commands/list");
|
|
13
|
-
// Define version from package.json
|
|
14
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
15
|
-
const pkg = require("../package.json");
|
|
16
|
-
async function runCliV2() {
|
|
17
|
-
const args = (0, arg_1.default)({
|
|
18
|
-
"--help": Boolean,
|
|
19
|
-
"--version": Boolean,
|
|
20
|
-
"--ci": Boolean,
|
|
21
|
-
"--verbose": Boolean,
|
|
22
|
-
"-h": "--help",
|
|
23
|
-
"-v": "--version",
|
|
24
|
-
}, {
|
|
25
|
-
permissive: true,
|
|
26
|
-
argv: process.argv.slice(2),
|
|
27
|
-
});
|
|
28
|
-
// Show version
|
|
29
|
-
if (args["--version"]) {
|
|
30
|
-
console.log(pkg.version);
|
|
31
|
-
process.exit(0);
|
|
32
|
-
}
|
|
33
|
-
// Show help
|
|
34
|
-
if (args["--help"]) {
|
|
35
|
-
showHelp();
|
|
36
|
-
process.exit(0);
|
|
37
|
-
}
|
|
38
|
-
const command = args._.length > 0 ? args._[0] : null;
|
|
39
|
-
try {
|
|
40
|
-
switch (command) {
|
|
41
|
-
case "init":
|
|
42
|
-
(0, init_1.initCommand)();
|
|
43
|
-
break;
|
|
44
|
-
case "install":
|
|
45
|
-
await (0, install_1.installCommand)(args["--ci"], args["--verbose"]);
|
|
46
|
-
break;
|
|
47
|
-
case "list":
|
|
48
|
-
await (0, list_1.listCommand)();
|
|
49
|
-
break;
|
|
50
|
-
default:
|
|
51
|
-
showHelp();
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
logError(error, args["--verbose"]);
|
|
57
|
-
process.exit(1);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
function showHelp() {
|
|
61
|
-
console.log(`
|
|
62
|
-
${chalk_1.default.bold("aicm v2")} - A CLI tool for managing AI IDE configurations (v2)
|
|
63
|
-
|
|
64
|
-
${chalk_1.default.bold("USAGE")}
|
|
65
|
-
$ aicm-v2 [command] [options]
|
|
66
|
-
|
|
67
|
-
${chalk_1.default.bold("COMMANDS")}
|
|
68
|
-
init Initialize a new aicm configuration file
|
|
69
|
-
install Install rules from configured sources
|
|
70
|
-
list List all configured rules and their status
|
|
71
|
-
|
|
72
|
-
${chalk_1.default.bold("OPTIONS")}
|
|
73
|
-
-h, --help Show this help message
|
|
74
|
-
-v, --version Show version number
|
|
75
|
-
--ci Run in CI environments (default: \`false\`)
|
|
76
|
-
--verbose Show detailed output and stack traces for debugging
|
|
77
|
-
|
|
78
|
-
${chalk_1.default.bold("EXAMPLES")}
|
|
79
|
-
$ aicm-v2 init
|
|
80
|
-
$ aicm-v2 install
|
|
81
|
-
$ aicm-v2 list
|
|
82
|
-
`);
|
|
83
|
-
}
|
|
84
|
-
function logError(error, verbose) {
|
|
85
|
-
if (error instanceof Error) {
|
|
86
|
-
console.error(chalk_1.default.red(`Error: ${error.message}`));
|
|
87
|
-
if (verbose && error.stack) {
|
|
88
|
-
console.error(chalk_1.default.gray(error.stack));
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
console.error(chalk_1.default.red(`Error: ${String(error)}`));
|
|
93
|
-
}
|
|
94
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { NormalizedConfig } from "../../types";
|
|
2
|
-
/**
|
|
3
|
-
* Options for the install functions
|
|
4
|
-
*/
|
|
5
|
-
export interface InstallOptions {
|
|
6
|
-
/**
|
|
7
|
-
* Base directory to use instead of process.cwd()
|
|
8
|
-
*/
|
|
9
|
-
cwd?: string;
|
|
10
|
-
/**
|
|
11
|
-
* Custom config object to use instead of loading from file
|
|
12
|
-
*/
|
|
13
|
-
config?: NormalizedConfig;
|
|
14
|
-
/**
|
|
15
|
-
* allow installation on CI environments
|
|
16
|
-
*/
|
|
17
|
-
installOnCI?: boolean;
|
|
18
|
-
/**
|
|
19
|
-
* Show verbose output during installation
|
|
20
|
-
*/
|
|
21
|
-
verbose?: boolean;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Result of the install operation
|
|
25
|
-
*/
|
|
26
|
-
export interface InstallResult {
|
|
27
|
-
/**
|
|
28
|
-
* Whether the operation was successful
|
|
29
|
-
*/
|
|
30
|
-
success: boolean;
|
|
31
|
-
/**
|
|
32
|
-
* Error message if the operation failed
|
|
33
|
-
*/
|
|
34
|
-
error?: string;
|
|
35
|
-
/**
|
|
36
|
-
* Error stack trace for debugging (when available)
|
|
37
|
-
*/
|
|
38
|
-
errorStack?: string;
|
|
39
|
-
/**
|
|
40
|
-
* Number of rules installed
|
|
41
|
-
*/
|
|
42
|
-
installedRuleCount: number;
|
|
43
|
-
/**
|
|
44
|
-
* Number of packages installed
|
|
45
|
-
*/
|
|
46
|
-
packagesCount: number;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Install rules for a single package (used within workspaces and standalone installs)
|
|
50
|
-
* @param options Install options
|
|
51
|
-
* @returns Result of the install operation
|
|
52
|
-
*/
|
|
53
|
-
export declare function installPackage(options?: InstallOptions): Promise<InstallResult>;
|