aicm 0.19.0 → 0.19.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/dist/api.d.ts CHANGED
@@ -5,6 +5,12 @@ import { InstallOptions, InstallResult } from "./commands/install";
5
5
  * @returns Result of the install operation
6
6
  */
7
7
  export declare function install(options?: InstallOptions): Promise<InstallResult>;
8
+ /**
9
+ * Check if workspaces mode is enabled without loading all rules/presets
10
+ * @param cwd Current working directory (optional, defaults to process.cwd())
11
+ * @returns True if workspaces mode is enabled
12
+ */
13
+ export declare function checkWorkspacesEnabled(cwd?: string): Promise<boolean>;
8
14
  export type { InstallOptions, InstallResult } from "./commands/install";
9
15
  export type { ResolvedConfig, Config, RuleFile, CommandFile, MCPServers, } from "./utils/config";
10
16
  export type { HookFile, HooksJson, HookType, HookCommand } from "./utils/hooks";
package/dist/api.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.install = install;
4
+ exports.checkWorkspacesEnabled = checkWorkspacesEnabled;
4
5
  const install_1 = require("./commands/install");
6
+ const config_1 = require("./utils/config");
5
7
  /**
6
8
  * Install AICM rules based on configuration
7
9
  * @param options Installation options
@@ -10,3 +12,11 @@ const install_1 = require("./commands/install");
10
12
  async function install(options = {}) {
11
13
  return (0, install_1.install)(options);
12
14
  }
15
+ /**
16
+ * Check if workspaces mode is enabled without loading all rules/presets
17
+ * @param cwd Current working directory (optional, defaults to process.cwd())
18
+ * @returns True if workspaces mode is enabled
19
+ */
20
+ async function checkWorkspacesEnabled(cwd) {
21
+ return (0, config_1.checkWorkspacesEnabled)(cwd);
22
+ }
@@ -251,11 +251,9 @@ async function cleanWorkspaces(cwd, verbose = false) {
251
251
  };
252
252
  }
253
253
  async function clean(options = {}) {
254
- var _a;
255
254
  const cwd = options.cwd || process.cwd();
256
255
  const verbose = options.verbose || false;
257
- const shouldUseWorkspaces = ((_a = (await (0, config_1.loadConfig)(cwd))) === null || _a === void 0 ? void 0 : _a.config.workspaces) ||
258
- (0, config_1.detectWorkspacesFromPackageJson)(cwd);
256
+ const shouldUseWorkspaces = await (0, config_1.checkWorkspacesEnabled)(cwd);
259
257
  if (shouldUseWorkspaces) {
260
258
  return cleanWorkspaces(cwd, verbose);
261
259
  }
@@ -23,11 +23,27 @@ const install_workspaces_1 = require("./install-workspaces");
23
23
  /**
24
24
  * Rewrite asset references from source paths to installation paths
25
25
  * Only rewrites the ../assets/ pattern - everything else is preserved
26
+ *
27
+ * @param content - The file content to rewrite
28
+ * @param presetName - The preset name if this file is from a preset
29
+ * @param fileInstallDepth - The depth of the file's installation directory relative to .cursor/
30
+ * For example: .cursor/commands/aicm/file.md has depth 2 (commands, aicm)
31
+ * .cursor/rules/aicm/preset/file.mdc has depth 3 (rules, aicm, preset)
26
32
  */
27
- function rewriteAssetReferences(content) {
28
- // Replace ../assets/ with ../../assets/aicm/
33
+ function rewriteAssetReferences(content, presetName, fileInstallDepth = 2) {
34
+ // Calculate the relative path from the file to .cursor/assets/aicm/
35
+ // We need to go up fileInstallDepth levels to reach .cursor/, then down to assets/aicm/
36
+ const upLevels = "../".repeat(fileInstallDepth);
37
+ // If this is from a preset, include the preset namespace in the asset path
38
+ let assetBasePath = "assets/aicm/";
39
+ if (presetName) {
40
+ const namespace = (0, config_1.extractNamespaceFromPresetPath)(presetName);
41
+ assetBasePath = node_path_1.default.posix.join("assets", "aicm", ...namespace) + "/";
42
+ }
43
+ const targetPath = upLevels + assetBasePath;
44
+ // Replace ../assets/ with the calculated target path
29
45
  // Handles both forward slashes and backslashes for cross-platform compatibility
30
- return content.replace(/\.\.[\\/]assets[\\/]/g, "../../assets/aicm/");
46
+ return content.replace(/\.\.[\\/]assets[\\/]/g, targetPath);
31
47
  }
32
48
  function getTargetPaths() {
33
49
  const projectDir = process.cwd();
@@ -54,8 +70,18 @@ function writeCursorRules(rules, cursorRulesDir) {
54
70
  }
55
71
  const ruleFile = rulePath + ".mdc";
56
72
  fs_extra_1.default.ensureDirSync(node_path_1.default.dirname(ruleFile));
73
+ // Calculate the depth for asset path rewriting
74
+ // cursorRulesDir is .cursor/rules/aicm (depth 2 from .cursor)
75
+ // Add namespace depth if present
76
+ let fileInstallDepth = 2; // rules, aicm
77
+ if (rule.presetName) {
78
+ const namespace = (0, config_1.extractNamespaceFromPresetPath)(rule.presetName);
79
+ fileInstallDepth += namespace.length;
80
+ }
81
+ // Add any subdirectories in the rule name
82
+ fileInstallDepth += ruleNameParts.length - 1; // -1 because the last part is the filename
57
83
  // Rewrite asset references before writing
58
- const content = rewriteAssetReferences(rule.content);
84
+ const content = rewriteAssetReferences(rule.content, rule.presetName, fileInstallDepth);
59
85
  fs_extra_1.default.writeFileSync(ruleFile, content);
60
86
  }
61
87
  }
@@ -69,8 +95,14 @@ function writeCursorCommands(commands, cursorCommandsDir) {
69
95
  const commandPath = node_path_1.default.join(cursorCommandsDir, ...commandNameParts);
70
96
  const commandFile = commandPath + ".md";
71
97
  fs_extra_1.default.ensureDirSync(node_path_1.default.dirname(commandFile));
98
+ // Calculate the depth for asset path rewriting
99
+ // cursorCommandsDir is .cursor/commands/aicm (depth 2 from .cursor)
100
+ // Commands are NOT namespaced by preset, but we still need to account for subdirectories
101
+ let fileInstallDepth = 2; // commands, aicm
102
+ // Add any subdirectories in the command name
103
+ fileInstallDepth += commandNameParts.length - 1; // -1 because the last part is the filename
72
104
  // Rewrite asset references before writing
73
- const content = rewriteAssetReferences(command.content);
105
+ const content = rewriteAssetReferences(command.content, command.presetName, fileInstallDepth);
74
106
  fs_extra_1.default.writeFileSync(commandFile, content);
75
107
  }
76
108
  }
