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.
- package/dist/commands/install.js +5 -5
- 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
|
@@ -1,172 +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.installWorkspaces = installWorkspaces;
|
|
7
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
-
const node_child_process_1 = require("node:child_process");
|
|
9
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
-
const config_1 = require("../../utils/config");
|
|
11
|
-
const working_directory_1 = require("../../utils/working-directory");
|
|
12
|
-
const install_package_1 = require("./install-package");
|
|
13
|
-
/**
|
|
14
|
-
* Discover aicm.json files using git ls-files
|
|
15
|
-
* @param rootDir The root directory to search from
|
|
16
|
-
* @returns Array of aicm.json file paths
|
|
17
|
-
*/
|
|
18
|
-
function findAicmFiles(rootDir) {
|
|
19
|
-
const output = (0, node_child_process_1.execSync)("git ls-files --cached --others --exclude-standard aicm.json **/aicm.json", {
|
|
20
|
-
cwd: rootDir,
|
|
21
|
-
encoding: "utf8",
|
|
22
|
-
});
|
|
23
|
-
return output
|
|
24
|
-
.trim()
|
|
25
|
-
.split("\n")
|
|
26
|
-
.filter(Boolean)
|
|
27
|
-
.map((file) => node_path_1.default.resolve(rootDir, file));
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Discover all packages with aicm configurations
|
|
31
|
-
* @param rootDir The root directory to search from
|
|
32
|
-
* @returns Array of discovered packages
|
|
33
|
-
*/
|
|
34
|
-
async function discoverPackagesWithAicm(rootDir) {
|
|
35
|
-
const aicmFiles = findAicmFiles(rootDir);
|
|
36
|
-
const packages = [];
|
|
37
|
-
for (const aicmFile of aicmFiles) {
|
|
38
|
-
const packageDir = node_path_1.default.dirname(aicmFile);
|
|
39
|
-
const relativePath = node_path_1.default.relative(rootDir, packageDir);
|
|
40
|
-
// Normalize to forward slashes for cross-platform compatibility
|
|
41
|
-
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
42
|
-
const config = await (0, config_1.getConfig)(packageDir);
|
|
43
|
-
if (config) {
|
|
44
|
-
packages.push({
|
|
45
|
-
relativePath: normalizedRelativePath || ".",
|
|
46
|
-
absolutePath: packageDir,
|
|
47
|
-
config,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
// Sort packages by relativePath for deterministic order
|
|
52
|
-
return packages.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Install aicm configurations for all packages in a workspace
|
|
56
|
-
* @param packages The packages to install configurations for
|
|
57
|
-
* @param options Install options
|
|
58
|
-
* @returns Result of the workspace installation
|
|
59
|
-
*/
|
|
60
|
-
async function installWorkspacesPackages(packages, options = {}) {
|
|
61
|
-
const results = [];
|
|
62
|
-
let totalRuleCount = 0;
|
|
63
|
-
// Install packages sequentially for now (can be parallelized later)
|
|
64
|
-
for (const pkg of packages) {
|
|
65
|
-
const packagePath = pkg.absolutePath;
|
|
66
|
-
try {
|
|
67
|
-
const result = await (0, install_package_1.installPackage)({
|
|
68
|
-
...options,
|
|
69
|
-
cwd: packagePath,
|
|
70
|
-
});
|
|
71
|
-
totalRuleCount += result.installedRuleCount;
|
|
72
|
-
results.push({
|
|
73
|
-
path: pkg.relativePath,
|
|
74
|
-
success: result.success,
|
|
75
|
-
error: result.error,
|
|
76
|
-
errorStack: result.errorStack,
|
|
77
|
-
installedRuleCount: result.installedRuleCount,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
catch (error) {
|
|
81
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
82
|
-
results.push({
|
|
83
|
-
path: pkg.relativePath,
|
|
84
|
-
success: false,
|
|
85
|
-
error: errorMessage,
|
|
86
|
-
errorStack: error instanceof Error ? error.stack : undefined,
|
|
87
|
-
installedRuleCount: 0,
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
const failedPackages = results.filter((r) => !r.success);
|
|
92
|
-
return {
|
|
93
|
-
success: failedPackages.length === 0,
|
|
94
|
-
packages: results,
|
|
95
|
-
totalRuleCount,
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Install rules across multiple packages in a workspace
|
|
100
|
-
* @param cwd The current working directory
|
|
101
|
-
* @param installOnCI Whether to install on CI environments
|
|
102
|
-
* @param verbose Whether to show verbose output
|
|
103
|
-
* @returns Result of the install operation
|
|
104
|
-
*/
|
|
105
|
-
async function installWorkspaces(cwd, installOnCI, verbose = false) {
|
|
106
|
-
return (0, working_directory_1.withWorkingDirectory)(cwd, async () => {
|
|
107
|
-
if (verbose) {
|
|
108
|
-
console.log(chalk_1.default.blue("🔍 Discovering packages..."));
|
|
109
|
-
}
|
|
110
|
-
const allPackages = await discoverPackagesWithAicm(cwd);
|
|
111
|
-
const packages = allPackages.filter((pkg) => {
|
|
112
|
-
const isRoot = pkg.relativePath === ".";
|
|
113
|
-
if (!isRoot)
|
|
114
|
-
return true;
|
|
115
|
-
// For root directories, only keep if it has rules or presets
|
|
116
|
-
const hasRules = pkg.config.rules && Object.keys(pkg.config.rules).length > 0;
|
|
117
|
-
const hasPresets = pkg.config.presets && pkg.config.presets.length > 0;
|
|
118
|
-
return hasRules || hasPresets;
|
|
119
|
-
});
|
|
120
|
-
if (packages.length === 0) {
|
|
121
|
-
return {
|
|
122
|
-
success: false,
|
|
123
|
-
error: "No packages with aicm configurations found",
|
|
124
|
-
installedRuleCount: 0,
|
|
125
|
-
packagesCount: 0,
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
if (verbose) {
|
|
129
|
-
console.log(chalk_1.default.blue(`Found ${packages.length} packages with aicm configurations:`));
|
|
130
|
-
packages.forEach((pkg) => {
|
|
131
|
-
console.log(chalk_1.default.gray(` - ${pkg.relativePath}`));
|
|
132
|
-
});
|
|
133
|
-
console.log(chalk_1.default.blue(`📦 Installing configurations...`));
|
|
134
|
-
}
|
|
135
|
-
const result = await installWorkspacesPackages(packages, {
|
|
136
|
-
installOnCI,
|
|
137
|
-
});
|
|
138
|
-
if (verbose) {
|
|
139
|
-
result.packages.forEach((pkg) => {
|
|
140
|
-
if (pkg.success) {
|
|
141
|
-
console.log(chalk_1.default.green(`✅ ${pkg.path} (${pkg.installedRuleCount} rules)`));
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
console.log(chalk_1.default.red(`❌ ${pkg.path}: ${pkg.error}`));
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
const failedPackages = result.packages.filter((r) => !r.success);
|
|
149
|
-
if (failedPackages.length > 0) {
|
|
150
|
-
console.log(chalk_1.default.yellow(`Installation completed with errors`));
|
|
151
|
-
if (verbose) {
|
|
152
|
-
console.log(chalk_1.default.green(`Successfully installed: ${result.packages.length - failedPackages.length}/${result.packages.length} packages (${result.totalRuleCount} rules total)`));
|
|
153
|
-
console.log(chalk_1.default.red(`Failed packages: ${failedPackages.map((p) => p.path).join(", ")}`));
|
|
154
|
-
}
|
|
155
|
-
const errorDetails = failedPackages
|
|
156
|
-
.map((p) => `${p.path}: ${p.error}`)
|
|
157
|
-
.join("; ");
|
|
158
|
-
return {
|
|
159
|
-
success: false,
|
|
160
|
-
error: `Package installation failed for ${failedPackages.length} package(s): ${errorDetails}`,
|
|
161
|
-
installedRuleCount: result.totalRuleCount,
|
|
162
|
-
packagesCount: result.packages.length,
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
console.log(`Successfully installed ${result.totalRuleCount} rules across ${result.packages.length} packages`);
|
|
166
|
-
return {
|
|
167
|
-
success: true,
|
|
168
|
-
installedRuleCount: result.totalRuleCount,
|
|
169
|
-
packagesCount: result.packages.length,
|
|
170
|
-
};
|
|
171
|
-
});
|
|
172
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { ResolvedConfig } from "../utils/config_v2";
|
|
2
|
-
export interface InstallOptions {
|
|
3
|
-
cwd?: string;
|
|
4
|
-
config?: ResolvedConfig;
|
|
5
|
-
installOnCI?: boolean;
|
|
6
|
-
verbose?: boolean;
|
|
7
|
-
}
|
|
8
|
-
export interface InstallResult {
|
|
9
|
-
success: boolean;
|
|
10
|
-
error?: string;
|
|
11
|
-
errorStack?: string;
|
|
12
|
-
installedRuleCount: number;
|
|
13
|
-
packagesCount: number;
|
|
14
|
-
}
|
|
15
|
-
export declare function installPackage(options?: InstallOptions): Promise<InstallResult>;
|
|
16
|
-
export declare function install(options?: InstallOptions): Promise<InstallResult>;
|
|
17
|
-
export declare function installCommand(installOnCI?: boolean, verbose?: boolean): Promise<void>;
|
|
@@ -1,457 +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.installPackage = installPackage;
|
|
7
|
-
exports.install = install;
|
|
8
|
-
exports.installCommand = installCommand;
|
|
9
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
-
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
11
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
-
const child_process_1 = require("child_process");
|
|
13
|
-
const ci_info_1 = require("ci-info");
|
|
14
|
-
const config_v2_1 = require("../utils/config_v2");
|
|
15
|
-
const working_directory_1 = require("../utils/working-directory");
|
|
16
|
-
function isInCIEnvironment() {
|
|
17
|
-
if (process.env.CI === "true")
|
|
18
|
-
return true;
|
|
19
|
-
if (process.env.CI === "false")
|
|
20
|
-
return false;
|
|
21
|
-
return ci_info_1.isCI;
|
|
22
|
-
}
|
|
23
|
-
function getIdePaths() {
|
|
24
|
-
const projectDir = process.cwd();
|
|
25
|
-
return {
|
|
26
|
-
cursor: node_path_1.default.join(projectDir, ".cursor", "rules", "aicm"),
|
|
27
|
-
windsurf: node_path_1.default.join(projectDir, ".aicm"),
|
|
28
|
-
codex: node_path_1.default.join(projectDir, ".aicm"),
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
function extractNamespaceFromPresetPath(presetPath) {
|
|
32
|
-
if (presetPath.startsWith("@")) {
|
|
33
|
-
return presetPath.split("/");
|
|
34
|
-
}
|
|
35
|
-
const parts = presetPath.split(/[/\\]/);
|
|
36
|
-
return parts.filter((part) => part.length > 0);
|
|
37
|
-
}
|
|
38
|
-
function writeCursorRules(rules, cursorRulesDir) {
|
|
39
|
-
fs_extra_1.default.emptyDirSync(cursorRulesDir);
|
|
40
|
-
for (const rule of rules) {
|
|
41
|
-
const ruleNameParts = rule.name.split(/[/\\]/).filter(Boolean);
|
|
42
|
-
let rulePath;
|
|
43
|
-
if (rule.presetName) {
|
|
44
|
-
const namespace = extractNamespaceFromPresetPath(rule.presetName);
|
|
45
|
-
rulePath = node_path_1.default.join(cursorRulesDir, ...namespace, ...ruleNameParts);
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
rulePath = node_path_1.default.join(cursorRulesDir, ...ruleNameParts);
|
|
49
|
-
}
|
|
50
|
-
const ruleFile = rulePath + ".mdc";
|
|
51
|
-
fs_extra_1.default.ensureDirSync(node_path_1.default.dirname(ruleFile));
|
|
52
|
-
fs_extra_1.default.writeFileSync(ruleFile, rule.content);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
function generateRulesFileContent(ruleFiles) {
|
|
56
|
-
const alwaysApplyRules = [];
|
|
57
|
-
const optInRules = [];
|
|
58
|
-
for (const rule of ruleFiles) {
|
|
59
|
-
const frontmatterMatch = rule.content.match(/^---\n([\s\S]*?)\n---/);
|
|
60
|
-
let alwaysApply = false;
|
|
61
|
-
if (frontmatterMatch) {
|
|
62
|
-
try {
|
|
63
|
-
const frontmatter = frontmatterMatch[1];
|
|
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
|
-
content +=
|
|
82
|
-
"<!-- WARNING: Everything between these markers will be overwritten during installation -->\n\n";
|
|
83
|
-
if (alwaysApplyRules.length > 0) {
|
|
84
|
-
content +=
|
|
85
|
-
"The following rules always apply to all files in the project:\n";
|
|
86
|
-
content += alwaysApplyRules.join("\n") + "\n\n";
|
|
87
|
-
}
|
|
88
|
-
if (optInRules.length > 0) {
|
|
89
|
-
content +=
|
|
90
|
-
"The following rules are available for the AI to include when needed:\n";
|
|
91
|
-
content += optInRules.join("\n") + "\n\n";
|
|
92
|
-
}
|
|
93
|
-
content += "<!-- AICM:END -->";
|
|
94
|
-
return content;
|
|
95
|
-
}
|
|
96
|
-
function writeRulesFile(rulesContent, rulesFilePath) {
|
|
97
|
-
const RULES_BEGIN = "<!-- AICM:BEGIN -->";
|
|
98
|
-
const RULES_END = "<!-- AICM:END -->";
|
|
99
|
-
let fileContent;
|
|
100
|
-
if (fs_extra_1.default.existsSync(rulesFilePath)) {
|
|
101
|
-
const existingContent = fs_extra_1.default.readFileSync(rulesFilePath, "utf8");
|
|
102
|
-
if (existingContent.includes(RULES_BEGIN) &&
|
|
103
|
-
existingContent.includes(RULES_END)) {
|
|
104
|
-
const beforeMarker = existingContent.split(RULES_BEGIN)[0];
|
|
105
|
-
const afterMarker = existingContent.split(RULES_END)[1];
|
|
106
|
-
fileContent = beforeMarker + rulesContent + afterMarker;
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
let separator = "";
|
|
110
|
-
if (!existingContent.endsWith("\n")) {
|
|
111
|
-
separator += "\n";
|
|
112
|
-
}
|
|
113
|
-
if (!existingContent.endsWith("\n\n")) {
|
|
114
|
-
separator += "\n";
|
|
115
|
-
}
|
|
116
|
-
fileContent = existingContent + separator + rulesContent;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
fileContent = rulesContent;
|
|
121
|
-
}
|
|
122
|
-
fs_extra_1.default.writeFileSync(rulesFilePath, fileContent);
|
|
123
|
-
}
|
|
124
|
-
function writeRulesForFile(rules, ruleDir, rulesFile) {
|
|
125
|
-
fs_extra_1.default.emptyDirSync(ruleDir);
|
|
126
|
-
const ruleFiles = rules.map((rule) => {
|
|
127
|
-
const ruleNameParts = rule.name.split(/[/\\]/).filter(Boolean);
|
|
128
|
-
let rulePath;
|
|
129
|
-
if (rule.presetName) {
|
|
130
|
-
const namespace = extractNamespaceFromPresetPath(rule.presetName);
|
|
131
|
-
rulePath = node_path_1.default.join(ruleDir, ...namespace, ...ruleNameParts);
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
rulePath = node_path_1.default.join(ruleDir, ...ruleNameParts);
|
|
135
|
-
}
|
|
136
|
-
const physicalRulePath = rulePath + ".md";
|
|
137
|
-
fs_extra_1.default.ensureDirSync(node_path_1.default.dirname(physicalRulePath));
|
|
138
|
-
fs_extra_1.default.writeFileSync(physicalRulePath, rule.content);
|
|
139
|
-
const relativeRuleDir = node_path_1.default.basename(ruleDir);
|
|
140
|
-
let windsurfPath;
|
|
141
|
-
if (rule.presetName) {
|
|
142
|
-
const namespace = extractNamespaceFromPresetPath(rule.presetName);
|
|
143
|
-
windsurfPath =
|
|
144
|
-
node_path_1.default.join(relativeRuleDir, ...namespace, ...ruleNameParts) + ".md";
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
windsurfPath = node_path_1.default.join(relativeRuleDir, ...ruleNameParts) + ".md";
|
|
148
|
-
}
|
|
149
|
-
const windsurfPathPosix = windsurfPath.replace(/\\/g, "/");
|
|
150
|
-
return {
|
|
151
|
-
name: rule.name,
|
|
152
|
-
path: windsurfPathPosix,
|
|
153
|
-
content: rule.content,
|
|
154
|
-
};
|
|
155
|
-
});
|
|
156
|
-
const rulesContent = generateRulesFileContent(ruleFiles);
|
|
157
|
-
writeRulesFile(rulesContent, node_path_1.default.join(process.cwd(), rulesFile));
|
|
158
|
-
}
|
|
159
|
-
function writeRulesToTargets(rules, targets) {
|
|
160
|
-
const idePaths = getIdePaths();
|
|
161
|
-
for (const target of targets) {
|
|
162
|
-
switch (target) {
|
|
163
|
-
case "cursor":
|
|
164
|
-
if (rules.length > 0) {
|
|
165
|
-
writeCursorRules(rules, idePaths.cursor);
|
|
166
|
-
}
|
|
167
|
-
break;
|
|
168
|
-
case "windsurf":
|
|
169
|
-
if (rules.length > 0) {
|
|
170
|
-
writeRulesForFile(rules, idePaths.windsurf, ".windsurfrules");
|
|
171
|
-
}
|
|
172
|
-
break;
|
|
173
|
-
case "codex":
|
|
174
|
-
if (rules.length > 0) {
|
|
175
|
-
writeRulesForFile(rules, idePaths.codex, "AGENTS.md");
|
|
176
|
-
}
|
|
177
|
-
break;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
function writeMcpServersToFile(mcpServers, mcpPath) {
|
|
182
|
-
var _a;
|
|
183
|
-
fs_extra_1.default.ensureDirSync(node_path_1.default.dirname(mcpPath));
|
|
184
|
-
const existingConfig = fs_extra_1.default.existsSync(mcpPath)
|
|
185
|
-
? fs_extra_1.default.readJsonSync(mcpPath)
|
|
186
|
-
: {};
|
|
187
|
-
const existingMcpServers = (_a = existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.mcpServers) !== null && _a !== void 0 ? _a : {};
|
|
188
|
-
const userMcpServers = {};
|
|
189
|
-
for (const [key, value] of Object.entries(existingMcpServers)) {
|
|
190
|
-
if (typeof value === "object" && value !== null && value.aicm !== true) {
|
|
191
|
-
userMcpServers[key] = value;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
const aicmMcpServers = {};
|
|
195
|
-
for (const [key, value] of Object.entries(mcpServers)) {
|
|
196
|
-
if (value !== false) {
|
|
197
|
-
aicmMcpServers[key] = {
|
|
198
|
-
...value,
|
|
199
|
-
aicm: true,
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
const mergedMcpServers = {
|
|
204
|
-
...userMcpServers,
|
|
205
|
-
...aicmMcpServers,
|
|
206
|
-
};
|
|
207
|
-
const mergedConfig = {
|
|
208
|
-
...existingConfig,
|
|
209
|
-
mcpServers: mergedMcpServers,
|
|
210
|
-
};
|
|
211
|
-
fs_extra_1.default.writeJsonSync(mcpPath, mergedConfig, { spaces: 2 });
|
|
212
|
-
}
|
|
213
|
-
function writeMcpServersToTargets(mcpServers, targets, cwd) {
|
|
214
|
-
if (!mcpServers || Object.keys(mcpServers).length === 0)
|
|
215
|
-
return;
|
|
216
|
-
for (const target of targets) {
|
|
217
|
-
if (target === "cursor") {
|
|
218
|
-
const mcpPath = node_path_1.default.join(cwd, ".cursor", "mcp.json");
|
|
219
|
-
writeMcpServersToFile(mcpServers, mcpPath);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
function findAicmFiles(rootDir) {
|
|
224
|
-
try {
|
|
225
|
-
const output = (0, child_process_1.execSync)("git ls-files --cached --others --exclude-standard aicm.json **/aicm.json", {
|
|
226
|
-
cwd: rootDir,
|
|
227
|
-
encoding: "utf8",
|
|
228
|
-
});
|
|
229
|
-
return output
|
|
230
|
-
.trim()
|
|
231
|
-
.split("\n")
|
|
232
|
-
.filter(Boolean)
|
|
233
|
-
.map((file) => node_path_1.default.resolve(rootDir, file));
|
|
234
|
-
}
|
|
235
|
-
catch (_a) {
|
|
236
|
-
return [];
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
async function discoverPackagesWithAicm(rootDir) {
|
|
240
|
-
const aicmFiles = findAicmFiles(rootDir);
|
|
241
|
-
const packages = [];
|
|
242
|
-
for (const aicmFile of aicmFiles) {
|
|
243
|
-
const packageDir = node_path_1.default.dirname(aicmFile);
|
|
244
|
-
const relativePath = node_path_1.default.relative(rootDir, packageDir);
|
|
245
|
-
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
246
|
-
const config = await (0, config_v2_1.loadConfig)(packageDir);
|
|
247
|
-
if (config) {
|
|
248
|
-
packages.push({
|
|
249
|
-
relativePath: normalizedRelativePath || ".",
|
|
250
|
-
absolutePath: packageDir,
|
|
251
|
-
config,
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
return packages.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
256
|
-
}
|
|
257
|
-
async function installPackage(options = {}) {
|
|
258
|
-
const cwd = options.cwd || process.cwd();
|
|
259
|
-
return (0, working_directory_1.withWorkingDirectory)(cwd, async () => {
|
|
260
|
-
let resolvedConfig;
|
|
261
|
-
if (options.config) {
|
|
262
|
-
resolvedConfig = options.config;
|
|
263
|
-
}
|
|
264
|
-
else {
|
|
265
|
-
resolvedConfig = await (0, config_v2_1.loadConfig)(cwd);
|
|
266
|
-
}
|
|
267
|
-
if (!resolvedConfig) {
|
|
268
|
-
return {
|
|
269
|
-
success: false,
|
|
270
|
-
error: "Configuration file not found",
|
|
271
|
-
installedRuleCount: 0,
|
|
272
|
-
packagesCount: 0,
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
const { config, rules, mcpServers } = resolvedConfig;
|
|
276
|
-
if (!rules || rules.length === 0) {
|
|
277
|
-
if (!config.presets || config.presets.length === 0) {
|
|
278
|
-
return {
|
|
279
|
-
success: false,
|
|
280
|
-
error: "No rules defined in configuration",
|
|
281
|
-
installedRuleCount: 0,
|
|
282
|
-
packagesCount: 0,
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
try {
|
|
287
|
-
writeRulesToTargets(rules, config.targets);
|
|
288
|
-
if (mcpServers && Object.keys(mcpServers).length > 0) {
|
|
289
|
-
writeMcpServersToTargets(mcpServers, config.targets, cwd);
|
|
290
|
-
}
|
|
291
|
-
return {
|
|
292
|
-
success: true,
|
|
293
|
-
installedRuleCount: rules.length,
|
|
294
|
-
packagesCount: 1,
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
catch (error) {
|
|
298
|
-
const errorMessage = `Error during installation: ${error instanceof Error ? error.message : String(error)}`;
|
|
299
|
-
return {
|
|
300
|
-
success: false,
|
|
301
|
-
error: errorMessage,
|
|
302
|
-
errorStack: error instanceof Error ? error.stack : undefined,
|
|
303
|
-
installedRuleCount: 0,
|
|
304
|
-
packagesCount: 0,
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
async function installWorkspacesPackages(packages, options = {}) {
|
|
310
|
-
const results = [];
|
|
311
|
-
let totalRuleCount = 0;
|
|
312
|
-
for (const pkg of packages) {
|
|
313
|
-
try {
|
|
314
|
-
const result = await installPackage({
|
|
315
|
-
...options,
|
|
316
|
-
cwd: pkg.absolutePath,
|
|
317
|
-
config: pkg.config,
|
|
318
|
-
});
|
|
319
|
-
totalRuleCount += result.installedRuleCount;
|
|
320
|
-
results.push({
|
|
321
|
-
path: pkg.relativePath,
|
|
322
|
-
success: result.success,
|
|
323
|
-
error: result.error,
|
|
324
|
-
errorStack: result.errorStack,
|
|
325
|
-
installedRuleCount: result.installedRuleCount,
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
catch (error) {
|
|
329
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
330
|
-
results.push({
|
|
331
|
-
path: pkg.relativePath,
|
|
332
|
-
success: false,
|
|
333
|
-
error: errorMessage,
|
|
334
|
-
errorStack: error instanceof Error ? error.stack : undefined,
|
|
335
|
-
installedRuleCount: 0,
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
const failedPackages = results.filter((r) => !r.success);
|
|
340
|
-
return {
|
|
341
|
-
success: failedPackages.length === 0,
|
|
342
|
-
packages: results,
|
|
343
|
-
totalRuleCount,
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
async function installWorkspaces(cwd, installOnCI, verbose = false) {
|
|
347
|
-
return (0, working_directory_1.withWorkingDirectory)(cwd, async () => {
|
|
348
|
-
if (verbose) {
|
|
349
|
-
console.log(chalk_1.default.blue("🔍 Discovering packages..."));
|
|
350
|
-
}
|
|
351
|
-
const allPackages = await discoverPackagesWithAicm(cwd);
|
|
352
|
-
const packages = allPackages.filter((pkg) => {
|
|
353
|
-
const isRoot = pkg.relativePath === ".";
|
|
354
|
-
if (!isRoot)
|
|
355
|
-
return true;
|
|
356
|
-
const hasRules = pkg.config.rules && pkg.config.rules.length > 0;
|
|
357
|
-
const hasPresets = pkg.config.config.presets && pkg.config.config.presets.length > 0;
|
|
358
|
-
return hasRules || hasPresets;
|
|
359
|
-
});
|
|
360
|
-
if (packages.length === 0) {
|
|
361
|
-
return {
|
|
362
|
-
success: false,
|
|
363
|
-
error: "No packages with aicm configurations found",
|
|
364
|
-
installedRuleCount: 0,
|
|
365
|
-
packagesCount: 0,
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
if (verbose) {
|
|
369
|
-
console.log(chalk_1.default.blue(`Found ${packages.length} packages with aicm configurations:`));
|
|
370
|
-
packages.forEach((pkg) => {
|
|
371
|
-
console.log(chalk_1.default.gray(` - ${pkg.relativePath}`));
|
|
372
|
-
});
|
|
373
|
-
console.log(chalk_1.default.blue(`📦 Installing configurations...`));
|
|
374
|
-
}
|
|
375
|
-
const result = await installWorkspacesPackages(packages, {
|
|
376
|
-
installOnCI,
|
|
377
|
-
verbose,
|
|
378
|
-
});
|
|
379
|
-
if (verbose) {
|
|
380
|
-
result.packages.forEach((pkg) => {
|
|
381
|
-
if (pkg.success) {
|
|
382
|
-
console.log(chalk_1.default.green(`✅ ${pkg.path} (${pkg.installedRuleCount} rules)`));
|
|
383
|
-
}
|
|
384
|
-
else {
|
|
385
|
-
console.log(chalk_1.default.red(`❌ ${pkg.path}: ${pkg.error}`));
|
|
386
|
-
}
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
const failedPackages = result.packages.filter((r) => !r.success);
|
|
390
|
-
if (failedPackages.length > 0) {
|
|
391
|
-
console.log(chalk_1.default.yellow(`Installation completed with errors`));
|
|
392
|
-
if (verbose) {
|
|
393
|
-
console.log(chalk_1.default.green(`Successfully installed: ${result.packages.length - failedPackages.length}/${result.packages.length} packages (${result.totalRuleCount} rules total)`));
|
|
394
|
-
console.log(chalk_1.default.red(`Failed packages: ${failedPackages.map((p) => p.path).join(", ")}`));
|
|
395
|
-
}
|
|
396
|
-
const errorDetails = failedPackages
|
|
397
|
-
.map((p) => `${p.path}: ${p.error}`)
|
|
398
|
-
.join("; ");
|
|
399
|
-
return {
|
|
400
|
-
success: false,
|
|
401
|
-
error: `Package installation failed for ${failedPackages.length} package(s): ${errorDetails}`,
|
|
402
|
-
installedRuleCount: result.totalRuleCount,
|
|
403
|
-
packagesCount: result.packages.length,
|
|
404
|
-
};
|
|
405
|
-
}
|
|
406
|
-
console.log(`Successfully installed ${result.totalRuleCount} rules across ${result.packages.length} packages`);
|
|
407
|
-
return {
|
|
408
|
-
success: true,
|
|
409
|
-
installedRuleCount: result.totalRuleCount,
|
|
410
|
-
packagesCount: result.packages.length,
|
|
411
|
-
};
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
async function install(options = {}) {
|
|
415
|
-
const cwd = options.cwd || process.cwd();
|
|
416
|
-
const installOnCI = options.installOnCI === true;
|
|
417
|
-
const inCI = isInCIEnvironment();
|
|
418
|
-
if (inCI && !installOnCI) {
|
|
419
|
-
console.log(chalk_1.default.yellow("Detected CI environment, skipping install."));
|
|
420
|
-
return {
|
|
421
|
-
success: true,
|
|
422
|
-
installedRuleCount: 0,
|
|
423
|
-
packagesCount: 0,
|
|
424
|
-
};
|
|
425
|
-
}
|
|
426
|
-
return (0, working_directory_1.withWorkingDirectory)(cwd, async () => {
|
|
427
|
-
let resolvedConfig;
|
|
428
|
-
if (options.config) {
|
|
429
|
-
resolvedConfig = options.config;
|
|
430
|
-
}
|
|
431
|
-
else {
|
|
432
|
-
resolvedConfig = await (0, config_v2_1.loadConfig)(cwd);
|
|
433
|
-
}
|
|
434
|
-
if (resolvedConfig === null || resolvedConfig === void 0 ? void 0 : resolvedConfig.config.workspaces) {
|
|
435
|
-
return await installWorkspaces(cwd, installOnCI, options.verbose);
|
|
436
|
-
}
|
|
437
|
-
return installPackage(options);
|
|
438
|
-
});
|
|
439
|
-
}
|
|
440
|
-
async function installCommand(installOnCI, verbose) {
|
|
441
|
-
const result = await install({ installOnCI, verbose });
|
|
442
|
-
if (!result.success) {
|
|
443
|
-
const error = new Error(result.error);
|
|
444
|
-
if (result.errorStack) {
|
|
445
|
-
error.stack = result.errorStack;
|
|
446
|
-
}
|
|
447
|
-
throw error;
|
|
448
|
-
}
|
|
449
|
-
else {
|
|
450
|
-
if (result.packagesCount > 1) {
|
|
451
|
-
console.log(`Successfully installed ${result.installedRuleCount} rules across ${result.packagesCount} packages`);
|
|
452
|
-
}
|
|
453
|
-
else {
|
|
454
|
-
console.log("Rules installation completed");
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { ResolvedConfig } from "../utils/config_v2";
|
|
2
|
-
export interface InstallOptions {
|
|
3
|
-
/**
|
|
4
|
-
* Base directory to use instead of process.cwd()
|
|
5
|
-
*/
|
|
6
|
-
cwd?: string;
|
|
7
|
-
/**
|
|
8
|
-
* Custom config object to use instead of loading from file
|
|
9
|
-
*/
|
|
10
|
-
config?: ResolvedConfig;
|
|
11
|
-
/**
|
|
12
|
-
* allow installation on CI environments
|
|
13
|
-
*/
|
|
14
|
-
installOnCI?: boolean;
|
|
15
|
-
/**
|
|
16
|
-
* Show verbose output during installation
|
|
17
|
-
*/
|
|
18
|
-
verbose?: boolean;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Result of the install operation
|
|
22
|
-
*/
|
|
23
|
-
export interface InstallResult {
|
|
24
|
-
/**
|
|
25
|
-
* Whether the operation was successful
|
|
26
|
-
*/
|
|
27
|
-
success: boolean;
|
|
28
|
-
/**
|
|
29
|
-
* Error object if the operation failed
|
|
30
|
-
*/
|
|
31
|
-
error?: Error;
|
|
32
|
-
/**
|
|
33
|
-
* Number of rules installed
|
|
34
|
-
*/
|
|
35
|
-
installedRuleCount: number;
|
|
36
|
-
/**
|
|
37
|
-
* Number of packages installed
|
|
38
|
-
*/
|
|
39
|
-
packagesCount: number;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Install rules for a single package (used within workspaces and standalone installs)
|
|
43
|
-
*/
|
|
44
|
-
export declare function installPackage(options?: InstallOptions): Promise<InstallResult>;
|
|
45
|
-
/**
|
|
46
|
-
* Core implementation of the rule installation logic
|
|
47
|
-
*/
|
|
48
|
-
export declare function install(options?: InstallOptions): Promise<InstallResult>;
|
|
49
|
-
/**
|
|
50
|
-
* CLI command wrapper for install
|
|
51
|
-
*/
|
|
52
|
-
export declare function installCommand(installOnCI?: boolean, verbose?: boolean): Promise<void>;
|