rulesync 0.45.0 → 0.47.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
@@ -27,22 +27,23 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  ));
28
28
 
29
29
  // src/types/tool-targets.ts
30
- var import_v4_mini, ToolTargetSchema, ToolTargetsSchema, WildcardTargetSchema, RulesyncTargetsSchema;
30
+ var import_mini, ToolTargetSchema, ToolTargetsSchema, WildcardTargetSchema, RulesyncTargetsSchema;
31
31
  var init_tool_targets = __esm({
32
32
  "src/types/tool-targets.ts"() {
33
33
  "use strict";
34
- import_v4_mini = require("zod/v4-mini");
35
- ToolTargetSchema = import_v4_mini.z.enum([
34
+ import_mini = require("zod/mini");
35
+ ToolTargetSchema = import_mini.z.enum([
36
36
  "copilot",
37
37
  "cursor",
38
38
  "cline",
39
39
  "claudecode",
40
40
  "roo",
41
- "geminicli"
41
+ "geminicli",
42
+ "kiro"
42
43
  ]);
43
- ToolTargetsSchema = import_v4_mini.z.array(ToolTargetSchema);
44
- WildcardTargetSchema = import_v4_mini.z.tuple([import_v4_mini.z.literal("*")]);
45
- RulesyncTargetsSchema = import_v4_mini.z.union([ToolTargetsSchema, WildcardTargetSchema]);
44
+ ToolTargetsSchema = import_mini.z.array(ToolTargetSchema);
45
+ WildcardTargetSchema = import_mini.z.tuple([import_mini.z.literal("*")]);
46
+ RulesyncTargetsSchema = import_mini.z.union([ToolTargetsSchema, WildcardTargetSchema]);
46
47
  }
47
48
  });
48
49
 
@@ -294,6 +295,57 @@ var init_geminicli = __esm({
294
295
  }
295
296
  });
296
297
 
298
+ // src/generators/mcp/kiro.ts
299
+ function generateKiroMcp(config) {
300
+ const kiroConfig = {
301
+ mcpServers: {}
302
+ };
303
+ for (const [serverName, server] of Object.entries(config.mcpServers)) {
304
+ if (!shouldIncludeServer(server, "kiro")) continue;
305
+ const kiroServer = {};
306
+ if (server.command) {
307
+ kiroServer.command = server.command;
308
+ if (server.args) kiroServer.args = server.args;
309
+ } else if (server.url || server.httpUrl) {
310
+ const url = server.httpUrl || server.url;
311
+ if (url) {
312
+ kiroServer.url = url;
313
+ }
314
+ if (server.httpUrl || server.transport === "http") {
315
+ kiroServer.transport = "streamable-http";
316
+ } else if (server.transport === "sse" || server.type === "sse") {
317
+ kiroServer.transport = "sse";
318
+ }
319
+ }
320
+ if (server.env) {
321
+ kiroServer.env = server.env;
322
+ }
323
+ if (server.timeout) {
324
+ kiroServer.timeout = server.timeout;
325
+ }
326
+ if (server.disabled !== void 0) {
327
+ kiroServer.disabled = server.disabled;
328
+ }
329
+ if (server.transport) {
330
+ kiroServer.transport = server.transport;
331
+ }
332
+ if (server.kiroAutoApprove) {
333
+ kiroServer.autoApprove = server.kiroAutoApprove;
334
+ }
335
+ if (server.kiroAutoBlock) {
336
+ kiroServer.autoBlock = server.kiroAutoBlock;
337
+ }
338
+ kiroConfig.mcpServers[serverName] = kiroServer;
339
+ }
340
+ return JSON.stringify(kiroConfig, null, 2);
341
+ }
342
+ var init_kiro = __esm({
343
+ "src/generators/mcp/kiro.ts"() {
344
+ "use strict";
345
+ init_mcp_helpers();
346
+ }
347
+ });
348
+
297
349
  // src/generators/mcp/roo.ts
298
350
  function generateRooMcp(config) {
299
351
  const rooConfig = {
@@ -364,10 +416,11 @@ function getDefaultConfig() {
364
416
  cline: ".clinerules",
365
417
  claudecode: ".",
366
418
  roo: ".roo/rules",
367
- geminicli: ".gemini/memories"
419
+ geminicli: ".gemini/memories",
420
+ kiro: ".kiro/steering"
368
421
  },
369
422
  watchEnabled: false,
370
- defaultTargets: ["copilot", "cursor", "cline", "claudecode", "roo", "geminicli"]
423
+ defaultTargets: ["copilot", "cursor", "cline", "claudecode", "roo", "geminicli", "kiro"]
371
424
  };
372
425
  }
373
426
  function resolveTargets(targets, config) {
@@ -414,27 +467,138 @@ async function addCommand(filename) {
414
467
  }
415
468
  }
416
469
 
470
+ // src/generators/ignore/kiro.ts
471
+ var import_node_path = require("path");
472
+ async function generateKiroIgnoreFiles(rules, config, baseDir) {
473
+ const outputs = [];
474
+ const aiignoreContent = generateAiignoreContent(rules);
475
+ const outputPath = baseDir || process.cwd();
476
+ const filepath = (0, import_node_path.join)(outputPath, ".aiignore");
477
+ outputs.push({
478
+ tool: "kiro",
479
+ filepath,
480
+ content: aiignoreContent
481
+ });
482
+ return outputs;
483
+ }
484
+ function generateAiignoreContent(rules) {
485
+ const lines = [
486
+ "# Generated by rulesync - Kiro AI-specific exclusions",
487
+ "# This file excludes files that can be in Git but shouldn't be read by the AI",
488
+ ""
489
+ ];
490
+ lines.push(
491
+ "# Data files AI shouldn't process",
492
+ "*.csv",
493
+ "*.tsv",
494
+ "*.sqlite",
495
+ "*.db",
496
+ "",
497
+ "# Large binary files",
498
+ "*.zip",
499
+ "*.tar.gz",
500
+ "*.rar",
501
+ "",
502
+ "# Sensitive documentation",
503
+ "internal-docs/",
504
+ "confidential/",
505
+ "",
506
+ "# Test data that might confuse AI",
507
+ "test/fixtures/large-*.json",
508
+ "benchmark-results/",
509
+ "",
510
+ "# Reinforce critical exclusions from .gitignore",
511
+ "*.pem",
512
+ "*.key",
513
+ ".env*",
514
+ ""
515
+ );
516
+ const rulePatterns = extractIgnorePatternsFromRules(rules);
517
+ if (rulePatterns.length > 0) {
518
+ lines.push("# Project-specific exclusions from rulesync rules");
519
+ lines.push(...rulePatterns);
520
+ lines.push("");
521
+ }
522
+ return lines.join("\n");
523
+ }
524
+ function extractIgnorePatternsFromRules(rules) {
525
+ const patterns = [];
526
+ for (const rule of rules) {
527
+ if (rule.frontmatter.globs && rule.frontmatter.globs.length > 0) {
528
+ for (const glob of rule.frontmatter.globs) {
529
+ if (shouldExcludeFromAI(glob)) {
530
+ patterns.push(`# Exclude: ${rule.frontmatter.description}`);
531
+ patterns.push(glob);
532
+ }
533
+ }
534
+ }
535
+ const contentPatterns = extractIgnorePatternsFromContent(rule.content);
536
+ patterns.push(...contentPatterns);
537
+ }
538
+ return patterns;
539
+ }
540
+ function shouldExcludeFromAI(glob) {
541
+ const excludePatterns = [
542
+ // Test and fixture files that might be large or confusing
543
+ "**/test/fixtures/**",
544
+ "**/tests/fixtures/**",
545
+ "**/*.fixture.*",
546
+ // Build and generated files
547
+ "**/dist/**",
548
+ "**/build/**",
549
+ "**/coverage/**",
550
+ // Configuration that might contain sensitive data
551
+ "**/config/production/**",
552
+ "**/config/prod/**",
553
+ "**/*.prod.*",
554
+ // Documentation that might be sensitive
555
+ "**/internal/**",
556
+ "**/private/**",
557
+ "**/confidential/**"
558
+ ];
559
+ return excludePatterns.some((pattern) => {
560
+ const regex = new RegExp(pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*"));
561
+ return regex.test(glob);
562
+ });
563
+ }
564
+ function extractIgnorePatternsFromContent(content) {
565
+ const patterns = [];
566
+ const lines = content.split("\n");
567
+ for (const line of lines) {
568
+ const trimmed = line.trim();
569
+ if (trimmed.startsWith("# IGNORE:") || trimmed.startsWith("# aiignore:")) {
570
+ const pattern = trimmed.replace(/^# (IGNORE|aiignore):\s*/, "").trim();
571
+ if (pattern) {
572
+ patterns.push(pattern);
573
+ }
574
+ }
575
+ if (trimmed.includes("exclude") || trimmed.includes("ignore")) {
576
+ const matches = trimmed.match(/['"`]([^'"`]+\.(log|tmp|cache|temp))['"`]/g);
577
+ if (matches) {
578
+ patterns.push(...matches.map((m) => m.replace(/['"`]/g, "")));
579
+ }
580
+ }
581
+ }
582
+ return patterns;
583
+ }
584
+
417
585
  // src/generators/rules/claudecode.ts
