aicm 0.17.0 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,56 +2,76 @@
2
2
 
3
3
  > AI Configuration Manager
4
4
 
5
- A CLI tool for managing Agentic configurations across projects
5
+ A CLI tool for managing Agentic configurations across projects.
6
6
 
7
7
  ![aicm](https://github.com/user-attachments/assets/ca38f2d6-ece6-43ad-a127-6f4fce8b2a5a)
8
8
 
9
+ ## Table of Contents
10
+
11
+ - [Why](#why)
12
+ - [Supported Environments](#supported-environments)
13
+ - [Getting Started](#getting-started)
14
+ - [Creating a Preset](#creating-a-preset)
15
+ - [Using a Preset](#using-a-preset)
16
+ - [Features](#features)
17
+ - [Rules](#using-rules)
18
+ - [Commands](#using-commands)
19
+ - [MCP Servers](#mcp-servers)
20
+ - [Auxiliary Files](#referencing-auxiliary-files)
21
+ - [Overrides](#overrides)
22
+ - [Workspaces Support](#workspaces-support)
23
+ - [Configuration](#configuration)
24
+ - [CLI Commands](#cli-commands)
25
+ - [Node.js API](#nodejs-api)
26
+
9
27
  ## Why
10
28
 
11
- Modern AI-powered IDEs like Cursor and Agents like Codex enable developers to write custom instructions to maintain context across coding sessions. They also support MCPs for enhanced functionality. However, sharing these configurations across multiple projects is a challenge.
29
+ Modern AI-powered IDEs like Cursor and Agents like Codex allow developers to add custom instructions, commands, and MCP servers. However, keeping these configurations consistent across a team or multiple projects is a challenge.
12
30
 
13
- **aicm** solves this by enabling you to create reusable presets that bundle rules and MCP configurations together. With multi-target support, you can write your rules once and deploy them consistently across different AI tools and IDEs.
31
+ **aicm** enables **"Write Once, Use Everywhere"** for your AI configurations.
14
32
 
15
- ## How it works
33
+ - **Team Consistency:** Ensure every developer on your team uses the same rules and best practices.
34
+ - **Reusable Presets:** Bundle your rules, commands & MCP configurations into npm packages (e.g., `@company/ai-preset`) to share them across your organization.
35
+ - **Multi-Target Support:** Write rules once in the comprehensive `.mdc` format, and automatically deploy them to Cursor, Windsurf, Codex, and Claude.
16
36
 
17
- aicm accepts Cursor's `.mdc` format as it provides the most comprehensive feature set. For other AI tools and IDEs, aicm automatically generates compatible formats:
37
+ ## Supported Environments
18
38
 
19
- - **Cursor**: Native `.mdc` files with full feature support
20
- - **Windsurf**: Generates `.windsurfrules` file
21
- - **Codex**: Generates `AGENTS.md` file
22
- - **Claude**: Generates `CLAUDE.md` file
39
+ aicm acts as a bridge between your configuration and your AI tools. It accepts Cursor's `.mdc` format and can transform it for other environments:
23
40
 
24
- This approach ensures you write your rules once in the richest format available, while maintaining compatibility across different AI development environments.
41
+ | Target | Installation |
42
+ | ------------ | ------------------------------------------------------------------------------ |
43
+ | **Cursor** | Copies `.mdc` files to `.cursor/rules/aicm/` and configures `.cursor/mcp.json` |
44
+ | **Windsurf** | Generates a `.windsurfrules` file that links to rules in `.aicm/` |
45
+ | **Codex** | Generates an `AGENTS.md` file that references rules in `.aicm/` |
46
+ | **Claude** | Generates a `CLAUDE.md` file that references rules in `.aicm/` |
25
47
 
26
48
  ## Getting Started
27
49
 
28
50
  The easiest way to get started with aicm is by using **presets** - npm packages containing rules and MCP configurations that you can install in any project.
29
51
 
30
- ### Using a preset
52
+ ### Demo
31
53
 
32
- 1. **Install a preset npm package**:
54
+ We'll install [an npm package](https://github.com/ranyitz/pirate-coding) containing a simple "Pirate Coding" preset to demonstrate how aicm works.
55
+
56
+ 1. **Install the demo preset package**:
33
57
 
34
58
  ```bash
35
- npm install --save-dev @team/ai-preset
59
+ npm install --save-dev pirate-coding
36
60
  ```
37
61
 
38
- 2. **Create an `aicm.json` file** in your project root:
62
+ 2. **Create an `aicm.json` file** in your project:
39
63
 
40
- ```json
41
- { "presets": ["@team/ai-preset"] }
64
+ ```bash
65
+ echo '{ "presets": ["pirate-coding"] }' > aicm.json
42
66
  ```
43
67
 
44
- 3. **Add a prepare script** to your `package.json` to install all preset rules and MCPs:
68
+ 3. **Install all rules & MCPs from your configuration**:
45
69
 
46
- ```json
47
- {
48
- "scripts": {
49
- "prepare": "npx aicm -y install"
50
- }
51
- }
70
+ ```bash
71
+ npx aicm install
52
72
  ```
53
73
 
54
- The rules are now installed in `.cursor/rules/aicm/` and any MCP servers are configured in `.cursor/mcp.json`.
74
+ After installation, open Cursor and ask it to do something. Your AI assistant will respond with pirate-themed coding advice.
55
75
 
56
76
  ### Creating a Preset
57
77
 
@@ -85,48 +105,59 @@ The rules are now installed in `.cursor/rules/aicm/` and any MCP servers are con
85
105
 
86
106
  > **Note:** This is syntactic sugar for `@team/ai-preset/aicm.json`.
87
107
 
88
- ### Using Local Rules
108
+ ### Using a Preset
109
+
110
+ To use a real preset in your production project:
111
+
112
+ 1. **Install a preset npm package**:
113
+
114
+ ```bash
115
+ npm install --save-dev @team/ai-preset
116
+ ```
89
117
 
90
- For project-specific rules, you can specify `rulesDir` in your `aicm.json` config. This approach allows you to write rules once and automatically generate them for all configured targets.
118
+ 2. **Create an `aicm.json` file** in your project root:
91
119
 
92
120
  ```json
93
- {
94
- "rulesDir": "path/to/rules/dir"
95
- }
121
+ { "presets": ["@team/ai-preset"] }
96
122
  ```
97
123
 
98
- **Referencing Auxiliary Files**
124
+ 3. **Add a prepare script** to your `package.json` to ensure rules are always up to date:
99
125
 
100
- You can place any file (e.g., `example.ts`, `schema.json`, `guide.md`) in your `rulesDir` alongside your `.mdc` files. These assets are automatically copied to the target location. You can reference them in your rules using relative paths, and aicm will automatically rewrite the links to point to the correct location for each target IDE.
126
+ ```json
127
+ {
128
+ "scripts": {
129
+ "prepare": "npx aicm -y install"
130
+ }
131
+ }
132
+ ```
101
133
 
102
- Example `rules/my-rule.mdc`:
134
+ The rules are now installed in `.cursor/rules/aicm/` and any MCP servers are configured in `.cursor/mcp.json`.
103
135
 
104
- ```markdown
105
- # My Rule
136
+ ### Notes
106
137
 
107
- See [Example](./example.ts) for details.
108
- ```
138
+ - Generated rules are always placed in a subdirectory for deterministic cleanup and easy gitignore.
139
+ - Users should add `.cursor/rules/aicm/` and `.aicm/` (for Windsurf/Codex) to `.gitignore` to avoid tracking generated rules.
109
140
 
110
- **Commands referencing files**
141
+ ## Features
111
142
 
112
- You can also use this feature to create commands that reference auxiliary files in your `rulesDir`. Since assets in `rulesDir` are copied to the target directory, your commands can link to them.
143
+ ### Using Rules
113
144
 
114
- For example, if you have a schema file at `rules/schema.json` and a command at `commands/generate-schema.md`:
145
+ aicm uses Cursor's `.mdc` files for rules. Read more about the format [here](https://cursor.com/docs/context/rules).
115
146
 
116
- ```markdown
117
- # Generate Schema
147
+ Add a rules directory to your project configuration:
118
148
 
119
- Use the schema defined in [Schema Template](../rules/schema.json) to generate the response.
149
+ ```json
150
+ {
151
+ "rulesDir": "./rules",
152
+ "targets": ["cursor"]
153
+ }
120
154
  ```
121
155
 
122
- When installed, `aicm` will automatically rewrite the link to point to the correct location of `schema.json` in the target environment (e.g., `../../rules/aicm/schema.json` for Cursor).
156
+ Rules are installed in `.cursor/rules/aicm/` and are loaded automatically by Cursor.
123
157
 
124
158
  ### Using Commands
125
159
 
126
- Cursor supports custom commands that can be invoked directly in the chat interface. aicm can manage these command files
127
- alongside your rules and MCP configurations so they install automatically into Cursor.
128
-
129
- #### Local Commands
160
+ Cursor supports custom commands that can be invoked directly in the chat interface. aicm can manage these command files alongside your rules and MCP configurations.
130
161
 
131
162
  Add a commands directory to your project configuration:
132
163
 
@@ -139,84 +170,66 @@ Add a commands directory to your project configuration:
139
170
 
140
171
  Command files ending in `.md` are installed to `.cursor/commands/aicm/` and appear in Cursor under the `/` command menu.
141
172
 
142
- #### Commands in Presets
173
+ ### MCP Servers
143
174
 
144
- Presets can ship reusable command libraries in addition to rules:
175
+ You can configure MCP servers directly in your `aicm.json`, which is useful for sharing mcp configurations across your team or bundling them into presets.
145
176
 
146
177
  ```json
147
178
  {
148
- "rulesDir": "rules",
149
- "commandsDir": "commands"
179
+ "mcpServers": {
180
+ "Playwright": {
181
+ "command": "npx",
182
+ "args": ["@playwright/mcp"]
183
+ }
184
+ }
150
185
  }
151
186
  ```
152
187
 
153
- Preset command files install alongside local ones in `.cursor/commands/aicm/` so they appear with concise paths inside Cursor.
154
- If multiple presets provide a command at the same relative path, aicm will warn during installation and use the version from the
155
- last preset listed in your configuration. Use `overrides` to explicitly choose a different definition when needed.
188
+ When installed, these servers are automatically added to your `.cursor/mcp.json`.
156
189
 
157
- #### Command Overrides
190
+ ### Referencing Auxiliary Files
158
191
 
159
- Use the existing `overrides` field to customize or disable commands provided by presets:
192
+ You can place any file (e.g., `example.ts`, `schema.json`, `guide.md`) in your `rulesDir` alongside your `.mdc` files. These assets are automatically copied to the target location. You can reference them in your rules using relative paths, and aicm will automatically rewrite the links to point to the correct location for each target IDE.
160
193
 
161
- ```json
162
- {
163
- "presets": ["@team/dev-preset"],
164
- "overrides": {
165
- "legacy-command": false,
166
- "custom-test": "./commands/test.md"
167
- }
168
- }
194
+ Example `rules/my-rule.mdc`:
195
+
196
+ ```markdown
197
+ # My Rule
198
+
199
+ See [Example](./example.ts) for details.
169
200
  ```
170
201
 
171
- ### Notes
202
+ #### Commands Referencing Files
172
203
 
173
- - Generated rules are always placed in a subdirectory for deterministic cleanup and easy gitignore.
174
- - Users may add `.cursor/rules/aicm/` and `.aicm/` (for Windsurf/Codex) to `.gitignore` if they do not want to track generated rules.
204
+ You can also use this feature to create commands that reference auxiliary files in your `rulesDir`. Since assets in `rulesDir` are copied to the target directory, your commands can link to them.
205
+
206
+ For example, if you have a schema file at `rules/schema.json` and a command at `commands/generate-schema.md`:
207
+
208
+ ```markdown
209
+ # Generate Schema
210
+
211
+ Use the schema defined in [Schema Template](../rules/schema.json) to generate the response.
212
+ ```
213
+
214
+ When installed, `aicm` will automatically rewrite the link to point to the correct location of `schema.json` in the target environment (e.g., `../../rules/aicm/schema.json` for Cursor).
215
+
216
+ > **Note:** Path rewriting works for any relative path format in your commands - markdown links, inline code references, or bare paths - as long as they point to actual files in your `rulesDir`.
175
217
 
176
218
  ### Overrides
177
219
 
178
- You can disable or replace specific rules provided by presets using the `overrides` field:
220
+ You can disable or replace specific rules or commands provided by presets using the `overrides` field:
179
221
 
180
222
  ```json
181
223
  {
182
224
  "presets": ["@company/ai-rules"],
183
225
  "overrides": {
184
226
  "rule-from-preset-a": "./rules/override-rule.mdc",
185
- "rule-from-preset-b": false
227
+ "rule-from-preset-b": false,
228
+ "legacy-command": false
186
229
  }
187
230
  }
188
231
  ```
189
232
 
190
- ### Demo
191
-
192
- We'll install [an npm package](https://github.com/ranyitz/pirate-coding) containing a simple preset to demonstrate how aicm works.
193
-
194
- 1. **Install the demo preset package**:
195
-
196
- ```bash
197
- npm install --save-dev pirate-coding
198
- ```
199
-
200
- 2. **Create an `aicm.json` file** in your project:
201
-
202
- ```bash
203
- echo '{ "presets": ["pirate-coding"] }' > aicm.json
204
- ```
205
-
206
- 3. **Install all rules & MCPs from your configuration**:
207
-
208
- ```bash
209
- npx aicm install
210
- ```
211
-
212
- This command installs all configured rules and MCPs to their IDE-specific locations.
213
-
214
- After installation, open Cursor and ask it to do something. Your AI assistant will respond with pirate-themed coding advice. You can also ask it about the aicm library which uses https://gitmcp.io/ to give you advice based on the latest documentation.
215
-
216
- ## Security Note
217
-
218
- To prevent [prompt-injection](https://en.wikipedia.org/wiki/Prompt_injection), use only packages from trusted sources.
219
-
220
233
  ## Workspaces Support
221
234
 
222
235
  aicm supports workspaces by automatically discovering and installing configurations across multiple packages in your repository.
@@ -229,17 +242,14 @@ You can enable workspaces mode by setting the `workspaces` property to `true` in
229
242
  }
230
243
  ```
231
244
 
232
- aicm automatically detects workspaces if your `package.json` contains a `workspaces` configuration:
233
-
234
- ### How It Works
235
-
236
- 1. **Discover packages**: Automatically find all directories containing `aicm.json` files in your repository
237
- 2. **Install per package**: Install rules and MCPs for each package individually in their respective directories
238
- 3. **Merge MCP servers**: Write a merged `.cursor/mcp.json` at the repository root containing all MCP servers from every package
245
+ aicm automatically detects workspaces if your `package.json` contains a `workspaces` configuration.
239
246
 
240
247
  ### How It Works
241
248
 
242
- Each directory containing an `aicm.json` file is treated as a separate package with its own configuration.
249
+ 1. **Discover packages**: Automatically find all directories containing `aicm.json` files in your repository.
250
+ 2. **Install per package**: Install rules and MCPs for each package individually in their respective directories.
251
+ 3. **Merge MCP servers**: Write a merged `.cursor/mcp.json` at the repository root containing all MCP servers from every package.
252
+ 4. **Merge commands**: Write a merged `.cursor/commands/aicm/` at the repository root containing all commands from every package.
243
253
 
244
254
  For example, in a workspace structure like:
245
255
 
@@ -300,17 +310,7 @@ Create an `aicm.json` file in your project root, or an `aicm` key in your projec
300
310
  - **workspaces**: Set to `true` to enable workspace mode. If not specified, aicm will automatically detect workspaces from your `package.json`.
301
311
  - **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.
302
312
 
303
- ### MCP Server Installation
304
-
305
- - **Cursor**: MCP server configs are written to `.cursor/mcp.json`.
306
-
307
- ## Supported Targets
308
-
309
- - **Cursor**: Rules are installed as individual `.mdc` files in the Cursor rules directory (`.cursor/rules/aicm/`), mcp servers are installed to `.cursor/mcp.json`
310
- - **Windsurf**: Rules are installed in the `.aicm` directory which should be added to your `.gitignore` file. Our approach for Windsurf is to create links from the `.windsurfrules` file to the respective rules in the `.aicm` directory. There is no support for local mcp servers at the moment.
311
- - **Codex**: Rules are installed in the `.aicm` directory and referenced from `AGENTS.md`.
312
-
313
- ## Commands
313
+ ## CLI Commands
314
314
 
315
315
  ### Global Options
316
316
 
@@ -373,27 +373,9 @@ install({
373
373
  });
374
374
  ```
375
375
 
376
- ### API Reference
377
-
378
- #### `install(options?: InstallOptions): Promise<InstallResult>`
379
-
380
- Installs rules and MCP servers based on configuration.
381
-
382
- **Options:**
383
-
384
- - `cwd`: Base directory to use instead of `process.cwd()`
385
- - `config`: Custom config object to use instead of loading from file
386
- - `installOnCI`: Run installation on CI environments (default: `false`)
387
- - `verbose`: Show verbose output and stack traces for debugging (default: `false`)
388
- - `dryRun`: Simulate installation without writing files, useful for preset validation in CI (default: `false`)
389
-
390
- **Returns:**
391
-
392
- A Promise that resolves to an object with:
376
+ ## Security Note
393
377
 
394
- - `success`: Whether the operation was successful
395
- - `error`: Error object if the operation failed
396
- - `installedRuleCount`: Number of rules installed
378
+ To prevent [prompt-injection](https://en.wikipedia.org/wiki/Prompt_injection), use only packages from trusted sources.
397
379
 
398
380
  ## Contributing
399
381
 
@@ -41,7 +41,7 @@ function writeCursorRules(rules, cursorRulesDir) {
41
41
  fs_extra_1.default.writeFileSync(ruleFile, rule.content);
42
42
  }
43
43
  }
44
- function writeCursorCommands(commands, cursorCommandsDir) {
44
+ function writeCursorCommands(commands, cursorCommandsDir, assets) {
45
45
  fs_extra_1.default.removeSync(cursorCommandsDir);
46
46
  for (const command of commands) {
47
47
  const commandNameParts = command.name
@@ -56,22 +56,18 @@ function writeCursorCommands(commands, cursorCommandsDir) {
56
56
  // Rules/assets are installed in .cursor/rules/aicm/
57
57
  // So a link like "../rules/asset.json" in source (from commands/ to rules/)
58
58
  // needs to become "../../rules/aicm/asset.json" in target (from .cursor/commands/aicm/ to .cursor/rules/aicm/)
59
- const content = rewriteCommandRelativeLinks(command.content);
59
+ const content = rewriteCommandRelativeLinks(command.content, command.sourcePath, assets);
60
60
  fs_extra_1.default.writeFileSync(commandFile, content);
61
61
  }
62
62
  }
63
- function rewriteCommandRelativeLinks(content) {
64
- return content.replace(/\[([^\]]*)\]\(([^)]+)\)/g, (match, text, url) => {
65
- if (url.startsWith("http") || url.startsWith("#") || url.startsWith("/")) {
66
- return match;
67
- }
68
- // Check if it's a link to the rules directory
69
- if (url.includes("rules/")) {
70
- const parts = url.split("/");
71
- const filename = parts[parts.length - 1];
72
- return `[${text}](../../rules/aicm/${filename})`;
73
- }
74
- return match;
63
+ function rewriteCommandRelativeLinks(content, commandSourcePath, assets) {
64
+ const commandDir = node_path_1.default.dirname(commandSourcePath);
65
+ const assetMap = new Map(assets.map((a) => [node_path_1.default.normalize(a.sourcePath), a.name]));
66
+ return content.replace(/\.\.[/\\][\w\-/\\.]+/g, (match) => {
67
+ const resolved = node_path_1.default.normalize(node_path_1.default.resolve(commandDir, match));
68
+ return assetMap.has(resolved)
69
+ ? `../../rules/aicm/${assetMap.get(resolved)}`
70
+ : match;
75
71
  });
76
72
  }
77
73
  function extractNamespaceFromPresetPath(presetPath) {
@@ -189,13 +185,13 @@ function writeRulesToTargets(rules, assets, targets) {
189
185
  // Write assets after rules so they don't get wiped by emptyDirSync
190
186
  writeAssetsToTargets(assets, targets);
191
187
  }
192
- function writeCommandsToTargets(commands, targets) {
188
+ function writeCommandsToTargets(commands, assets, targets) {
193
189
  const projectDir = process.cwd();
194
190
  const cursorRoot = node_path_1.default.join(projectDir, ".cursor");
195
191
  for (const target of targets) {
196
192
  if (target === "cursor") {
197
193
  const commandsDir = node_path_1.default.join(cursorRoot, "commands", "aicm");
198
- writeCursorCommands(commands, commandsDir);
194
+ writeCursorCommands(commands, commandsDir, assets);
199
195
  }
200
196
  // Other targets do not support commands yet
201
197
  }
@@ -427,7 +423,7 @@ async function installPackage(options = {}) {
427
423
  try {
428
424
  if (!options.dryRun) {
429
425
  writeRulesToTargets(rules, assets, config.targets);
430
- writeCommandsToTargets(commandsToInstall, config.targets);
426
+ writeCommandsToTargets(commandsToInstall, assets, config.targets);
431
427
  if (mcpServers && Object.keys(mcpServers).length > 0) {
432
428
  writeMcpServersToTargets(mcpServers, config.targets, cwd);
433
429
  }
@@ -556,7 +552,9 @@ async function installWorkspaces(cwd, installOnCI, verbose = false, dryRun = fal
556
552
  workspaceCommands.length > 0 &&
557
553
  workspaceCommandTargets.length > 0) {
558
554
  const dedupedWorkspaceCommands = dedupeCommandsForInstall(workspaceCommands);
559
- writeCommandsToTargets(dedupedWorkspaceCommands, workspaceCommandTargets);
555
+ // Collect all assets from packages for command path rewriting
556
+ const allAssets = packages.flatMap((pkg) => { var _a; return (_a = pkg.config.assets) !== null && _a !== void 0 ? _a : []; });
557
+ writeCommandsToTargets(dedupedWorkspaceCommands, allAssets, workspaceCommandTargets);
560
558
  }
561
559
  const { merged: rootMcp, conflicts } = mergeWorkspaceMcpServers(packages);
562
560
  const hasCursorTarget = packages.some((p) => p.config.config.targets.includes("cursor"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aicm",
3
- "version": "0.17.0",
3
+ "version": "0.17.1",
4
4
  "description": "A TypeScript CLI tool for managing AI IDE rules across different projects and teams",
5
5
  "main": "dist/api.js",
6
6
  "types": "dist/api.d.ts",