@@ -92,8 +124,12 @@ function writeRulesForFile(rules, assets, ruleDir, rulesFile) {
92
124
  // For local rules, maintain the original flat structure
93
125
  rulePath = node_path_1.default.join(ruleDir, ...ruleNameParts);
94
126
  }
95
- // Rewrite asset references before writing
96
- const content = rewriteAssetReferences(rule.content);
127
+ // For windsurf/codex/claude, assets are installed at the same namespace level as rules
128
+ // Example: .aicm/my-preset/rule.md and .aicm/my-preset/asset.json
129
+ // So we need to remove the 'assets/' part from the path
130
+ // ../assets/file.json -> ../file.json
131
+ // ../../assets/file.json -> ../../file.json
132
+ const content = rule.content.replace(/(\.\.[/\\])assets[/\\]/g, "$1");
97
133
  const physicalRulePath = rulePath + ".md";
98
134
  fs_extra_1.default.ensureDirSync(node_path_1.default.dirname(physicalRulePath));
99
135
  fs_extra_1.default.writeFileSync(physicalRulePath, content);
@@ -87,5 +87,10 @@ export declare function loadAllRules(config: Config, cwd: string): Promise<{
87
87
  hookFiles: HookFile[];
88
88
  }>;
89
89
  export declare function loadConfigFile(searchFrom?: string): Promise<CosmiconfigResult>;
90
+ /**
91
+ * Check if workspaces mode is enabled without loading all rules/presets
92
+ * This is useful for commands that only need to know the workspace setting
93
+ */
94
+ export declare function checkWorkspacesEnabled(cwd?: string): Promise<boolean>;
90
95
  export declare function loadConfig(cwd?: string): Promise<ResolvedConfig | null>;
91
96
  export declare function saveConfig(config: Config, cwd?: string): boolean;
@@ -16,6 +16,7 @@ exports.resolvePresetPath = resolvePresetPath;
16
16
  exports.loadPreset = loadPreset;
17
17
  exports.loadAllRules = loadAllRules;
18
18
  exports.loadConfigFile = loadConfigFile;
19
+ exports.checkWorkspacesEnabled = checkWorkspacesEnabled;
19
20
  exports.loadConfig = loadConfig;
20
21
  exports.saveConfig = saveConfig;
21
22
  const fs_extra_1 = __importDefault(require("fs-extra"));
@@ -380,6 +381,18 @@ async function loadConfigFile(searchFrom) {
380
381
  throw new Error(`Failed to load configuration: ${error instanceof Error ? error.message : "Unknown error"}`);
381
382
  }
382
383
  }
384
+ /**
385
+ * Check if workspaces mode is enabled without loading all rules/presets
386
+ * This is useful for commands that only need to know the workspace setting
387
+ */
388
+ async function checkWorkspacesEnabled(cwd) {
389
+ const workingDir = cwd || process.cwd();
390
+ const configResult = await loadConfigFile(workingDir);
391
+ if (!(configResult === null || configResult === void 0 ? void 0 : configResult.config)) {
392
+ return detectWorkspacesFromPackageJson(workingDir);
393
+ }
394
+ return resolveWorkspaces(configResult.config, configResult.filepath, workingDir);
395
+ }
383
396
  async function loadConfig(cwd) {
384
397
  const workingDir = cwd || process.cwd();
385
398
  const configResult = await loadConfigFile(workingDir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aicm",
3
- "version": "0.19.0",
3
+ "version": "0.19.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",