418
586
  var import_node_path4 = require("path");
419
587
 
420
588
  // src/types/claudecode.ts
421
- var import_v4_mini2 = require("zod/v4-mini");
422
- var ClaudeSettingsSchema = import_v4_mini2.z.looseObject({
423
- permissions: import_v4_mini2.z._default(
424
- import_v4_mini2.z.looseObject({
425
- deny: import_v4_mini2.z._default(import_v4_mini2.z.array(import_v4_mini2.z.string()), [])
589
+ var import_mini2 = require("zod/mini");
590
+ var ClaudeSettingsSchema = import_mini2.z.looseObject({
591
+ permissions: import_mini2.z._default(
592
+ import_mini2.z.looseObject({
593
+ deny: import_mini2.z._default(import_mini2.z.array(import_mini2.z.string()), [])
426
594
  }),
427
595
  { deny: [] }
428
596
  )
429
597
  });
430
598
 
431
599
  // src/utils/file.ts
432
- var import_promises3 = require("fs/promises");
433
- var import_node_path3 = require("path");
434
-
435
- // src/utils/file-ops.ts
436
600
  var import_promises2 = require("fs/promises");
437
- var import_node_path = require("path");
601
+ var import_node_path2 = require("path");
438
602
  async function ensureDir(dirPath) {
439
603
  try {
440
604
  await (0, import_promises2.stat)(dirPath);
@@ -446,7 +610,7 @@ async function readFileContent(filepath) {
446
610
  return (0, import_promises2.readFile)(filepath, "utf-8");
447
611
  }
448
612
  async function writeFileContent(filepath, content) {
449
- await ensureDir((0, import_node_path.dirname)(filepath));
613
+ await ensureDir((0, import_node_path2.dirname)(filepath));
450
614
  await (0, import_promises2.writeFile)(filepath, content, "utf-8");
451
615
  }
452
616
  async function fileExists(filepath) {
@@ -457,16 +621,57 @@ async function fileExists(filepath) {
457
621
  return false;
458
622
  }
459
623
  }
624
+ async function findFiles(dir, extension = ".md") {
625
+ try {
626
+ const files = await (0, import_promises2.readdir)(dir);
627
+ return files.filter((file) => file.endsWith(extension)).map((file) => (0, import_node_path2.join)(dir, file));
628
+ } catch {
629
+ return [];
630
+ }
631
+ }
632
+ async function removeDirectory(dirPath) {
633
+ const dangerousPaths = [".", "/", "~", "src", "node_modules"];
634
+ if (dangerousPaths.includes(dirPath) || dirPath === "") {
635
+ console.warn(`Skipping deletion of dangerous path: ${dirPath}`);
636
+ return;
637
+ }
638
+ try {
639
+ if (await fileExists(dirPath)) {
640
+ await (0, import_promises2.rm)(dirPath, { recursive: true, force: true });
641
+ }
642
+ } catch (error) {
643
+ console.warn(`Failed to remove directory ${dirPath}:`, error);
644
+ }
645
+ }
646
+ async function removeFile(filepath) {
647
+ try {
648
+ if (await fileExists(filepath)) {
649
+ await (0, import_promises2.rm)(filepath);
650
+ }
651
+ } catch (error) {
652
+ console.warn(`Failed to remove file ${filepath}:`, error);
653
+ }
654
+ }
655
+ async function removeClaudeGeneratedFiles() {
656
+ const filesToRemove = ["CLAUDE.md", ".claude/memories"];
657
+ for (const fileOrDir of filesToRemove) {
658
+ if (fileOrDir.endsWith("/memories")) {
659
+ await removeDirectory(fileOrDir);
660
+ } else {
661
+ await removeFile(fileOrDir);
662
+ }
663
+ }
664
+ }
460
665
 
461
666
  // src/utils/ignore.ts
462
- var import_node_path2 = require("path");
667
+ var import_node_path3 = require("path");
463
668
  var import_micromatch = __toESM(require("micromatch"), 1);
464
669
  var cachedIgnorePatterns = null;
465
670
  async function loadIgnorePatterns(baseDir = process.cwd()) {
466
671
  if (cachedIgnorePatterns) {
467
672
  return cachedIgnorePatterns;
468
673
  }
469
- const ignorePath = (0, import_node_path2.join)(baseDir, ".rulesyncignore");
674
+ const ignorePath = (0, import_node_path3.join)(baseDir, ".rulesyncignore");
470
675
  if (!await fileExists(ignorePath)) {
471
676
  cachedIgnorePatterns = { patterns: [] };
472
677
  return cachedIgnorePatterns;
@@ -509,53 +714,6 @@ function filterIgnoredFiles(files, ignorePatterns) {
509
714
  return files.filter((file) => !isFileIgnored(file, ignorePatterns));
510
715
  }
511
716
 
512
- // src/utils/file.ts
513
- async function findFiles(dir, extension = ".md", ignorePatterns) {
514
- try {
515
- const files = await (0, import_promises3.readdir)(dir);
516
- const filtered = files.filter((file) => file.endsWith(extension)).map((file) => (0, import_node_path3.join)(dir, file));
517
- if (ignorePatterns && ignorePatterns.length > 0) {
518
- return filterIgnoredFiles(filtered, ignorePatterns);
519
- }
520
- return filtered;
521
- } catch {
522
- return [];
523
- }
524
- }
525
- async function removeDirectory(dirPath) {
526
- const dangerousPaths = [".", "/", "~", "src", "node_modules"];
527
- if (dangerousPaths.includes(dirPath) || dirPath === "") {
528
- console.warn(`Skipping deletion of dangerous path: ${dirPath}`);
529
- return;
530
- }
531
- try {
532
- if (await fileExists(dirPath)) {
533
- await (0, import_promises3.rm)(dirPath, { recursive: true, force: true });
534
- }
535
- } catch (error) {
536
- console.warn(`Failed to remove directory ${dirPath}:`, error);
537
- }
538
- }
539
- async function removeFile(filepath) {
540
- try {
541
- if (await fileExists(filepath)) {
542
- await (0, import_promises3.rm)(filepath);
543
- }
544
- } catch (error) {
545
- console.warn(`Failed to remove file ${filepath}:`, error);
546
- }
547
- }
548
- async function removeClaudeGeneratedFiles() {
549
- const filesToRemove = ["CLAUDE.md", ".claude/memories"];
550
- for (const fileOrDir of filesToRemove) {
551
- if (fileOrDir.endsWith("/memories")) {
552
- await removeDirectory(fileOrDir);
553
- } else {
554
- await removeFile(fileOrDir);
555
- }
556
- }
557
- }
558
-
559
717
  // src/generators/rules/claudecode.ts
560
718
  async function generateClaudecodeConfig(rules, config, baseDir) {
561
719
  const outputs = [];
@@ -892,14 +1050,34 @@ function generateAiexclude(patterns) {
892
1050
  return lines.join("\n");
893
1051
  }
894
1052
 
895
- // src/generators/rules/roo.ts
1053
+ // src/generators/rules/kiro.ts
896
1054
  var import_node_path9 = require("path");
1055
+ async function generateKiroConfig(rules, config, baseDir) {
1056
+ const outputs = [];
1057
+ for (const rule of rules) {
1058
+ const content = generateKiroMarkdown(rule);
1059
+ const outputDir = baseDir ? (0, import_node_path9.join)(baseDir, config.outputPaths.kiro) : config.outputPaths.kiro;
1060
+ const filepath = (0, import_node_path9.join)(outputDir, `${rule.filename}.md`);
1061
+ outputs.push({
1062
+ tool: "kiro",
1063
+ filepath,
1064
+ content
1065
+ });
1066
+ }
1067
+ return outputs;
1068
+ }
1069
+ function generateKiroMarkdown(rule) {
1070
+ return rule.content.trim();
1071
+ }
1072
+
1073
+ // src/generators/rules/roo.ts
1074
+ var import_node_path10 = require("path");
897
1075
  async function generateRooConfig(rules, config, baseDir) {
898
1076
  const outputs = [];
899
1077
  for (const rule of rules) {
900
1078
  const content = generateRooMarkdown(rule);
901
- const outputDir = baseDir ? (0, import_node_path9.join)(baseDir, config.outputPaths.roo) : config.outputPaths.roo;
902
- const filepath = (0, import_node_path9.join)(outputDir, `${rule.filename}.md`);
1079
+ const outputDir = baseDir ? (0, import_node_path10.join)(baseDir, config.outputPaths.roo) : config.outputPaths.roo;
1080
+ const filepath = (0, import_node_path10.join)(outputDir, `${rule.filename}.md`);
903
1081
  outputs.push({
904
1082
  tool: "roo",
905
1083
  filepath,
@@ -908,7 +1086,7 @@ async function generateRooConfig(rules, config, baseDir) {
908
1086
  }
909
1087
  const ignorePatterns = await loadIgnorePatterns(baseDir);
910
1088
  if (ignorePatterns.patterns.length > 0) {
911
- const rooIgnorePath = baseDir ? (0, import_node_path9.join)(baseDir, ".rooignore") : ".rooignore";
1089
+ const rooIgnorePath = baseDir ? (0, import_node_path10.join)(baseDir, ".rooignore") : ".rooignore";
912
1090
  const rooIgnoreContent = generateRooIgnore(ignorePatterns.patterns);
913
1091
  outputs.push({
914
1092
  tool: "roo",
@@ -974,6 +1152,11 @@ async function generateForTool(tool, rules, config, baseDir) {
974
1152
  return generateRooConfig(rules, config, baseDir);
975
1153
  case "geminicli":
976
1154
  return generateGeminiConfig(rules, config, baseDir);
1155
+ case "kiro": {
1156
+ const kiroRulesOutputs = await generateKiroConfig(rules, config, baseDir);
1157
+ const kiroIgnoreOutputs = await generateKiroIgnoreFiles(rules, config, baseDir);
1158
+ return [...kiroRulesOutputs, ...kiroIgnoreOutputs];
1159
+ }
977
1160
  default:
978
1161
  console.warn(`Unknown tool: ${tool}`);
979
1162
  return null;
@@ -981,74 +1164,76 @@ async function generateForTool(tool, rules, config, baseDir) {
981
1164
  }
982
1165
 
983
1166
  // src/core/parser.ts
984
- var import_node_path10 = require("path");
1167
+ var import_node_path11 = require("path");
985
1168
  var import_gray_matter = __toESM(require("gray-matter"), 1);
986
1169
 
987
1170
  // src/types/config.ts
988
- var import_v4_mini3 = require("zod/v4-mini");
1171
+ var import_mini3 = require("zod/mini");
989
1172
  init_tool_targets();
990
- var ConfigSchema = import_v4_mini3.z.object({
991
- aiRulesDir: import_v4_mini3.z.string(),
992
- outputPaths: import_v4_mini3.z.record(ToolTargetSchema, import_v4_mini3.z.string()),
993
- watchEnabled: import_v4_mini3.z.boolean(),
1173
+ var ConfigSchema = import_mini3.z.object({
1174
+ aiRulesDir: import_mini3.z.string(),
1175
+ outputPaths: import_mini3.z.record(ToolTargetSchema, import_mini3.z.string()),
1176
+ watchEnabled: import_mini3.z.boolean(),
994
1177
  defaultTargets: ToolTargetsSchema
995
1178
  });
996
1179
 
997
1180
  // src/types/mcp.ts
998
- var import_v4_mini4 = require("zod/v4-mini");
1181
+ var import_mini4 = require("zod/mini");
999
1182
  init_tool_targets();
1000
- var McpTransportTypeSchema = import_v4_mini4.z.enum(["stdio", "sse", "http"]);
1001
- var McpServerBaseSchema = import_v4_mini4.z.object({
1002
- command: import_v4_mini4.z.optional(import_v4_mini4.z.string()),
1003
- args: import_v4_mini4.z.optional(import_v4_mini4.z.array(import_v4_mini4.z.string())),
1004
- url: import_v4_mini4.z.optional(import_v4_mini4.z.string()),
1005
- httpUrl: import_v4_mini4.z.optional(import_v4_mini4.z.string()),
1006
- env: import_v4_mini4.z.optional(import_v4_mini4.z.record(import_v4_mini4.z.string(), import_v4_mini4.z.string())),
1007
- disabled: import_v4_mini4.z.optional(import_v4_mini4.z.boolean()),
1008
- networkTimeout: import_v4_mini4.z.optional(import_v4_mini4.z.number()),
1009
- timeout: import_v4_mini4.z.optional(import_v4_mini4.z.number()),
1010
- trust: import_v4_mini4.z.optional(import_v4_mini4.z.boolean()),
1011
- cwd: import_v4_mini4.z.optional(import_v4_mini4.z.string()),
1012
- transport: import_v4_mini4.z.optional(McpTransportTypeSchema),
1013
- type: import_v4_mini4.z.optional(import_v4_mini4.z.enum(["sse", "streamable-http"])),
1014
- alwaysAllow: import_v4_mini4.z.optional(import_v4_mini4.z.array(import_v4_mini4.z.string())),
1015
- tools: import_v4_mini4.z.optional(import_v4_mini4.z.array(import_v4_mini4.z.string()))
1183
+ var McpTransportTypeSchema = import_mini4.z.enum(["stdio", "sse", "http"]);
1184
+ var McpServerBaseSchema = import_mini4.z.object({
1185
+ command: import_mini4.z.optional(import_mini4.z.string()),
1186
+ args: import_mini4.z.optional(import_mini4.z.array(import_mini4.z.string())),
1187
+ url: import_mini4.z.optional(import_mini4.z.string()),
1188
+ httpUrl: import_mini4.z.optional(import_mini4.z.string()),
1189
+ env: import_mini4.z.optional(import_mini4.z.record(import_mini4.z.string(), import_mini4.z.string())),
1190
+ disabled: import_mini4.z.optional(import_mini4.z.boolean()),
1191
+ networkTimeout: import_mini4.z.optional(import_mini4.z.number()),
1192
+ timeout: import_mini4.z.optional(import_mini4.z.number()),
1193
+ trust: import_mini4.z.optional(import_mini4.z.boolean()),
1194
+ cwd: import_mini4.z.optional(import_mini4.z.string()),
1195
+ transport: import_mini4.z.optional(McpTransportTypeSchema),
1196
+ type: import_mini4.z.optional(import_mini4.z.enum(["sse", "streamable-http"])),
1197
+ alwaysAllow: import_mini4.z.optional(import_mini4.z.array(import_mini4.z.string())),
1198
+ tools: import_mini4.z.optional(import_mini4.z.array(import_mini4.z.string())),
1199
+ kiroAutoApprove: import_mini4.z.optional(import_mini4.z.array(import_mini4.z.string())),
1200
+ kiroAutoBlock: import_mini4.z.optional(import_mini4.z.array(import_mini4.z.string()))
1016
1201
  });
1017
- var RulesyncMcpServerSchema = import_v4_mini4.z.extend(McpServerBaseSchema, {
1018
- targets: import_v4_mini4.z.optional(RulesyncTargetsSchema)
1202
+ var RulesyncMcpServerSchema = import_mini4.z.extend(McpServerBaseSchema, {
1203
+ targets: import_mini4.z.optional(RulesyncTargetsSchema)
1019
1204
  });
1020
- var McpConfigSchema = import_v4_mini4.z.object({
1021
- mcpServers: import_v4_mini4.z.record(import_v4_mini4.z.string(), McpServerBaseSchema)
1205
+ var McpConfigSchema = import_mini4.z.object({
1206
+ mcpServers: import_mini4.z.record(import_mini4.z.string(), McpServerBaseSchema)
1022
1207
  });
1023
- var RulesyncMcpConfigSchema = import_v4_mini4.z.object({
1024
- mcpServers: import_v4_mini4.z.record(import_v4_mini4.z.string(), RulesyncMcpServerSchema)
1208
+ var RulesyncMcpConfigSchema = import_mini4.z.object({
1209
+ mcpServers: import_mini4.z.record(import_mini4.z.string(), RulesyncMcpServerSchema)
1025
1210
  });
1026
1211
 
1027
1212
  // src/types/rules.ts
1028
- var import_v4_mini5 = require("zod/v4-mini");
1213
+ var import_mini5 = require("zod/mini");
1029
1214
  init_tool_targets();
1030
- var RuleFrontmatterSchema = import_v4_mini5.z.object({
1031
- root: import_v4_mini5.z.boolean(),
1215
+ var RuleFrontmatterSchema = import_mini5.z.object({
1216
+ root: import_mini5.z.boolean(),
1032
1217
  targets: RulesyncTargetsSchema,
1033
- description: import_v4_mini5.z.string(),
1034
- globs: import_v4_mini5.z.array(import_v4_mini5.z.string()),
1035
- cursorRuleType: import_v4_mini5.z.optional(import_v4_mini5.z.enum(["always", "manual", "specificFiles", "intelligently"]))
1218
+ description: import_mini5.z.string(),
1219
+ globs: import_mini5.z.array(import_mini5.z.string()),
1220
+ cursorRuleType: import_mini5.z.optional(import_mini5.z.enum(["always", "manual", "specificFiles", "intelligently"]))
1036
1221
  });
1037
- var ParsedRuleSchema = import_v4_mini5.z.object({
1222
+ var ParsedRuleSchema = import_mini5.z.object({
1038
1223
  frontmatter: RuleFrontmatterSchema,
1039
- content: import_v4_mini5.z.string(),
1040
- filename: import_v4_mini5.z.string(),
1041
- filepath: import_v4_mini5.z.string()
1224
+ content: import_mini5.z.string(),
1225
+ filename: import_mini5.z.string(),
1226
+ filepath: import_mini5.z.string()
1042
1227
  });
1043
- var GeneratedOutputSchema = import_v4_mini5.z.object({
1228
+ var GeneratedOutputSchema = import_mini5.z.object({
1044
1229
  tool: ToolTargetSchema,
1045
- filepath: import_v4_mini5.z.string(),
1046
- content: import_v4_mini5.z.string()
1230
+ filepath: import_mini5.z.string(),
1231
+ content: import_mini5.z.string()
1047
1232
  });
1048
- var GenerateOptionsSchema = import_v4_mini5.z.object({
1049
- targetTools: import_v4_mini5.z.optional(ToolTargetsSchema),
1050
- outputDir: import_v4_mini5.z.optional(import_v4_mini5.z.string()),
1051
- watch: import_v4_mini5.z.optional(import_v4_mini5.z.boolean())
1233
+ var GenerateOptionsSchema = import_mini5.z.object({
1234
+ targetTools: import_mini5.z.optional(ToolTargetsSchema),
1235
+ outputDir: import_mini5.z.optional(import_mini5.z.string()),
1236
+ watch: import_mini5.z.optional(import_mini5.z.boolean())
1052
1237
  });
1053
1238
 
1054
1239
  // src/types/index.ts
@@ -1057,7 +1242,8 @@ init_tool_targets();
1057
1242
  // src/core/parser.ts
1058
1243
  async function parseRulesFromDirectory(aiRulesDir) {
1059
1244
  const ignorePatterns = await loadIgnorePatterns();
1060
- const ruleFiles = await findFiles(aiRulesDir, ".md", ignorePatterns.patterns);
1245
+ const allRuleFiles = await findFiles(aiRulesDir, ".md");
1246
+ const ruleFiles = filterIgnoredFiles(allRuleFiles, ignorePatterns.patterns);
1061
1247
  const rules = [];
1062
1248
  const errors = [];
1063
1249
  if (ignorePatterns.patterns.length > 0) {
@@ -1090,7 +1276,7 @@ async function parseRuleFile(filepath) {
1090
1276
  const parsed = (0, import_gray_matter.default)(content);
1091
1277
  try {
1092
1278
  const frontmatter = RuleFrontmatterSchema.parse(parsed.data);
1093
- const filename = (0, import_node_path10.basename)(filepath, ".md");
1279
+ const filename = (0, import_node_path11.basename)(filepath, ".md");
1094
1280
  return {
1095
1281
  frontmatter,
1096
1282
  content: parsed.content,
@@ -1163,6 +1349,7 @@ init_cline();
1163
1349
  init_copilot();
1164
1350
  init_cursor();
1165
1351
  init_geminicli();
1352
+ init_kiro();
1166
1353
  init_roo();
1167
1354
 
1168
1355
  // src/core/mcp-parser.ts
@@ -1226,6 +1413,11 @@ async function generateMcpConfigs(projectRoot, baseDir) {
1226
1413
  path: path3.join(targetRoot, ".gemini", "settings.json"),
1227
1414
  generate: () => generateGeminiCliMcp(config)
1228
1415
  },
1416
+ {
1417
+ tool: "kiro-project",
1418
+ path: path3.join(targetRoot, ".kiro", "mcp.json"),
1419
+ generate: () => generateKiroMcp(config)
1420
+ },
1229
1421
  {
1230
1422
  tool: "roo-project",
1231
1423
  path: path3.join(targetRoot, ".roo", "mcp.json"),
@@ -1236,7 +1428,7 @@ async function generateMcpConfigs(projectRoot, baseDir) {
1236
1428
  try {
1237
1429
  const content = generator.generate();
1238
1430
  const parsed = JSON.parse(content);
1239
- if (generator.tool.includes("claude") || generator.tool.includes("cline") || generator.tool.includes("cursor") || generator.tool.includes("gemini") || generator.tool.includes("roo")) {
1431
+ if (generator.tool.includes("claude") || generator.tool.includes("cline") || generator.tool.includes("cursor") || generator.tool.includes("gemini") || generator.tool.includes("kiro") || generator.tool.includes("roo")) {
1240
1432
  if (!parsed.mcpServers || Object.keys(parsed.mcpServers).length === 0) {
1241
1433
  results.push({
1242
1434
  tool: generator.tool,
@@ -1322,6 +1514,9 @@ async function generateCommand(options = {}) {
1322
1514
  case "geminicli":
1323
1515
  deleteTasks.push(removeDirectory(config.outputPaths.geminicli));
1324
1516
  break;
1517
+ case "kiro":
1518
+ deleteTasks.push(removeDirectory(config.outputPaths.kiro));
1519
+ break;
1325
1520
  }
1326
1521
  }
1327
1522
  await Promise.all(deleteTasks);
@@ -1386,9 +1581,9 @@ Generating configurations for base directory: ${baseDir}`);
1386
1581
 
1387
1582
  // src/cli/commands/gitignore.ts
1388
1583
  var import_node_fs = require("fs");
1389
- var import_node_path11 = require("path");
1584
+ var import_node_path12 = require("path");
1390
1585
  var gitignoreCommand = async () => {
1391
- const gitignorePath = (0, import_node_path11.join)(process.cwd(), ".gitignore");
1586
+ const gitignorePath = (0, import_node_path12.join)(process.cwd(), ".gitignore");
1392
1587
  const rulesFilesToIgnore = [
1393
1588
  "# Generated by rulesync - AI tool configuration files",
1394
1589
  "**/.github/copilot-instructions.md",
@@ -1405,6 +1600,8 @@ var gitignoreCommand = async () => {
1405
1600
  "**/GEMINI.md",
1406
1601
  "**/.gemini/memories/",
1407
1602
  "**/.aiexclude",
1603
+ "**/.aiignore",
1604
+ "**/.kiro/steering/",
1408
1605
  "**/.mcp.json",
1409
1606
  "!.rulesync/.mcp.json",
1410
1607
  "**/.cursor/mcp.json",
@@ -1442,17 +1639,17 @@ ${linesToAdd.join("\n")}
1442
1639
  };
1443
1640
 
1444
1641
  // src/core/importer.ts
1445
- var import_node_path18 = require("path");
1642
+ var import_node_path19 = require("path");
1446
1643
  var import_gray_matter4 = __toESM(require("gray-matter"), 1);
1447
1644
 
1448
1645
  // src/parsers/claudecode.ts
1449
- var import_node_path12 = require("path");
1646
+ var import_node_path13 = require("path");
1450
1647
  async function parseClaudeConfiguration(baseDir = process.cwd()) {
1451
1648
  const errors = [];
1452
1649
  const rules = [];
1453
1650
  let ignorePatterns;
1454
1651
  let mcpServers;
1455
- const claudeFilePath = (0, import_node_path12.join)(baseDir, "CLAUDE.md");
1652
+ const claudeFilePath = (0, import_node_path13.join)(baseDir, "CLAUDE.md");
1456
1653
  if (!await fileExists(claudeFilePath)) {
1457
1654
  errors.push("CLAUDE.md file not found");
1458
1655
  return { rules, errors };
@@ -1463,12 +1660,12 @@ async function parseClaudeConfiguration(baseDir = process.cwd()) {
1463
1660
  if (mainRule) {
1464
1661
  rules.push(mainRule);
1465
1662
  }
1466
- const memoryDir = (0, import_node_path12.join)(baseDir, ".claude", "memories");
1663
+ const memoryDir = (0, import_node_path13.join)(baseDir, ".claude", "memories");
1467
1664
  if (await fileExists(memoryDir)) {
1468
1665
  const memoryRules = await parseClaudeMemoryFiles(memoryDir);
1469
1666
  rules.push(...memoryRules);
1470
1667
  }
1471
- const settingsPath = (0, import_node_path12.join)(baseDir, ".claude", "settings.json");
1668
+ const settingsPath = (0, import_node_path13.join)(baseDir, ".claude", "settings.json");
1472
1669
  if (await fileExists(settingsPath)) {
1473
1670
  const settingsResult = await parseClaudeSettings(settingsPath);
1474
1671
  if (settingsResult.ignorePatterns) {
@@ -1525,10 +1722,10 @@ async function parseClaudeMemoryFiles(memoryDir) {
1525
1722
  const files = await readdir2(memoryDir);
1526
1723
  for (const file of files) {
1527
1724
  if (file.endsWith(".md")) {
1528
- const filePath = (0, import_node_path12.join)(memoryDir, file);
1725
+ const filePath = (0, import_node_path13.join)(memoryDir, file);
1529
1726
  const content = await readFileContent(filePath);
1530
1727
  if (content.trim()) {
1531
- const filename = (0, import_node_path12.basename)(file, ".md");
1728
+ const filename = (0, import_node_path13.basename)(file, ".md");
1532
1729
  const frontmatter = {
1533
1730
  root: false,
1534
1731
  targets: ["claudecode"],
@@ -1588,11 +1785,11 @@ async function parseClaudeSettings(settingsPath) {
1588
1785
  }
1589
1786
 
1590
1787
  // src/parsers/cline.ts
1591
- var import_node_path13 = require("path");
1788
+ var import_node_path14 = require("path");
1592
1789
  async function parseClineConfiguration(baseDir = process.cwd()) {
1593
1790
  const errors = [];
1594
1791
  const rules = [];
1595
- const clineFilePath = (0, import_node_path13.join)(baseDir, ".cline", "instructions.md");
1792
+ const clineFilePath = (0, import_node_path14.join)(baseDir, ".cline", "instructions.md");
1596
1793
  if (await fileExists(clineFilePath)) {
1597
1794
  try {
1598
1795
  const content = await readFileContent(clineFilePath);
@@ -1615,14 +1812,14 @@ async function parseClineConfiguration(baseDir = process.cwd()) {
1615
1812
  errors.push(`Failed to parse .cline/instructions.md: ${errorMessage}`);
1616
1813
  }
1617
1814
  }
1618
- const clinerulesDirPath = (0, import_node_path13.join)(baseDir, ".clinerules");
1815
+ const clinerulesDirPath = (0, import_node_path14.join)(baseDir, ".clinerules");
1619
1816
  if (await fileExists(clinerulesDirPath)) {
1620
1817
  try {
1621
1818
  const { readdir: readdir2 } = await import("fs/promises");
1622
1819
  const files = await readdir2(clinerulesDirPath);
1623
1820
  for (const file of files) {
1624
1821
  if (file.endsWith(".md")) {
1625
- const filePath = (0, import_node_path13.join)(clinerulesDirPath, file);
1822
+ const filePath = (0, import_node_path14.join)(clinerulesDirPath, file);
1626
1823
  try {
1627
1824
  const content = await readFileContent(filePath);
1628
1825
  if (content.trim()) {
@@ -1658,12 +1855,12 @@ async function parseClineConfiguration(baseDir = process.cwd()) {
1658
1855
  }
1659
1856
 
1660
1857
  // src/parsers/copilot.ts
1661
- var import_node_path14 = require("path");
1858
+ var import_node_path15 = require("path");
1662
1859
  var import_gray_matter2 = __toESM(require("gray-matter"), 1);
1663
1860
  async function parseCopilotConfiguration(baseDir = process.cwd()) {
1664
1861
  const errors = [];
1665
1862
  const rules = [];
1666
- const copilotFilePath = (0, import_node_path14.join)(baseDir, ".github", "copilot-instructions.md");
1863
+ const copilotFilePath = (0, import_node_path15.join)(baseDir, ".github", "copilot-instructions.md");
1667
1864
  if (await fileExists(copilotFilePath)) {
1668
1865
  try {
1669
1866
  const rawContent = await readFileContent(copilotFilePath);
@@ -1688,19 +1885,19 @@ async function parseCopilotConfiguration(baseDir = process.cwd()) {
1688
1885
  errors.push(`Failed to parse copilot-instructions.md: ${errorMessage}`);
1689
1886
  }
1690
1887
  }
1691
- const instructionsDir = (0, import_node_path14.join)(baseDir, ".github", "instructions");
1888
+ const instructionsDir = (0, import_node_path15.join)(baseDir, ".github", "instructions");
1692
1889
  if (await fileExists(instructionsDir)) {
1693
1890
  try {
1694
1891
  const { readdir: readdir2 } = await import("fs/promises");
1695
1892
  const files = await readdir2(instructionsDir);
1696
1893
  for (const file of files) {
1697
1894
  if (file.endsWith(".instructions.md")) {
1698
- const filePath = (0, import_node_path14.join)(instructionsDir, file);
1895
+ const filePath = (0, import_node_path15.join)(instructionsDir, file);
1699
1896
  const rawContent = await readFileContent(filePath);
1700
1897
  const parsed = (0, import_gray_matter2.default)(rawContent);
1701
1898
  const content = parsed.content.trim();
1702
1899
  if (content) {
1703
- const filename = (0, import_node_path14.basename)(file, ".instructions.md");
1900
+ const filename = (0, import_node_path15.basename)(file, ".instructions.md");
1704
1901
  const frontmatter = {
1705
1902
  root: false,
1706
1903
  targets: ["copilot"],
@@ -1730,10 +1927,10 @@ async function parseCopilotConfiguration(baseDir = process.cwd()) {
1730
1927
  }
1731
1928
 
1732
1929
  // src/parsers/cursor.ts
1733
- var import_node_path15 = require("path");
1930
+ var import_node_path16 = require("path");
1734
1931
  var import_gray_matter3 = __toESM(require("gray-matter"), 1);
1735
1932
  var import_js_yaml = require("js-yaml");
1736
- var import_v4_mini6 = require("zod/v4-mini");
1933
+ var import_mini6 = require("zod/mini");
1737
1934
  var customMatterOptions = {
1738
1935
  engines: {
1739
1936
  yaml: {
@@ -1761,7 +1958,7 @@ var customMatterOptions = {
1761
1958
  }
1762
1959
  };
1763
1960
  function convertCursorMdcFrontmatter(cursorFrontmatter, _filename) {
1764
- const FrontmatterSchema = import_v4_mini6.z.record(import_v4_mini6.z.string(), import_v4_mini6.z.unknown());
1961
+ const FrontmatterSchema = import_mini6.z.record(import_mini6.z.string(), import_mini6.z.unknown());
1765
1962
  const parseResult = FrontmatterSchema.safeParse(cursorFrontmatter);
1766
1963
  if (!parseResult.success) {
1767
1964
  return {
@@ -1855,7 +2052,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1855
2052
  const rules = [];
1856
2053
  let ignorePatterns;
1857
2054
  let mcpServers;
1858
- const cursorFilePath = (0, import_node_path15.join)(baseDir, ".cursorrules");
2055
+ const cursorFilePath = (0, import_node_path16.join)(baseDir, ".cursorrules");
1859
2056
  if (await fileExists(cursorFilePath)) {
1860
2057
  try {
1861
2058
  const rawContent = await readFileContent(cursorFilePath);
@@ -1876,20 +2073,20 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1876
2073
  errors.push(`Failed to parse .cursorrules file: ${errorMessage}`);
1877
2074
  }
1878
2075
  }
1879
- const cursorRulesDir = (0, import_node_path15.join)(baseDir, ".cursor", "rules");
2076
+ const cursorRulesDir = (0, import_node_path16.join)(baseDir, ".cursor", "rules");
1880
2077
  if (await fileExists(cursorRulesDir)) {
1881
2078
  try {
1882
2079
  const { readdir: readdir2 } = await import("fs/promises");
1883
2080
  const files = await readdir2(cursorRulesDir);
1884
2081
  for (const file of files) {
1885
2082
  if (file.endsWith(".mdc")) {
1886
- const filePath = (0, import_node_path15.join)(cursorRulesDir, file);
2083
+ const filePath = (0, import_node_path16.join)(cursorRulesDir, file);
1887
2084
  try {
1888
2085
  const rawContent = await readFileContent(filePath);
1889
2086
  const parsed = (0, import_gray_matter3.default)(rawContent, customMatterOptions);
1890
2087
  const content = parsed.content.trim();
1891
2088
  if (content) {
1892
- const filename = (0, import_node_path15.basename)(file, ".mdc");
2089
+ const filename = (0, import_node_path16.basename)(file, ".mdc");
1893
2090
  const frontmatter = convertCursorMdcFrontmatter(parsed.data, filename);
1894
2091
  rules.push({
1895
2092
  frontmatter,
@@ -1912,7 +2109,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1912
2109
  if (rules.length === 0) {
1913
2110
  errors.push("No Cursor configuration files found (.cursorrules or .cursor/rules/*.mdc)");
1914
2111
  }
1915
- const cursorIgnorePath = (0, import_node_path15.join)(baseDir, ".cursorignore");
2112
+ const cursorIgnorePath = (0, import_node_path16.join)(baseDir, ".cursorignore");
1916
2113
  if (await fileExists(cursorIgnorePath)) {
1917
2114
  try {
1918
2115
  const content = await readFileContent(cursorIgnorePath);
@@ -1925,7 +2122,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1925
2122
  errors.push(`Failed to parse .cursorignore: ${errorMessage}`);
1926
2123
  }
1927
2124
  }
1928
- const cursorMcpPath = (0, import_node_path15.join)(baseDir, ".cursor", "mcp.json");
2125
+ const cursorMcpPath = (0, import_node_path16.join)(baseDir, ".cursor", "mcp.json");
1929
2126
  if (await fileExists(cursorMcpPath)) {
1930
2127
  try {
1931
2128
  const content = await readFileContent(cursorMcpPath);
@@ -1948,13 +2145,13 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1948
2145
  }
1949
2146
 
1950
2147
  // src/parsers/geminicli.ts
1951
- var import_node_path16 = require("path");
2148
+ var import_node_path17 = require("path");
1952
2149
  async function parseGeminiConfiguration(baseDir = process.cwd()) {
1953
2150
  const errors = [];
1954
2151
  const rules = [];
1955
2152
  let ignorePatterns;
1956
2153
  let mcpServers;
1957
- const geminiFilePath = (0, import_node_path16.join)(baseDir, "GEMINI.md");
2154
+ const geminiFilePath = (0, import_node_path17.join)(baseDir, "GEMINI.md");
1958
2155
  if (!await fileExists(geminiFilePath)) {
1959
2156
  errors.push("GEMINI.md file not found");
1960
2157
  return { rules, errors };
@@ -1965,12 +2162,12 @@ async function parseGeminiConfiguration(baseDir = process.cwd()) {
1965
2162
  if (mainRule) {
1966
2163
  rules.push(mainRule);
1967
2164
  }
1968
- const memoryDir = (0, import_node_path16.join)(baseDir, ".gemini", "memories");
2165
+ const memoryDir = (0, import_node_path17.join)(baseDir, ".gemini", "memories");
1969
2166
  if (await fileExists(memoryDir)) {
1970
2167
  const memoryRules = await parseGeminiMemoryFiles(memoryDir);
1971
2168
  rules.push(...memoryRules);
1972
2169
  }
1973
- const settingsPath = (0, import_node_path16.join)(baseDir, ".gemini", "settings.json");
2170
+ const settingsPath = (0, import_node_path17.join)(baseDir, ".gemini", "settings.json");
1974
2171
  if (await fileExists(settingsPath)) {
1975
2172
  const settingsResult = await parseGeminiSettings(settingsPath);
1976
2173
  if (settingsResult.ignorePatterns) {
@@ -1981,7 +2178,7 @@ async function parseGeminiConfiguration(baseDir = process.cwd()) {
1981
2178
  }
1982
2179
  errors.push(...settingsResult.errors);
1983
2180
  }
1984
- const aiexcludePath = (0, import_node_path16.join)(baseDir, ".aiexclude");
2181
+ const aiexcludePath = (0, import_node_path17.join)(baseDir, ".aiexclude");
1985
2182
  if (await fileExists(aiexcludePath)) {
1986
2183
  const aiexcludePatterns = await parseAiexclude(aiexcludePath);
1987
2184
  if (aiexcludePatterns.length > 0) {
@@ -2034,10 +2231,10 @@ async function parseGeminiMemoryFiles(memoryDir) {
2034
2231
  const files = await readdir2(memoryDir);
2035
2232
  for (const file of files) {
2036
2233
  if (file.endsWith(".md")) {
2037
- const filePath = (0, import_node_path16.join)(memoryDir, file);
2234
+ const filePath = (0, import_node_path17.join)(memoryDir, file);
2038
2235
  const content = await readFileContent(filePath);
2039
2236
  if (content.trim()) {
2040
- const filename = (0, import_node_path16.basename)(file, ".md");
2237
+ const filename = (0, import_node_path17.basename)(file, ".md");
2041
2238
  const frontmatter = {
2042
2239
  root: false,
2043
2240
  targets: ["geminicli"],
@@ -2087,11 +2284,11 @@ async function parseAiexclude(aiexcludePath) {
2087
2284
  }
2088
2285
 
2089
2286
  // src/parsers/roo.ts
2090
- var import_node_path17 = require("path");
2287
+ var import_node_path18 = require("path");
2091
2288
  async function parseRooConfiguration(baseDir = process.cwd()) {
2092
2289
  const errors = [];
2093
2290
  const rules = [];
2094
- const rooFilePath = (0, import_node_path17.join)(baseDir, ".roo", "instructions.md");
2291
+ const rooFilePath = (0, import_node_path18.join)(baseDir, ".roo", "instructions.md");
2095
2292
  if (await fileExists(rooFilePath)) {
2096
2293
  try {
2097
2294
  const content = await readFileContent(rooFilePath);
@@ -2114,14 +2311,14 @@ async function parseRooConfiguration(baseDir = process.cwd()) {
2114
2311
  errors.push(`Failed to parse .roo/instructions.md: ${errorMessage}`);
2115
2312
  }
2116
2313
  }
2117
- const rooRulesDir = (0, import_node_path17.join)(baseDir, ".roo", "rules");
2314
+ const rooRulesDir = (0, import_node_path18.join)(baseDir, ".roo", "rules");
2118
2315
  if (await fileExists(rooRulesDir)) {
2119
2316
  try {
2120
2317
  const { readdir: readdir2 } = await import("fs/promises");
2121
2318
  const files = await readdir2(rooRulesDir);
2122
2319
  for (const file of files) {
2123
2320
  if (file.endsWith(".md")) {
2124
- const filePath = (0, import_node_path17.join)(rooRulesDir, file);
2321
+ const filePath = (0, import_node_path18.join)(rooRulesDir, file);
2125
2322
  try {
2126
2323
  const content = await readFileContent(filePath);
2127
2324
  if (content.trim()) {
@@ -2222,7 +2419,7 @@ async function importConfiguration(options) {
2222
2419
  if (rules.length === 0 && !ignorePatterns && !mcpServers) {
2223
2420
  return { success: false, rulesCreated: 0, errors };
2224
2421
  }
2225
- const rulesDirPath = (0, import_node_path18.join)(baseDir, rulesDir);
2422
+ const rulesDirPath = (0, import_node_path19.join)(baseDir, rulesDir);
2226
2423
  try {
2227
2424
  const { mkdir: mkdir3 } = await import("fs/promises");
2228
2425
  await mkdir3(rulesDirPath, { recursive: true });
@@ -2236,7 +2433,7 @@ async function importConfiguration(options) {
2236
2433
  try {
2237
2434
  const baseFilename = `${tool}__${rule.filename}`;
2238
2435
  const filename = await generateUniqueFilename(rulesDirPath, baseFilename);
2239
- const filePath = (0, import_node_path18.join)(rulesDirPath, `${filename}.md`);
2436
+ const filePath = (0, import_node_path19.join)(rulesDirPath, `${filename}.md`);
2240
2437
  const content = generateRuleFileContent(rule);
2241
2438
  await writeFileContent(filePath, content);
2242
2439
  rulesCreated++;
@@ -2251,7 +2448,7 @@ async function importConfiguration(options) {
2251
2448
  let ignoreFileCreated = false;
2252
2449
  if (ignorePatterns && ignorePatterns.length > 0) {
2253
2450
  try {
2254
- const rulesyncignorePath = (0, import_node_path18.join)(baseDir, ".rulesyncignore");
2451
+ const rulesyncignorePath = (0, import_node_path19.join)(baseDir, ".rulesyncignore");
2255
2452
  const ignoreContent = `${ignorePatterns.join("\n")}
2256
2453
  `;
2257
2454
  await writeFileContent(rulesyncignorePath, ignoreContent);
@@ -2267,7 +2464,7 @@ async function importConfiguration(options) {
2267
2464
  let mcpFileCreated = false;
2268
2465
  if (mcpServers && Object.keys(mcpServers).length > 0) {
2269
2466
  try {
2270
- const mcpPath = (0, import_node_path18.join)(baseDir, rulesDir, ".mcp.json");
2467
+ const mcpPath = (0, import_node_path19.join)(baseDir, rulesDir, ".mcp.json");
2271
2468
  const mcpContent = `${JSON.stringify({ mcpServers }, null, 2)}
2272
2469
  `;
2273
2470
  await writeFileContent(mcpPath, mcpContent);
@@ -2281,7 +2478,7 @@ async function importConfiguration(options) {
2281
2478
  }
2282
2479
  }
2283
2480
  return {
2284
- success: rulesCreated > 0 || ignoreFileCreated || mcpFileCreated,
2481
+ success: errors.length === 0 && (rulesCreated > 0 || ignoreFileCreated || mcpFileCreated),
2285
2482
  rulesCreated,
2286
2483
  errors,
2287
2484
  ignoreFileCreated,
@@ -2295,7 +2492,7 @@ function generateRuleFileContent(rule) {
2295
2492
  async function generateUniqueFilename(rulesDir, baseFilename) {
2296
2493
  let filename = baseFilename;
2297
2494
  let counter = 1;
2298
- while (await fileExists((0, import_node_path18.join)(rulesDir, `${filename}.md`))) {
2495
+ while (await fileExists((0, import_node_path19.join)(rulesDir, `${filename}.md`))) {
2299
2496
  filename = `${baseFilename}-${counter}`;
2300
2497
  counter++;
2301
2498
  }
@@ -2360,7 +2557,7 @@ async function importCommand(options = {}) {
2360
2557
  }
2361
2558
 
2362
2559
  // src/cli/commands/init.ts
2363
- var import_node_path19 = require("path");
2560
+ var import_node_path20 = require("path");
2364
2561
  async function initCommand() {
2365
2562
  const aiRulesDir = ".rulesync";
2366
2563
  console.log("Initializing rulesync...");
@@ -2407,7 +2604,7 @@ globs: ["**/*"]
2407
2604
  - Follow single responsibility principle
2408
2605
  `
2409
2606
  };
2410
- const filepath = (0, import_node_path19.join)(aiRulesDir, sampleFile.filename);
2607
+ const filepath = (0, import_node_path20.join)(aiRulesDir, sampleFile.filename);
2411
2608
  if (!await fileExists(filepath)) {
2412
2609
  await writeFileContent(filepath, sampleFile.content);
2413
2610
  console.log(`Created ${filepath}`);
@@ -2551,12 +2748,12 @@ async function watchCommand() {
2551
2748
 
2552
2749
  // src/cli/index.ts
2553
2750
  var program = new import_commander.Command();
2554
- program.name("rulesync").description("Unified AI rules management CLI tool").version("0.45.0");
2751
+ program.name("rulesync").description("Unified AI rules management CLI tool").version("0.47.0");
2555
2752
  program.command("init").description("Initialize rulesync in current directory").action(initCommand);
2556
2753
  program.command("add <filename>").description("Add a new rule file").action(addCommand);
2557
2754
  program.command("gitignore").description("Add generated files to .gitignore").action(gitignoreCommand);
2558
2755
  program.command("import").description("Import configurations from AI tools to rulesync format").option("--claudecode", "Import from Claude Code (CLAUDE.md)").option("--cursor", "Import from Cursor (.cursorrules)").option("--copilot", "Import from GitHub Copilot (.github/copilot-instructions.md)").option("--cline", "Import from Cline (.cline/instructions.md)").option("--roo", "Import from Roo Code (.roo/instructions.md)").option("--geminicli", "Import from Gemini CLI (GEMINI.md)").option("-v, --verbose", "Verbose output").action(importCommand);
2559
- program.command("generate").description("Generate configuration files for AI tools").option("--copilot", "Generate only for GitHub Copilot").option("--cursor", "Generate only for Cursor").option("--cline", "Generate only for Cline").option("--claudecode", "Generate only for Claude Code").option("--roo", "Generate only for Roo Code").option("--geminicli", "Generate only for Gemini CLI").option("--delete", "Delete all existing files in output directories before generating").option(
2756
+ program.command("generate").description("Generate configuration files for AI tools").option("--copilot", "Generate only for GitHub Copilot").option("--cursor", "Generate only for Cursor").option("--cline", "Generate only for Cline").option("--claudecode", "Generate only for Claude Code").option("--roo", "Generate only for Roo Code").option("--geminicli", "Generate only for Gemini CLI").option("--kiro", "Generate only for Kiro IDE").option("--delete", "Delete all existing files in output directories before generating").option(
2560
2757
  "-b, --base-dir <paths>",
2561
2758
  "Base directories to generate files (comma-separated for multiple paths)"
2562
2759
  ).option("-v, --verbose", "Verbose output").action(async (options) => {
@@ -2567,6 +2764,7 @@ program.command("generate").description("Generate configuration files for AI too
2567
2764
  if (options.claudecode) tools.push("claudecode");
2568
2765
  if (options.roo) tools.push("roo");
2569
2766
  if (options.geminicli) tools.push("geminicli");
2767
+ if (options.kiro) tools.push("kiro");
2570
2768
  const generateOptions = {
2571
2769
  verbose: options.verbose,
2572
2770
  delete: options.delete