rulesync 8.10.0 → 8.11.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/dist/index.cjs CHANGED
@@ -32,6 +32,7 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  ALL_FEATURES: () => ALL_FEATURES,
34
34
  ALL_TOOL_TARGETS: () => ALL_TOOL_TARGETS,
35
+ convertFromTool: () => convertFromTool2,
35
36
  generate: () => generate2,
36
37
  importFromTool: () => importFromTool2
37
38
  });
@@ -876,10 +877,6 @@ function getBaseDirsInLightOfGlobal({
876
877
  return resolvedBaseDirs;
877
878
  }
878
879
 
879
- // src/lib/generate.ts
880
- var import_node_path148 = require("path");
881
- var import_es_toolkit5 = require("es-toolkit");
882
-
883
880
  // src/features/commands/commands-processor.ts
884
881
  var import_node_path25 = require("path");
885
882
  var import_mini16 = require("zod/mini");
@@ -19134,9 +19131,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
19134
19131
  }
19135
19132
  toRulesyncRule() {
19136
19133
  let globs;
19137
- if (this.isRoot()) {
19138
- globs = ["**/*"];
19139
- } else if (this.frontmatter.applyTo) {
19134
+ if (this.frontmatter.applyTo) {
19140
19135
  globs = this.frontmatter.applyTo.split(",").map((g) => g.trim());
19141
19136
  }
19142
19137
  const rulesyncFrontmatter = {
@@ -22206,7 +22201,239 @@ ${toonContent}`;
22206
22201
  }
22207
22202
  };
22208
22203
 
22204
+ // src/lib/convert.ts
22205
+ async function convertFromTool(params) {
22206
+ const ctx = params;
22207
+ const [
22208
+ rulesCount,
22209
+ ignoreCount,
22210
+ mcpCount,
22211
+ commandsCount,
22212
+ subagentsCount,
22213
+ skillsCount,
22214
+ hooksCount,
22215
+ permissionsCount
22216
+ ] = [
22217
+ await runFeatureConvert(ctx, buildRulesStrategy(ctx)),
22218
+ await runFeatureConvert(ctx, buildIgnoreStrategy(ctx)),
22219
+ await runFeatureConvert(ctx, buildMcpStrategy(ctx)),
22220
+ await runFeatureConvert(ctx, buildCommandsStrategy(ctx)),
22221
+ await runFeatureConvert(ctx, buildSubagentsStrategy(ctx)),
22222
+ await runFeatureConvert(ctx, buildSkillsStrategy(ctx)),
22223
+ await runFeatureConvert(ctx, buildHooksStrategy(ctx)),
22224
+ await runFeatureConvert(ctx, buildPermissionsStrategy(ctx))
22225
+ ];
22226
+ return {
22227
+ rulesCount,
22228
+ ignoreCount,
22229
+ mcpCount,
22230
+ commandsCount,
22231
+ subagentsCount,
22232
+ skillsCount,
22233
+ hooksCount,
22234
+ permissionsCount
22235
+ };
22236
+ }
22237
+ async function runFeatureConvert(ctx, strategy) {
22238
+ if (!strategy) return 0;
22239
+ const { config, fromTool, toTools, logger } = ctx;
22240
+ const {
22241
+ feature,
22242
+ itemLabel,
22243
+ allTargets,
22244
+ importableTargets = allTargets,
22245
+ createProcessor,
22246
+ loadSource,
22247
+ toRulesync,
22248
+ fromRulesync,
22249
+ write
22250
+ } = strategy;
22251
+ if (!config.getFeatures(fromTool).includes(feature)) {
22252
+ return 0;
22253
+ }
22254
+ if (!allTargets.includes(fromTool)) {
22255
+ logger.warn(`Source tool '${fromTool}' does not support feature '${feature}'. Skipping.`);
22256
+ return 0;
22257
+ }
22258
+ if (!importableTargets.includes(fromTool)) {
22259
+ logger.warn(`Conversion from ${fromTool} ${feature} is not supported. Skipping.`);
22260
+ return 0;
22261
+ }
22262
+ const sourceProcessor = createProcessor({ toolTarget: fromTool, dryRun: false });
22263
+ const sourceItems = await loadSource(sourceProcessor);
22264
+ if (sourceItems.length === 0) {
22265
+ logger.warn(`No ${feature} files found for ${fromTool}. Skipping ${feature} conversion.`);
22266
+ return 0;
22267
+ }
22268
+ const rulesyncItems = await toRulesync(sourceProcessor, sourceItems);
22269
+ let totalCount = 0;
22270
+ for (const toTool of toTools) {
22271
+ if (!allTargets.includes(toTool)) {
22272
+ logger.warn(`Destination tool '${toTool}' does not support feature '${feature}'. Skipping.`);
22273
+ continue;
22274
+ }
22275
+ const destProcessor = createProcessor({
22276
+ toolTarget: toTool,
22277
+ dryRun: config.isPreviewMode()
22278
+ });
22279
+ const destItems = await fromRulesync(destProcessor, rulesyncItems);
22280
+ const { count } = await write(destProcessor, destItems);
22281
+ totalCount += count;
22282
+ if (config.getVerbose() && count > 0) {
22283
+ const verb = config.isPreviewMode() ? "Would convert" : "Converted";
22284
+ logger.success(`${verb} ${count} ${itemLabel} for ${toTool}`);
22285
+ }
22286
+ }
22287
+ return totalCount;
22288
+ }
22289
+ function getBaseDir(config) {
22290
+ return config.getBaseDirs()[0] ?? ".";
22291
+ }
22292
+ function buildRulesStrategy(ctx) {
22293
+ const { config, logger } = ctx;
22294
+ const global = config.getGlobal();
22295
+ const baseDir = getBaseDir(config);
22296
+ const allTargets = RulesProcessor.getToolTargets({ global });
22297
+ return {
22298
+ feature: "rules",
22299
+ itemLabel: "rule file(s)",
22300
+ allTargets,
22301
+ createProcessor: ({ toolTarget, dryRun }) => new RulesProcessor({ baseDir, toolTarget, global, dryRun, logger }),
22302
+ loadSource: (p) => p.loadToolFiles(),
22303
+ toRulesync: (p, files) => p.convertToolFilesToRulesyncFiles(files),
22304
+ fromRulesync: (p, files) => p.convertRulesyncFilesToToolFiles(files),
22305
+ write: (p, files) => p.writeAiFiles(files)
22306
+ };
22307
+ }
22308
+ function buildIgnoreStrategy(ctx) {
22309
+ const { config, logger } = ctx;
22310
+ if (config.getGlobal()) {
22311
+ logger.debug("Skipping ignore conversion (not supported in global mode)");
22312
+ return null;
22313
+ }
22314
+ const baseDir = getBaseDir(config);
22315
+ const allTargets = IgnoreProcessor.getToolTargets();
22316
+ return {
22317
+ feature: "ignore",
22318
+ itemLabel: "ignore file(s)",
22319
+ allTargets,
22320
+ createProcessor: ({ toolTarget, dryRun }) => new IgnoreProcessor({
22321
+ baseDir,
22322
+ toolTarget,
22323
+ dryRun,
22324
+ logger,
22325
+ featureOptions: config.getFeatureOptions(toolTarget, "ignore")
22326
+ }),
22327
+ loadSource: (p) => p.loadToolFiles(),
22328
+ toRulesync: (p, files) => p.convertToolFilesToRulesyncFiles(files),
22329
+ fromRulesync: (p, files) => p.convertRulesyncFilesToToolFiles(files),
22330
+ write: (p, files) => p.writeAiFiles(files)
22331
+ };
22332
+ }
22333
+ function buildMcpStrategy(ctx) {
22334
+ const { config, logger } = ctx;
22335
+ const global = config.getGlobal();
22336
+ const baseDir = getBaseDir(config);
22337
+ const allTargets = McpProcessor.getToolTargets({ global });
22338
+ return {
22339
+ feature: "mcp",
22340
+ itemLabel: "MCP file(s)",
22341
+ allTargets,
22342
+ createProcessor: ({ toolTarget, dryRun }) => new McpProcessor({ baseDir, toolTarget, global, dryRun, logger }),
22343
+ loadSource: (p) => p.loadToolFiles(),
22344
+ toRulesync: (p, files) => p.convertToolFilesToRulesyncFiles(files),
22345
+ fromRulesync: (p, files) => p.convertRulesyncFilesToToolFiles(files),
22346
+ write: (p, files) => p.writeAiFiles(files)
22347
+ };
22348
+ }
22349
+ function buildCommandsStrategy(ctx) {
22350
+ const { config, logger } = ctx;
22351
+ const global = config.getGlobal();
22352
+ const baseDir = getBaseDir(config);
22353
+ const allTargets = CommandsProcessor.getToolTargets({ global, includeSimulated: false });
22354
+ return {
22355
+ feature: "commands",
22356
+ itemLabel: "command file(s)",
22357
+ allTargets,
22358
+ createProcessor: ({ toolTarget, dryRun }) => new CommandsProcessor({ baseDir, toolTarget, global, dryRun, logger }),
22359
+ loadSource: (p) => p.loadToolFiles(),
22360
+ toRulesync: (p, files) => p.convertToolFilesToRulesyncFiles(files),
22361
+ fromRulesync: (p, files) => p.convertRulesyncFilesToToolFiles(files),
22362
+ write: (p, files) => p.writeAiFiles(files)
22363
+ };
22364
+ }
22365
+ function buildSubagentsStrategy(ctx) {
22366
+ const { config, logger } = ctx;
22367
+ const global = config.getGlobal();
22368
+ const baseDir = getBaseDir(config);
22369
+ const allTargets = SubagentsProcessor.getToolTargets({ global, includeSimulated: false });
22370
+ return {
22371
+ feature: "subagents",
22372
+ itemLabel: "subagent file(s)",
22373
+ allTargets,
22374
+ createProcessor: ({ toolTarget, dryRun }) => new SubagentsProcessor({ baseDir, toolTarget, global, dryRun, logger }),
22375
+ loadSource: (p) => p.loadToolFiles(),
22376
+ toRulesync: (p, files) => p.convertToolFilesToRulesyncFiles(files),
22377
+ fromRulesync: (p, files) => p.convertRulesyncFilesToToolFiles(files),
22378
+ write: (p, files) => p.writeAiFiles(files)
22379
+ };
22380
+ }
22381
+ function buildSkillsStrategy(ctx) {
22382
+ const { config, logger } = ctx;
22383
+ const global = config.getGlobal();
22384
+ const baseDir = getBaseDir(config);
22385
+ const allTargets = SkillsProcessor.getToolTargets({ global });
22386
+ return {
22387
+ feature: "skills",
22388
+ itemLabel: "skill(s)",
22389
+ allTargets,
22390
+ createProcessor: ({ toolTarget, dryRun }) => new SkillsProcessor({ baseDir, toolTarget, global, dryRun, logger }),
22391
+ loadSource: (p) => p.loadToolDirs(),
22392
+ toRulesync: (p, dirs) => p.convertToolDirsToRulesyncDirs(dirs),
22393
+ fromRulesync: (p, dirs) => p.convertRulesyncDirsToToolDirs(dirs),
22394
+ write: (p, dirs) => p.writeAiDirs(dirs)
22395
+ };
22396
+ }
22397
+ function buildHooksStrategy(ctx) {
22398
+ const { config, logger } = ctx;
22399
+ const global = config.getGlobal();
22400
+ const baseDir = getBaseDir(config);
22401
+ const allTargets = HooksProcessor.getToolTargets({ global });
22402
+ const importableTargets = HooksProcessor.getToolTargets({ global, importOnly: true });
22403
+ return {
22404
+ feature: "hooks",
22405
+ itemLabel: "hooks file(s)",
22406
+ allTargets,
22407
+ importableTargets,
22408
+ createProcessor: ({ toolTarget, dryRun }) => new HooksProcessor({ baseDir, toolTarget, global, dryRun, logger }),
22409
+ loadSource: (p) => p.loadToolFiles(),
22410
+ toRulesync: (p, files) => p.convertToolFilesToRulesyncFiles(files),
22411
+ fromRulesync: (p, files) => p.convertRulesyncFilesToToolFiles(files),
22412
+ write: (p, files) => p.writeAiFiles(files)
22413
+ };
22414
+ }
22415
+ function buildPermissionsStrategy(ctx) {
22416
+ const { config, logger } = ctx;
22417
+ const global = config.getGlobal();
22418
+ const baseDir = getBaseDir(config);
22419
+ const allTargets = PermissionsProcessor.getToolTargets({ global });
22420
+ const importableTargets = PermissionsProcessor.getToolTargets({ global, importOnly: true });
22421
+ return {
22422
+ feature: "permissions",
22423
+ itemLabel: "permissions file(s)",
22424
+ allTargets,
22425
+ importableTargets,
22426
+ createProcessor: ({ toolTarget, dryRun }) => new PermissionsProcessor({ baseDir, toolTarget, global, dryRun, logger }),
22427
+ loadSource: (p) => p.loadToolFiles(),
22428
+ toRulesync: (p, files) => p.convertToolFilesToRulesyncFiles(files),
22429
+ fromRulesync: (p, files) => p.convertRulesyncFilesToToolFiles(files),
22430
+ write: (p, files) => p.writeAiFiles(files)
22431
+ };
22432
+ }
22433
+
22209
22434
  // src/lib/generate.ts
22435
+ var import_node_path148 = require("path");
22436
+ var import_es_toolkit5 = require("es-toolkit");
22210
22437
  async function processFeatureGeneration(params) {
22211
22438
  const { config, processor, toolFiles } = params;
22212
22439
  let totalCount = 0;
@@ -22922,10 +23149,35 @@ async function importFromTool2(options) {
22922
23149
  });
22923
23150
  return importFromTool({ config, tool: target, logger });
22924
23151
  }
23152
+ async function convertFromTool2(options) {
23153
+ const { from, to, features, silent = true, verbose = false, ...rest } = options;
23154
+ if (!from) {
23155
+ throw new Error("from is required. Please specify a source tool to convert from.");
23156
+ }
23157
+ if (!to || to.length === 0) {
23158
+ throw new Error("to is required and must not be empty. Please specify destination tools.");
23159
+ }
23160
+ const toTools = Array.from(new Set(to));
23161
+ if (toTools.includes(from)) {
23162
+ throw new Error(
23163
+ `Destination tools must not include the source tool '${from}'. Converting a tool onto itself is likely a mistake and may cause lossy round-trips.`
23164
+ );
23165
+ }
23166
+ const logger = new ConsoleLogger({ verbose, silent });
23167
+ const config = await ConfigResolver.resolve({
23168
+ ...rest,
23169
+ targets: [from],
23170
+ features: features ?? ["*"],
23171
+ verbose,
23172
+ silent
23173
+ });
23174
+ return convertFromTool({ config, fromTool: from, toTools, logger });
23175
+ }
22925
23176
  // Annotate the CommonJS export names for ESM import in node:
22926
23177
  0 && (module.exports = {
22927
23178
  ALL_FEATURES,
22928
23179
  ALL_TOOL_TARGETS,
23180
+ convertFromTool,
22929
23181
  generate,
22930
23182
  importFromTool
22931
23183
  });
package/dist/index.d.cts CHANGED
@@ -47,6 +47,17 @@ declare const FeatureSchema: z.ZodMiniEnum<{
47
47
  }>;
48
48
  type Feature = z.infer<typeof FeatureSchema>;
49
49
 
50
+ type ConvertResult = {
51
+ rulesCount: number;
52
+ ignoreCount: number;
53
+ mcpCount: number;
54
+ commandsCount: number;
55
+ subagentsCount: number;
56
+ skillsCount: number;
57
+ hooksCount: number;
58
+ permissionsCount: number;
59
+ };
60
+
50
61
  type ValidationResult = {
51
62
  success: true;
52
63
  error: undefined | null;
@@ -309,7 +320,14 @@ type ImportOptions = BaseOptions & {
309
320
  target: ToolTarget;
310
321
  features?: Feature[];
311
322
  };
323
+ type ConvertOptions = BaseOptions & {
324
+ from: ToolTarget;
325
+ to: ToolTarget[];
326
+ features?: Feature[];
327
+ dryRun?: boolean;
328
+ };
312
329
  declare function generate(options?: GenerateOptions): Promise<GenerateResult>;
313
330
  declare function importFromTool(options: ImportOptions): Promise<ImportResult>;
331
+ declare function convertFromTool(options: ConvertOptions): Promise<ConvertResult>;
314
332
 
315
- export { ALL_FEATURES, ALL_TOOL_TARGETS, type Feature, type GenerateOptions, type GenerateResult, type ImportOptions, type ImportResult, type ToolTarget, generate, importFromTool };
333
+ export { ALL_FEATURES, ALL_TOOL_TARGETS, type ConvertOptions, type ConvertResult, type Feature, type GenerateOptions, type GenerateResult, type ImportOptions, type ImportResult, type ToolTarget, convertFromTool, generate, importFromTool };
package/dist/index.d.ts CHANGED
@@ -47,6 +47,17 @@ declare const FeatureSchema: z.ZodMiniEnum<{
47
47
  }>;
48
48
  type Feature = z.infer<typeof FeatureSchema>;
49
49
 
50
+ type ConvertResult = {
51
+ rulesCount: number;
52
+ ignoreCount: number;
53
+ mcpCount: number;
54
+ commandsCount: number;
55
+ subagentsCount: number;
56
+ skillsCount: number;
57
+ hooksCount: number;
58
+ permissionsCount: number;
59
+ };
60
+
50
61
  type ValidationResult = {
51
62
  success: true;
52
63
  error: undefined | null;
@@ -309,7 +320,14 @@ type ImportOptions = BaseOptions & {
309
320
  target: ToolTarget;
310
321
  features?: Feature[];
311
322
  };
323
+ type ConvertOptions = BaseOptions & {
324
+ from: ToolTarget;
325
+ to: ToolTarget[];
326
+ features?: Feature[];
327
+ dryRun?: boolean;
328
+ };
312
329
  declare function generate(options?: GenerateOptions): Promise<GenerateResult>;
313
330
  declare function importFromTool(options: ImportOptions): Promise<ImportResult>;
331
+ declare function convertFromTool(options: ConvertOptions): Promise<ConvertResult>;
314
332
 
315
- export { ALL_FEATURES, ALL_TOOL_TARGETS, type Feature, type GenerateOptions, type GenerateResult, type ImportOptions, type ImportResult, type ToolTarget, generate, importFromTool };
333
+ export { ALL_FEATURES, ALL_TOOL_TARGETS, type ConvertOptions, type ConvertResult, type Feature, type GenerateOptions, type GenerateResult, type ImportOptions, type ImportResult, type ToolTarget, convertFromTool, generate, importFromTool };
package/dist/index.js CHANGED
@@ -4,9 +4,10 @@ import {
4
4
  ConfigResolver,
5
5
  ConsoleLogger,
6
6
  checkRulesyncDirExists,
7
+ convertFromTool,
7
8
  generate,
8
9
  importFromTool
9
- } from "./chunk-RMITDFVW.js";
10
+ } from "./chunk-ZX2YPC22.js";
10
11
 
11
12
  // src/index.ts
12
13
  async function generate2(options = {}) {
@@ -36,9 +37,34 @@ async function importFromTool2(options) {
36
37
  });
37
38
  return importFromTool({ config, tool: target, logger });
38
39
  }
40
+ async function convertFromTool2(options) {
41
+ const { from, to, features, silent = true, verbose = false, ...rest } = options;
42
+ if (!from) {
43
+ throw new Error("from is required. Please specify a source tool to convert from.");
44
+ }
45
+ if (!to || to.length === 0) {
46
+ throw new Error("to is required and must not be empty. Please specify destination tools.");
47
+ }
48
+ const toTools = Array.from(new Set(to));
49
+ if (toTools.includes(from)) {
50
+ throw new Error(
51
+ `Destination tools must not include the source tool '${from}'. Converting a tool onto itself is likely a mistake and may cause lossy round-trips.`
52
+ );
53
+ }
54
+ const logger = new ConsoleLogger({ verbose, silent });
55
+ const config = await ConfigResolver.resolve({
56
+ ...rest,
57
+ targets: [from],
58
+ features: features ?? ["*"],
59
+ verbose,
60
+ silent
61
+ });
62
+ return convertFromTool({ config, fromTool: from, toTools, logger });
63
+ }
39
64
  export {
40
65
  ALL_FEATURES,
41
66
  ALL_TOOL_TARGETS,
67
+ convertFromTool2 as convertFromTool,
42
68
  generate2 as generate,
43
69
  importFromTool2 as importFromTool
44
70
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rulesync",
3
- "version": "8.10.0",
3
+ "version": "8.11.0",
4
4
  "description": "Unified AI rules management CLI tool that generates configuration files for various AI development tools",
5
5
  "keywords": [
6
6
  "ai",