rulesync 7.3.0 → 7.5.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.
@@ -605,7 +605,7 @@ import { intersection } from "es-toolkit";
605
605
  import { join as join109 } from "path";
606
606
 
607
607
  // src/features/commands/commands-processor.ts
608
- import { basename as basename16, join as join19 } from "path";
608
+ import { basename as basename2, join as join19, relative as relative3 } from "path";
609
609
  import { z as z12 } from "zod/mini";
610
610
 
611
611
  // src/types/feature-processor.ts
@@ -671,7 +671,7 @@ var FeatureProcessor = class {
671
671
  };
672
672
 
673
673
  // src/features/commands/agentsmd-command.ts
674
- import { basename as basename2, join as join5 } from "path";
674
+ import { join as join5 } from "path";
675
675
 
676
676
  // src/utils/frontmatter.ts
677
677
  import matter from "gray-matter";
@@ -724,7 +724,7 @@ function parseFrontmatter(content) {
724
724
  }
725
725
 
726
726
  // src/features/commands/simulated-command.ts
727
- import { basename, join as join4 } from "path";
727
+ import { join as join4 } from "path";
728
728
  import { z as z4 } from "zod/mini";
729
729
 
730
730
  // src/types/ai-file.ts
@@ -972,7 +972,7 @@ var SimulatedCommand = class _SimulatedCommand extends ToolCommand {
972
972
  return {
973
973
  baseDir,
974
974
  relativeDirPath: _SimulatedCommand.getSettablePaths().relativeDirPath,
975
- relativeFilePath: basename(relativeFilePath),
975
+ relativeFilePath,
976
976
  frontmatter: result.data,
977
977
  body: content.trim(),
978
978
  validate
@@ -1029,7 +1029,7 @@ var AgentsmdCommand = class _AgentsmdCommand extends SimulatedCommand {
1029
1029
  return new _AgentsmdCommand({
1030
1030
  baseDir,
1031
1031
  relativeDirPath: _AgentsmdCommand.getSettablePaths().relativeDirPath,
1032
- relativeFilePath: basename2(relativeFilePath),
1032
+ relativeFilePath,
1033
1033
  frontmatter: result.data,
1034
1034
  body: content.trim(),
1035
1035
  validate
@@ -1053,7 +1053,7 @@ var AgentsmdCommand = class _AgentsmdCommand extends SimulatedCommand {
1053
1053
  };
1054
1054
 
1055
1055
  // src/features/commands/antigravity-command.ts
1056
- import { basename as basename4, join as join7 } from "path";
1056
+ import { basename, join as join7 } from "path";
1057
1057
  import { z as z6 } from "zod/mini";
1058
1058
 
1059
1059
  // src/utils/type-guards.ts
@@ -1062,7 +1062,7 @@ function isRecord(value) {
1062
1062
  }
1063
1063
 
1064
1064
  // src/features/commands/rulesync-command.ts
1065
- import { basename as basename3, join as join6 } from "path";
1065
+ import { join as join6 } from "path";
1066
1066
  import { z as z5 } from "zod/mini";
1067
1067
 
1068
1068
  // src/types/rulesync-file.ts
@@ -1106,6 +1106,16 @@ var RulesyncCommand = class _RulesyncCommand extends RulesyncFile {
1106
1106
  getBody() {
1107
1107
  return this.body;
1108
1108
  }
1109
+ withRelativeFilePath(newRelativeFilePath) {
1110
+ return new _RulesyncCommand({
1111
+ baseDir: this.getBaseDir(),
1112
+ relativeDirPath: this.getRelativeDirPath(),
1113
+ relativeFilePath: newRelativeFilePath,
1114
+ frontmatter: this.getFrontmatter(),
1115
+ body: this.getBody(),
1116
+ fileContent: this.getFileContent()
1117
+ });
1118
+ }
1109
1119
  validate() {
1110
1120
  if (!this.frontmatter) {
1111
1121
  return { success: true, error: null };
@@ -1136,11 +1146,10 @@ var RulesyncCommand = class _RulesyncCommand extends RulesyncFile {
1136
1146
  if (!result.success) {
1137
1147
  throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${formatError(result.error)}`);
1138
1148
  }
1139
- const filename = basename3(relativeFilePath);
1140
1149
  return new _RulesyncCommand({
1141
1150
  baseDir: process.cwd(),
1142
1151
  relativeDirPath: _RulesyncCommand.getSettablePaths().relativeDirPath,
1143
- relativeFilePath: filename,
1152
+ relativeFilePath,
1144
1153
  frontmatter: result.data,
1145
1154
  body: content.trim(),
1146
1155
  fileContent
@@ -1255,7 +1264,7 @@ ${body}${turboDirective}`;
1255
1264
  const antigravityTrigger = antigravityConfig && typeof antigravityConfig.trigger === "string" ? antigravityConfig.trigger : void 0;
1256
1265
  const rootTrigger = typeof rulesyncFrontmatter.trigger === "string" ? rulesyncFrontmatter.trigger : void 0;
1257
1266
  const bodyTriggerMatch = rulesyncCommand.getBody().match(/trigger:\s*(\/[\w-]+)/);
1258
- const filenameTrigger = `/${basename4(rulesyncCommand.getRelativeFilePath(), ".md")}`;
1267
+ const filenameTrigger = `/${basename(rulesyncCommand.getRelativeFilePath(), ".md")}`;
1259
1268
  return antigravityTrigger || rootTrigger || (bodyTriggerMatch ? bodyTriggerMatch[1] : void 0) || filenameTrigger;
1260
1269
  }
1261
1270
  validate() {
@@ -1299,7 +1308,7 @@ ${body}${turboDirective}`;
1299
1308
  return new _AntigravityCommand({
1300
1309
  baseDir,
1301
1310
  relativeDirPath: _AntigravityCommand.getSettablePaths().relativeDirPath,
1302
- relativeFilePath: basename4(relativeFilePath),
1311
+ relativeFilePath,
1303
1312
  frontmatter: result.data,
1304
1313
  body: content.trim(),
1305
1314
  fileContent,
@@ -1324,7 +1333,7 @@ ${body}${turboDirective}`;
1324
1333
  };
1325
1334
 
1326
1335
  // src/features/commands/claudecode-command.ts
1327
- import { basename as basename5, join as join8 } from "path";
1336
+ import { join as join8 } from "path";
1328
1337
  import { z as z7 } from "zod/mini";
1329
1338
  var ClaudecodeCommandFrontmatterSchema = z7.looseObject({
1330
1339
  description: z7.string(),
@@ -1445,7 +1454,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
1445
1454
  return new _ClaudecodeCommand({
1446
1455
  baseDir,
1447
1456
  relativeDirPath: paths.relativeDirPath,
1448
- relativeFilePath: basename5(relativeFilePath),
1457
+ relativeFilePath,
1449
1458
  frontmatter: result.data,
1450
1459
  body: content.trim(),
1451
1460
  validate
@@ -1468,7 +1477,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
1468
1477
  };
1469
1478
 
1470
1479
  // src/features/commands/cline-command.ts
1471
- import { basename as basename6, join as join9 } from "path";
1480
+ import { join as join9 } from "path";
1472
1481
  var ClineCommand = class _ClineCommand extends ToolCommand {
1473
1482
  static getSettablePaths({ global } = {}) {
1474
1483
  if (global) {
@@ -1535,7 +1544,7 @@ var ClineCommand = class _ClineCommand extends ToolCommand {
1535
1544
  return new _ClineCommand({
1536
1545
  baseDir,
1537
1546
  relativeDirPath: paths.relativeDirPath,
1538
- relativeFilePath: basename6(relativeFilePath),
1547
+ relativeFilePath,
1539
1548
  fileContent: content.trim(),
1540
1549
  validate
1541
1550
  });
@@ -1556,7 +1565,7 @@ var ClineCommand = class _ClineCommand extends ToolCommand {
1556
1565
  };
1557
1566
 
1558
1567
  // src/features/commands/codexcli-command.ts
1559
- import { basename as basename7, join as join10 } from "path";
1568
+ import { join as join10 } from "path";
1560
1569
  var CodexcliCommand = class _CodexcliCommand extends ToolCommand {
1561
1570
  static getSettablePaths({ global } = {}) {
1562
1571
  if (!global) {
@@ -1622,7 +1631,7 @@ var CodexcliCommand = class _CodexcliCommand extends ToolCommand {
1622
1631
  return new _CodexcliCommand({
1623
1632
  baseDir,
1624
1633
  relativeDirPath: paths.relativeDirPath,
1625
- relativeFilePath: basename7(relativeFilePath),
1634
+ relativeFilePath,
1626
1635
  fileContent: content.trim(),
1627
1636
  validate
1628
1637
  });
@@ -1643,7 +1652,7 @@ var CodexcliCommand = class _CodexcliCommand extends ToolCommand {
1643
1652
  };
1644
1653
 
1645
1654
  // src/features/commands/copilot-command.ts
1646
- import { basename as basename8, join as join11 } from "path";
1655
+ import { join as join11 } from "path";
1647
1656
  import { z as z8 } from "zod/mini";
1648
1657
  var CopilotCommandFrontmatterSchema = z8.looseObject({
1649
1658
  mode: z8.optional(z8.string()),
@@ -1755,7 +1764,7 @@ var CopilotCommand = class _CopilotCommand extends ToolCommand {
1755
1764
  return new _CopilotCommand({
1756
1765
  baseDir,
1757
1766
  relativeDirPath: paths.relativeDirPath,
1758
- relativeFilePath: basename8(relativeFilePath),
1767
+ relativeFilePath,
1759
1768
  frontmatter: result.data,
1760
1769
  body: content.trim(),
1761
1770
  validate
@@ -1784,7 +1793,7 @@ var CopilotCommand = class _CopilotCommand extends ToolCommand {
1784
1793
  };
1785
1794
 
1786
1795
  // src/features/commands/cursor-command.ts
1787
- import { basename as basename9, join as join12 } from "path";
1796
+ import { join as join12 } from "path";
1788
1797
  var CursorCommand = class _CursorCommand extends ToolCommand {
1789
1798
  static getSettablePaths(_options = {}) {
1790
1799
  return {
@@ -1847,7 +1856,7 @@ var CursorCommand = class _CursorCommand extends ToolCommand {
1847
1856
  return new _CursorCommand({
1848
1857
  baseDir,
1849
1858
  relativeDirPath: paths.relativeDirPath,
1850
- relativeFilePath: basename9(relativeFilePath),
1859
+ relativeFilePath,
1851
1860
  fileContent: content.trim(),
1852
1861
  validate
1853
1862
  });
@@ -1868,7 +1877,7 @@ var CursorCommand = class _CursorCommand extends ToolCommand {
1868
1877
  };
1869
1878
 
1870
1879
  // src/features/commands/factorydroid-command.ts
1871
- import { basename as basename10, join as join13 } from "path";
1880
+ import { join as join13 } from "path";
1872
1881
  var FactorydroidCommand = class _FactorydroidCommand extends SimulatedCommand {
1873
1882
  static getSettablePaths(_options) {
1874
1883
  return {
@@ -1902,7 +1911,7 @@ var FactorydroidCommand = class _FactorydroidCommand extends SimulatedCommand {
1902
1911
  return new _FactorydroidCommand({
1903
1912
  baseDir,
1904
1913
  relativeDirPath: paths.relativeDirPath,
1905
- relativeFilePath: basename10(relativeFilePath),
1914
+ relativeFilePath,
1906
1915
  frontmatter: result.data,
1907
1916
  body: content.trim(),
1908
1917
  validate
@@ -1926,7 +1935,7 @@ var FactorydroidCommand = class _FactorydroidCommand extends SimulatedCommand {
1926
1935
  };
1927
1936
 
1928
1937
  // src/features/commands/geminicli-command.ts
1929
- import { basename as basename11, join as join14 } from "path";
1938
+ import { join as join14 } from "path";
1930
1939
  import { parse as parseToml } from "smol-toml";
1931
1940
  import { z as z9 } from "zod/mini";
1932
1941
  var GeminiCliCommandFrontmatterSchema = z9.looseObject({
@@ -2034,7 +2043,7 @@ ${geminiFrontmatter.prompt}
2034
2043
  return new _GeminiCliCommand({
2035
2044
  baseDir,
2036
2045
  relativeDirPath: paths.relativeDirPath,
2037
- relativeFilePath: basename11(relativeFilePath),
2046
+ relativeFilePath,
2038
2047
  fileContent,
2039
2048
  validate
2040
2049
  });
@@ -2071,7 +2080,7 @@ prompt = ""`;
2071
2080
  };
2072
2081
 
2073
2082
  // src/features/commands/kilo-command.ts
2074
- import { basename as basename12, join as join15 } from "path";
2083
+ import { join as join15 } from "path";
2075
2084
  var KiloCommand = class _KiloCommand extends ToolCommand {
2076
2085
  static getSettablePaths(_options = {}) {
2077
2086
  return {
@@ -2131,7 +2140,7 @@ var KiloCommand = class _KiloCommand extends ToolCommand {
2131
2140
  return new _KiloCommand({
2132
2141
  baseDir,
2133
2142
  relativeDirPath: paths.relativeDirPath,
2134
- relativeFilePath: basename12(relativeFilePath),
2143
+ relativeFilePath,
2135
2144
  fileContent: content.trim(),
2136
2145
  validate
2137
2146
  });
@@ -2152,7 +2161,7 @@ var KiloCommand = class _KiloCommand extends ToolCommand {
2152
2161
  };
2153
2162
 
2154
2163
  // src/features/commands/kiro-command.ts
2155
- import { basename as basename13, join as join16 } from "path";
2164
+ import { join as join16 } from "path";
2156
2165
  var KiroCommand = class _KiroCommand extends ToolCommand {
2157
2166
  static getSettablePaths(_options = {}) {
2158
2167
  return {
@@ -2212,7 +2221,7 @@ var KiroCommand = class _KiroCommand extends ToolCommand {
2212
2221
  return new _KiroCommand({
2213
2222
  baseDir,
2214
2223
  relativeDirPath: paths.relativeDirPath,
2215
- relativeFilePath: basename13(relativeFilePath),
2224
+ relativeFilePath,
2216
2225
  fileContent: content.trim(),
2217
2226
  validate
2218
2227
  });
@@ -2233,7 +2242,7 @@ var KiroCommand = class _KiroCommand extends ToolCommand {
2233
2242
  };
2234
2243
 
2235
2244
  // src/features/commands/opencode-command.ts
2236
- import { basename as basename14, join as join17 } from "path";
2245
+ import { join as join17 } from "path";
2237
2246
  import { optional as optional2, z as z10 } from "zod/mini";
2238
2247
  var OpenCodeCommandFrontmatterSchema = z10.looseObject({
2239
2248
  description: z10.string(),
@@ -2344,7 +2353,7 @@ var OpenCodeCommand = class _OpenCodeCommand extends ToolCommand {
2344
2353
  return new _OpenCodeCommand({
2345
2354
  baseDir,
2346
2355
  relativeDirPath: paths.relativeDirPath,
2347
- relativeFilePath: basename14(relativeFilePath),
2356
+ relativeFilePath,
2348
2357
  frontmatter: result.data,
2349
2358
  body: content.trim(),
2350
2359
  validate
@@ -2373,7 +2382,7 @@ var OpenCodeCommand = class _OpenCodeCommand extends ToolCommand {
2373
2382
  };
2374
2383
 
2375
2384
  // src/features/commands/roo-command.ts
2376
- import { basename as basename15, join as join18 } from "path";
2385
+ import { join as join18 } from "path";
2377
2386
  import { optional as optional3, z as z11 } from "zod/mini";
2378
2387
  var RooCommandFrontmatterSchema = z11.looseObject({
2379
2388
  description: z11.string(),
@@ -2489,7 +2498,7 @@ var RooCommand = class _RooCommand extends ToolCommand {
2489
2498
  return new _RooCommand({
2490
2499
  baseDir,
2491
2500
  relativeDirPath: _RooCommand.getSettablePaths().relativeDirPath,
2492
- relativeFilePath: basename15(relativeFilePath),
2501
+ relativeFilePath,
2493
2502
  frontmatter: result.data,
2494
2503
  body: content.trim(),
2495
2504
  fileContent,
@@ -2536,42 +2545,78 @@ var toolCommandFactories = /* @__PURE__ */ new Map([
2536
2545
  "agentsmd",
2537
2546
  {
2538
2547
  class: AgentsmdCommand,
2539
- meta: { extension: "md", supportsProject: true, supportsGlobal: false, isSimulated: true }
2548
+ meta: {
2549
+ extension: "md",
2550
+ supportsProject: true,
2551
+ supportsGlobal: false,
2552
+ isSimulated: true,
2553
+ supportsSubdirectory: false
2554
+ }
2540
2555
  }
2541
2556
  ],
2542
2557
  [
2543
2558
  "antigravity",
2544
2559
  {
2545
2560
  class: AntigravityCommand,
2546
- meta: { extension: "md", supportsProject: true, supportsGlobal: false, isSimulated: false }
2561
+ meta: {
2562
+ extension: "md",
2563
+ supportsProject: true,
2564
+ supportsGlobal: false,
2565
+ isSimulated: false,
2566
+ supportsSubdirectory: false
2567
+ }
2547
2568
  }
2548
2569
  ],
2549
2570
  [
2550
2571
  "claudecode",
2551
2572
  {
2552
2573
  class: ClaudecodeCommand,
2553
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2574
+ meta: {
2575
+ extension: "md",
2576
+ supportsProject: true,
2577
+ supportsGlobal: true,
2578
+ isSimulated: false,
2579
+ supportsSubdirectory: true
2580
+ }
2554
2581
  }
2555
2582
  ],
2556
2583
  [
2557
2584
  "claudecode-legacy",
2558
2585
  {
2559
2586
  class: ClaudecodeCommand,
2560
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2587
+ meta: {
2588
+ extension: "md",
2589
+ supportsProject: true,
2590
+ supportsGlobal: true,
2591
+ isSimulated: false,
2592
+ supportsSubdirectory: true
2593
+ }
2561
2594
  }
2562
2595
  ],
2563
2596
  [
2564
2597
  "cline",
2565
2598
  {
2566
2599
  class: ClineCommand,
2567
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2600
+ meta: {
2601
+ extension: "md",
2602
+ supportsProject: true,
2603
+ supportsGlobal: true,
2604
+ isSimulated: false,
2605
+ supportsSubdirectory: false
2606
+ }
2568
2607
  }
2569
2608
  ],
2570
2609
  [
2571
2610
  "codexcli",
2572
2611
  {
2573
2612
  class: CodexcliCommand,
2574
- meta: { extension: "md", supportsProject: false, supportsGlobal: true, isSimulated: false }
2613
+ meta: {
2614
+ extension: "md",
2615
+ supportsProject: false,
2616
+ supportsGlobal: true,
2617
+ isSimulated: false,
2618
+ supportsSubdirectory: false
2619
+ }
2575
2620
  }
2576
2621
  ],
2577
2622
  [
@@ -2582,7 +2627,8 @@ var toolCommandFactories = /* @__PURE__ */ new Map([
2582
2627
  extension: "prompt.md",
2583
2628
  supportsProject: true,
2584
2629
  supportsGlobal: false,
2585
- isSimulated: false
2630
+ isSimulated: false,
2631
+ supportsSubdirectory: false
2586
2632
  }
2587
2633
  }
2588
2634
  ],
@@ -2590,49 +2636,91 @@ var toolCommandFactories = /* @__PURE__ */ new Map([
2590
2636
  "cursor",
2591
2637
  {
2592
2638
  class: CursorCommand,
2593
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2639
+ meta: {
2640
+ extension: "md",
2641
+ supportsProject: true,
2642
+ supportsGlobal: true,
2643
+ isSimulated: false,
2644
+ supportsSubdirectory: false
2645
+ }
2594
2646
  }
2595
2647
  ],
2596
2648
  [
2597
2649
  "factorydroid",
2598
2650
  {
2599
2651
  class: FactorydroidCommand,
2600
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: true }
2652
+ meta: {
2653
+ extension: "md",
2654
+ supportsProject: true,
2655
+ supportsGlobal: true,
2656
+ isSimulated: true,
2657
+ supportsSubdirectory: false
2658
+ }
2601
2659
  }
2602
2660
  ],
2603
2661
  [
2604
2662
  "geminicli",
2605
2663
  {
2606
2664
  class: GeminiCliCommand,
2607
- meta: { extension: "toml", supportsProject: true, supportsGlobal: true, isSimulated: false }
2665
+ meta: {
2666
+ extension: "toml",
2667
+ supportsProject: true,
2668
+ supportsGlobal: true,
2669
+ isSimulated: false,
2670
+ supportsSubdirectory: true
2671
+ }
2608
2672
  }
2609
2673
  ],
2610
2674
  [
2611
2675
  "kilo",
2612
2676
  {
2613
2677
  class: KiloCommand,
2614
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2678
+ meta: {
2679
+ extension: "md",
2680
+ supportsProject: true,
2681
+ supportsGlobal: true,
2682
+ isSimulated: false,
2683
+ supportsSubdirectory: false
2684
+ }
2615
2685
  }
2616
2686
  ],
2617
2687
  [
2618
2688
  "kiro",
2619
2689
  {
2620
2690
  class: KiroCommand,
2621
- meta: { extension: "md", supportsProject: true, supportsGlobal: false, isSimulated: false }
2691
+ meta: {
2692
+ extension: "md",
2693
+ supportsProject: true,
2694
+ supportsGlobal: false,
2695
+ isSimulated: false,
2696
+ supportsSubdirectory: false
2697
+ }
2622
2698
  }
2623
2699
  ],
2624
2700
  [
2625
2701
  "opencode",
2626
2702
  {
2627
2703
  class: OpenCodeCommand,
2628
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2704
+ meta: {
2705
+ extension: "md",
2706
+ supportsProject: true,
2707
+ supportsGlobal: true,
2708
+ isSimulated: false,
2709
+ supportsSubdirectory: true
2710
+ }
2629
2711
  }
2630
2712
  ],
2631
2713
  [
2632
2714
  "roo",
2633
2715
  {
2634
2716
  class: RooCommand,
2635
- meta: { extension: "md", supportsProject: true, supportsGlobal: false, isSimulated: false }
2717
+ meta: {
2718
+ extension: "md",
2719
+ supportsProject: true,
2720
+ supportsGlobal: false,
2721
+ isSimulated: false,
2722
+ supportsSubdirectory: true
2723
+ }
2636
2724
  }
2637
2725
  ]
2638
2726
  ]);
@@ -2685,13 +2773,27 @@ var CommandsProcessor = class extends FeatureProcessor {
2685
2773
  (file) => file instanceof RulesyncCommand
2686
2774
  );
2687
2775
  const factory = this.getFactory(this.toolTarget);
2776
+ const flattenedPathOrigins = /* @__PURE__ */ new Map();
2688
2777
  const toolCommands = rulesyncCommands.map((rulesyncCommand) => {
2689
2778
  if (!factory.class.isTargetedByRulesyncCommand(rulesyncCommand)) {
2690
2779
  return null;
2691
2780
  }
2781
+ const originalRelativePath = rulesyncCommand.getRelativeFilePath();
2782
+ const commandToConvert = factory.meta.supportsSubdirectory ? rulesyncCommand : this.flattenRelativeFilePath(rulesyncCommand);
2783
+ if (!factory.meta.supportsSubdirectory) {
2784
+ const flattenedPath = commandToConvert.getRelativeFilePath();
2785
+ const firstOrigin = flattenedPathOrigins.get(flattenedPath);
2786
+ if (firstOrigin && firstOrigin !== originalRelativePath) {
2787
+ logger.warn(
2788
+ `Command path collision detected while flattening for ${this.toolTarget}: "${firstOrigin}" and "${originalRelativePath}" both map to "${flattenedPath}". The later command will overwrite the earlier one.`
2789
+ );
2790
+ } else if (!firstOrigin) {
2791
+ flattenedPathOrigins.set(flattenedPath, originalRelativePath);
2792
+ }
2793
+ }
2692
2794
  return factory.class.fromRulesyncCommand({
2693
2795
  baseDir: this.baseDir,
2694
- rulesyncCommand,
2796
+ rulesyncCommand: commandToConvert,
2695
2797
  global: this.global
2696
2798
  });
2697
2799
  }).filter((command) => command !== null);
@@ -2706,17 +2808,26 @@ var CommandsProcessor = class extends FeatureProcessor {
2706
2808
  });
2707
2809
  return rulesyncCommands;
2708
2810
  }
2811
+ flattenRelativeFilePath(rulesyncCommand) {
2812
+ const flatPath = basename2(rulesyncCommand.getRelativeFilePath());
2813
+ if (flatPath === rulesyncCommand.getRelativeFilePath()) return rulesyncCommand;
2814
+ return rulesyncCommand.withRelativeFilePath(flatPath);
2815
+ }
2816
+ safeRelativePath(basePath, fullPath) {
2817
+ const rel = relative3(basePath, fullPath);
2818
+ checkPathTraversal({ relativePath: rel, intendedRootDir: basePath });
2819
+ return rel;
2820
+ }
2709
2821
  /**
2710
2822
  * Implementation of abstract method from FeatureProcessor
2711
2823
  * Load and parse rulesync command files from .rulesync/commands/ directory
2712
2824
  */
2713
2825
  async loadRulesyncFiles() {
2714
- const rulesyncCommandPaths = await findFilesByGlobs(
2715
- join19(RulesyncCommand.getSettablePaths().relativeDirPath, "*.md")
2716
- );
2826
+ const basePath = RulesyncCommand.getSettablePaths().relativeDirPath;
2827
+ const rulesyncCommandPaths = await findFilesByGlobs(join19(basePath, "**", "*.md"));
2717
2828
  const rulesyncCommands = await Promise.all(
2718
2829
  rulesyncCommandPaths.map(
2719
- (path3) => RulesyncCommand.fromFile({ relativeFilePath: basename16(path3) })
2830
+ (path3) => RulesyncCommand.fromFile({ relativeFilePath: this.safeRelativePath(basePath, path3) })
2720
2831
  )
2721
2832
  );
2722
2833
  logger.debug(`Successfully loaded ${rulesyncCommands.length} rulesync commands`);
@@ -2731,15 +2842,15 @@ var CommandsProcessor = class extends FeatureProcessor {
2731
2842
  } = {}) {
2732
2843
  const factory = this.getFactory(this.toolTarget);
2733
2844
  const paths = factory.class.getSettablePaths({ global: this.global });
2734
- const commandFilePaths = await findFilesByGlobs(
2735
- join19(this.baseDir, paths.relativeDirPath, `*.${factory.meta.extension}`)
2736
- );
2845
+ const baseDirFull = join19(this.baseDir, paths.relativeDirPath);
2846
+ const globPattern = factory.meta.supportsSubdirectory ? join19(baseDirFull, "**", `*.${factory.meta.extension}`) : join19(baseDirFull, `*.${factory.meta.extension}`);
2847
+ const commandFilePaths = await findFilesByGlobs(globPattern);
2737
2848
  if (forDeletion) {
2738
2849
  const toolCommands2 = commandFilePaths.map(
2739
2850
  (path3) => factory.class.forDeletion({
2740
2851
  baseDir: this.baseDir,
2741
2852
  relativeDirPath: paths.relativeDirPath,
2742
- relativeFilePath: basename16(path3),
2853
+ relativeFilePath: this.safeRelativePath(baseDirFull, path3),
2743
2854
  global: this.global
2744
2855
  })
2745
2856
  ).filter((cmd) => cmd.isDeletable());
@@ -2750,7 +2861,7 @@ var CommandsProcessor = class extends FeatureProcessor {
2750
2861
  commandFilePaths.map(
2751
2862
  (path3) => factory.class.fromFile({
2752
2863
  baseDir: this.baseDir,
2753
- relativeFilePath: basename16(path3),
2864
+ relativeFilePath: this.safeRelativePath(baseDirFull, path3),
2754
2865
  global: this.global
2755
2866
  })
2756
2867
  )
@@ -6670,7 +6781,7 @@ var McpProcessor = class extends FeatureProcessor {
6670
6781
 
6671
6782
  // src/features/rules/rules-processor.ts
6672
6783
  import { encode } from "@toon-format/toon";
6673
- import { basename as basename24, join as join108, relative as relative4 } from "path";
6784
+ import { basename as basename10, join as join108, relative as relative5 } from "path";
6674
6785
  import { z as z49 } from "zod/mini";
6675
6786
 
6676
6787
  // src/constants/general.ts
@@ -6687,7 +6798,7 @@ import { z as z20 } from "zod/mini";
6687
6798
  import { join as join52 } from "path";
6688
6799
 
6689
6800
  // src/types/ai-dir.ts
6690
- import path2, { basename as basename17, join as join51, relative as relative3, resolve as resolve4 } from "path";
6801
+ import path2, { basename as basename3, join as join51, relative as relative4, resolve as resolve4 } from "path";
6691
6802
  var AiDir = class {
6692
6803
  /**
6693
6804
  * @example "."
@@ -6747,7 +6858,7 @@ var AiDir = class {
6747
6858
  const fullPath = path2.join(this.baseDir, this.relativeDirPath, this.dirName);
6748
6859
  const resolvedFull = resolve4(fullPath);
6749
6860
  const resolvedBase = resolve4(this.baseDir);
6750
- const rel = relative3(resolvedBase, resolvedFull);
6861
+ const rel = relative4(resolvedBase, resolvedFull);
6751
6862
  if (rel.startsWith("..") || path2.isAbsolute(rel)) {
6752
6863
  throw new Error(
6753
6864
  `Path traversal detected: Final path escapes baseDir. baseDir="${this.baseDir}", relativeDirPath="${this.relativeDirPath}", dirName="${this.dirName}"`
@@ -6784,12 +6895,12 @@ var AiDir = class {
6784
6895
  const dirPath = join51(baseDir, relativeDirPath, dirName);
6785
6896
  const glob = join51(dirPath, "**", "*");
6786
6897
  const filePaths = await findFilesByGlobs(glob, { type: "file" });
6787
- const filteredPaths = filePaths.filter((filePath) => basename17(filePath) !== excludeFileName);
6898
+ const filteredPaths = filePaths.filter((filePath) => basename3(filePath) !== excludeFileName);
6788
6899
  const files = await Promise.all(
6789
6900
  filteredPaths.map(async (filePath) => {
6790
6901
  const fileBuffer = await readFileBuffer(filePath);
6791
6902
  return {
6792
- relativeFilePathToDirPath: relative3(dirPath, filePath),
6903
+ relativeFilePathToDirPath: relative4(dirPath, filePath),
6793
6904
  fileBuffer
6794
6905
  };
6795
6906
  })
@@ -7139,7 +7250,7 @@ var FactorydroidSkill = class _FactorydroidSkill extends SimulatedSkill {
7139
7250
  };
7140
7251
 
7141
7252
  // src/features/skills/skills-processor.ts
7142
- import { basename as basename19, join as join71 } from "path";
7253
+ import { basename as basename5, join as join71 } from "path";
7143
7254
  import { z as z34 } from "zod/mini";
7144
7255
 
7145
7256
  // src/types/dir-feature-processor.ts
@@ -9346,7 +9457,7 @@ var RooSkill = class _RooSkill extends ToolSkill {
9346
9457
  };
9347
9458
 
9348
9459
  // src/features/skills/skills-utils.ts
9349
- import { basename as basename18, join as join70 } from "path";
9460
+ import { basename as basename4, join as join70 } from "path";
9350
9461
  async function getLocalSkillDirNames(baseDir) {
9351
9462
  const skillsDir = join70(baseDir, RULESYNC_SKILLS_RELATIVE_DIR_PATH);
9352
9463
  const names = /* @__PURE__ */ new Set();
@@ -9355,8 +9466,8 @@ async function getLocalSkillDirNames(baseDir) {
9355
9466
  }
9356
9467
  const dirPaths = await findFilesByGlobs(join70(skillsDir, "*"), { type: "dir" });
9357
9468
  for (const dirPath of dirPaths) {
9358
- const name = basename18(dirPath);
9359
- if (name === basename18(RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH)) continue;
9469
+ const name = basename4(dirPath);
9470
+ if (name === basename4(RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH)) continue;
9360
9471
  names.add(name);
9361
9472
  }
9362
9473
  return names;
@@ -9578,7 +9689,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
9578
9689
  let curatedSkills = [];
9579
9690
  if (await directoryExists(curatedDirPath)) {
9580
9691
  const curatedDirPaths = await findFilesByGlobs(join71(curatedDirPath, "*"), { type: "dir" });
9581
- const curatedDirNames = curatedDirPaths.map((path3) => basename19(path3));
9692
+ const curatedDirNames = curatedDirPaths.map((path3) => basename5(path3));
9582
9693
  const nonConflicting = curatedDirNames.filter((name) => {
9583
9694
  if (localSkillNames.has(name)) {
9584
9695
  logger.debug(`Skipping curated skill "${name}": local skill takes precedence.`);
@@ -9613,7 +9724,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
9613
9724
  const paths = factory.class.getSettablePaths({ global: this.global });
9614
9725
  const skillsDirPath = join71(this.baseDir, paths.relativeDirPath);
9615
9726
  const dirPaths = await findFilesByGlobs(join71(skillsDirPath, "*"), { type: "dir" });
9616
- const dirNames = dirPaths.map((path3) => basename19(path3));
9727
+ const dirNames = dirPaths.map((path3) => basename5(path3));
9617
9728
  const toolSkills = await Promise.all(
9618
9729
  dirNames.map(
9619
9730
  (dirName) => factory.class.fromDir({
@@ -9631,7 +9742,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
9631
9742
  const paths = factory.class.getSettablePaths({ global: this.global });
9632
9743
  const skillsDirPath = join71(this.baseDir, paths.relativeDirPath);
9633
9744
  const dirPaths = await findFilesByGlobs(join71(skillsDirPath, "*"), { type: "dir" });
9634
- const dirNames = dirPaths.map((path3) => basename19(path3));
9745
+ const dirNames = dirPaths.map((path3) => basename5(path3));
9635
9746
  const toolSkills = dirNames.map(
9636
9747
  (dirName) => factory.class.forDeletion({
9637
9748
  baseDir: this.baseDir,
@@ -9695,7 +9806,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
9695
9806
  import { join as join73 } from "path";
9696
9807
 
9697
9808
  // src/features/subagents/simulated-subagent.ts
9698
- import { basename as basename20, join as join72 } from "path";
9809
+ import { basename as basename6, join as join72 } from "path";
9699
9810
  import { z as z35 } from "zod/mini";
9700
9811
 
9701
9812
  // src/features/subagents/tool-subagent.ts
@@ -9822,7 +9933,7 @@ var SimulatedSubagent = class extends ToolSubagent {
9822
9933
  return {
9823
9934
  baseDir,
9824
9935
  relativeDirPath: this.getSettablePaths().relativeDirPath,
9825
- relativeFilePath: basename20(relativeFilePath),
9936
+ relativeFilePath: basename6(relativeFilePath),
9826
9937
  frontmatter: result.data,
9827
9938
  body: content.trim(),
9828
9939
  validate
@@ -9979,7 +10090,7 @@ var RooSubagent = class _RooSubagent extends SimulatedSubagent {
9979
10090
  };
9980
10091
 
9981
10092
  // src/features/subagents/subagents-processor.ts
9982
- import { basename as basename23, join as join84 } from "path";
10093
+ import { basename as basename9, join as join84 } from "path";
9983
10094
  import { z as z42 } from "zod/mini";
9984
10095
 
9985
10096
  // src/features/subagents/claudecode-subagent.ts
@@ -9987,7 +10098,7 @@ import { join as join79 } from "path";
9987
10098
  import { z as z37 } from "zod/mini";
9988
10099
 
9989
10100
  // src/features/subagents/rulesync-subagent.ts
9990
- import { basename as basename21, join as join78 } from "path";
10101
+ import { basename as basename7, join as join78 } from "path";
9991
10102
  import { z as z36 } from "zod/mini";
9992
10103
  var RulesyncSubagentFrontmatterSchema = z36.looseObject({
9993
10104
  targets: z36._default(RulesyncTargetsSchema, ["*"]),
@@ -10050,7 +10161,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
10050
10161
  if (!result.success) {
10051
10162
  throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${formatError(result.error)}`);
10052
10163
  }
10053
- const filename = basename21(relativeFilePath);
10164
+ const filename = basename7(relativeFilePath);
10054
10165
  return new _RulesyncSubagent({
10055
10166
  baseDir: process.cwd(),
10056
10167
  relativeDirPath: this.getSettablePaths().relativeDirPath,
@@ -10669,7 +10780,7 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
10669
10780
  };
10670
10781
 
10671
10782
  // src/features/subagents/opencode-subagent.ts
10672
- import { basename as basename22, join as join83 } from "path";
10783
+ import { basename as basename8, join as join83 } from "path";
10673
10784
  import { z as z41 } from "zod/mini";
10674
10785
  var OpenCodeSubagentFrontmatterSchema = z41.looseObject({
10675
10786
  description: z41.string(),
@@ -10711,7 +10822,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
10711
10822
  const { description, mode, name, ...opencodeSection } = this.frontmatter;
10712
10823
  const rulesyncFrontmatter = {
10713
10824
  targets: ["*"],
10714
- name: name ?? basename22(this.getRelativeFilePath(), ".md"),
10825
+ name: name ?? basename8(this.getRelativeFilePath(), ".md"),
10715
10826
  description,
10716
10827
  opencode: { mode, ...opencodeSection }
10717
10828
  };
@@ -11044,7 +11155,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
11044
11155
  (path3) => factory.class.forDeletion({
11045
11156
  baseDir: this.baseDir,
11046
11157
  relativeDirPath: paths.relativeDirPath,
11047
- relativeFilePath: basename23(path3),
11158
+ relativeFilePath: basename9(path3),
11048
11159
  global: this.global
11049
11160
  })
11050
11161
  ).filter((subagent) => subagent.isDeletable());
@@ -11057,7 +11168,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
11057
11168
  subagentFilePaths.map(
11058
11169
  (path3) => factory.class.fromFile({
11059
11170
  baseDir: this.baseDir,
11060
- relativeFilePath: basename23(path3),
11171
+ relativeFilePath: basename9(path3),
11061
11172
  global: this.global
11062
11173
  })
11063
11174
  )
@@ -12440,14 +12551,22 @@ var CopilotRuleFrontmatterSchema = z47.object({
12440
12551
  var CopilotRule = class _CopilotRule extends ToolRule {
12441
12552
  frontmatter;
12442
12553
  body;
12443
- static getSettablePaths(_options = {}) {
12554
+ static getSettablePaths(options = {}) {
12555
+ if (options.global) {
12556
+ return {
12557
+ root: {
12558
+ relativeDirPath: buildToolPath(".copilot", ".", options.excludeToolDir),
12559
+ relativeFilePath: "copilot-instructions.md"
12560
+ }
12561
+ };
12562
+ }
12444
12563
  return {
12445
12564
  root: {
12446
- relativeDirPath: buildToolPath(".github", ".", _options.excludeToolDir),
12565
+ relativeDirPath: buildToolPath(".github", ".", options.excludeToolDir),
12447
12566
  relativeFilePath: "copilot-instructions.md"
12448
12567
  },
12449
12568
  nonRoot: {
12450
- relativeDirPath: buildToolPath(".github", "instructions", _options.excludeToolDir)
12569
+ relativeDirPath: buildToolPath(".github", "instructions", options.excludeToolDir)
12451
12570
  }
12452
12571
  };
12453
12572
  }
@@ -12498,10 +12617,12 @@ var CopilotRule = class _CopilotRule extends ToolRule {
12498
12617
  static fromRulesyncRule({
12499
12618
  baseDir = process.cwd(),
12500
12619
  rulesyncRule,
12501
- validate = true
12620
+ validate = true,
12621
+ global = false
12502
12622
  }) {
12503
12623
  const rulesyncFrontmatter = rulesyncRule.getFrontmatter();
12504
12624
  const root = rulesyncFrontmatter.root;
12625
+ const paths = this.getSettablePaths({ global });
12505
12626
  const copilotFrontmatter = {
12506
12627
  description: rulesyncFrontmatter.description,
12507
12628
  applyTo: rulesyncFrontmatter.globs?.length ? rulesyncFrontmatter.globs.join(",") : void 0,
@@ -12513,12 +12634,15 @@ var CopilotRule = class _CopilotRule extends ToolRule {
12513
12634
  baseDir,
12514
12635
  frontmatter: copilotFrontmatter,
12515
12636
  body,
12516
- relativeDirPath: this.getSettablePaths().root.relativeDirPath,
12517
- relativeFilePath: this.getSettablePaths().root.relativeFilePath,
12637
+ relativeDirPath: paths.root.relativeDirPath,
12638
+ relativeFilePath: paths.root.relativeFilePath,
12518
12639
  validate,
12519
12640
  root
12520
12641
  });
12521
12642
  }
12643
+ if (!paths.nonRoot) {
12644
+ throw new Error(`nonRoot path is not set for ${rulesyncRule.getRelativeFilePath()}`);
12645
+ }
12522
12646
  const originalFileName = rulesyncRule.getRelativeFilePath();
12523
12647
  const nameWithoutExt = originalFileName.replace(/\.md$/, "");
12524
12648
  const newFileName = `${nameWithoutExt}.instructions.md`;
@@ -12526,7 +12650,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
12526
12650
  baseDir,
12527
12651
  frontmatter: copilotFrontmatter,
12528
12652
  body,
12529
- relativeDirPath: this.getSettablePaths().nonRoot.relativeDirPath,
12653
+ relativeDirPath: paths.nonRoot.relativeDirPath,
12530
12654
  relativeFilePath: newFileName,
12531
12655
  validate,
12532
12656
  root
@@ -12535,25 +12659,29 @@ var CopilotRule = class _CopilotRule extends ToolRule {
12535
12659
  static async fromFile({
12536
12660
  baseDir = process.cwd(),
12537
12661
  relativeFilePath,
12538
- validate = true
12662
+ validate = true,
12663
+ global = false
12539
12664
  }) {
12540
- const isRoot = relativeFilePath === "copilot-instructions.md";
12541
- const relativePath = isRoot ? join95(
12542
- this.getSettablePaths().root.relativeDirPath,
12543
- this.getSettablePaths().root.relativeFilePath
12544
- ) : join95(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
12545
- const fileContent = await readFileContent(join95(baseDir, relativePath));
12665
+ const paths = this.getSettablePaths({ global });
12666
+ const isRoot = relativeFilePath === paths.root.relativeFilePath;
12546
12667
  if (isRoot) {
12668
+ const relativePath2 = join95(paths.root.relativeDirPath, paths.root.relativeFilePath);
12669
+ const fileContent2 = await readFileContent(join95(baseDir, relativePath2));
12547
12670
  return new _CopilotRule({
12548
12671
  baseDir,
12549
- relativeDirPath: this.getSettablePaths().root.relativeDirPath,
12550
- relativeFilePath: this.getSettablePaths().root.relativeFilePath,
12672
+ relativeDirPath: paths.root.relativeDirPath,
12673
+ relativeFilePath: paths.root.relativeFilePath,
12551
12674
  frontmatter: {},
12552
- body: fileContent.trim(),
12675
+ body: fileContent2.trim(),
12553
12676
  validate,
12554
12677
  root: isRoot
12555
12678
  });
12556
12679
  }
12680
+ if (!paths.nonRoot) {
12681
+ throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
12682
+ }
12683
+ const relativePath = join95(paths.nonRoot.relativeDirPath, relativeFilePath);
12684
+ const fileContent = await readFileContent(join95(baseDir, relativePath));
12557
12685
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
12558
12686
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
12559
12687
  if (!result.success) {
@@ -12563,7 +12691,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
12563
12691
  }
12564
12692
  return new _CopilotRule({
12565
12693
  baseDir,
12566
- relativeDirPath: this.getSettablePaths().nonRoot.relativeDirPath,
12694
+ relativeDirPath: paths.nonRoot.relativeDirPath,
12567
12695
  relativeFilePath: relativeFilePath.endsWith(".instructions.md") ? relativeFilePath : relativeFilePath.replace(/\.md$/, ".instructions.md"),
12568
12696
  frontmatter: result.data,
12569
12697
  body: content.trim(),
@@ -12574,9 +12702,11 @@ var CopilotRule = class _CopilotRule extends ToolRule {
12574
12702
  static forDeletion({
12575
12703
  baseDir = process.cwd(),
12576
12704
  relativeDirPath,
12577
- relativeFilePath
12705
+ relativeFilePath,
12706
+ global = false
12578
12707
  }) {
12579
- const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
12708
+ const paths = this.getSettablePaths({ global });
12709
+ const isRoot = relativeFilePath === paths.root.relativeFilePath;
12580
12710
  return new _CopilotRule({
12581
12711
  baseDir,
12582
12712
  relativeDirPath,
@@ -13256,46 +13386,78 @@ var KiroRule = class _KiroRule extends ToolRule {
13256
13386
  // src/features/rules/opencode-rule.ts
13257
13387
  import { join as join102 } from "path";
13258
13388
  var OpenCodeRule = class _OpenCodeRule extends ToolRule {
13259
- static getSettablePaths(_options = {}) {
13389
+ static getSettablePaths({
13390
+ global,
13391
+ excludeToolDir
13392
+ } = {}) {
13393
+ if (global) {
13394
+ return {
13395
+ root: {
13396
+ relativeDirPath: buildToolPath(".config/opencode", ".", excludeToolDir),
13397
+ relativeFilePath: "AGENTS.md"
13398
+ }
13399
+ };
13400
+ }
13260
13401
  return {
13261
13402
  root: {
13262
13403
  relativeDirPath: ".",
13263
13404
  relativeFilePath: "AGENTS.md"
13264
13405
  },
13265
13406
  nonRoot: {
13266
- relativeDirPath: buildToolPath(".opencode", "memories", _options.excludeToolDir)
13407
+ relativeDirPath: buildToolPath(".opencode", "memories", excludeToolDir)
13267
13408
  }
13268
13409
  };
13269
13410
  }
13270
13411
  static async fromFile({
13271
13412
  baseDir = process.cwd(),
13272
13413
  relativeFilePath,
13273
- validate = true
13414
+ validate = true,
13415
+ global = false
13274
13416
  }) {
13275
- const isRoot = relativeFilePath === "AGENTS.md";
13276
- const relativePath = isRoot ? "AGENTS.md" : join102(".opencode", "memories", relativeFilePath);
13417
+ const paths = this.getSettablePaths({ global });
13418
+ const isRoot = relativeFilePath === paths.root.relativeFilePath;
13419
+ if (isRoot) {
13420
+ const relativePath2 = paths.root.relativeFilePath;
13421
+ const fileContent2 = await readFileContent(
13422
+ join102(baseDir, paths.root.relativeDirPath, relativePath2)
13423
+ );
13424
+ return new _OpenCodeRule({
13425
+ baseDir,
13426
+ relativeDirPath: paths.root.relativeDirPath,
13427
+ relativeFilePath: paths.root.relativeFilePath,
13428
+ fileContent: fileContent2,
13429
+ validate,
13430
+ root: true
13431
+ });
13432
+ }
13433
+ if (!paths.nonRoot) {
13434
+ throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
13435
+ }
13436
+ const relativePath = join102(paths.nonRoot.relativeDirPath, relativeFilePath);
13277
13437
  const fileContent = await readFileContent(join102(baseDir, relativePath));
13278
13438
  return new _OpenCodeRule({
13279
13439
  baseDir,
13280
- relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
13281
- relativeFilePath: isRoot ? "AGENTS.md" : relativeFilePath,
13440
+ relativeDirPath: paths.nonRoot.relativeDirPath,
13441
+ relativeFilePath,
13442
+ fileContent,
13282
13443
  validate,
13283
- root: isRoot,
13284
- fileContent
13444
+ root: false
13285
13445
  });
13286
13446
  }
13287
13447
  static fromRulesyncRule({
13288
13448
  baseDir = process.cwd(),
13289
13449
  rulesyncRule,
13290
- validate = true
13450
+ validate = true,
13451
+ global = false
13291
13452
  }) {
13453
+ const paths = this.getSettablePaths({ global });
13292
13454
  return new _OpenCodeRule(
13293
13455
  this.buildToolRuleParamsDefault({
13294
13456
  baseDir,
13295
13457
  rulesyncRule,
13296
13458
  validate,
13297
- rootPath: this.getSettablePaths().root,
13298
- nonRootPath: this.getSettablePaths().nonRoot
13459
+ rootPath: paths.root,
13460
+ nonRootPath: paths.nonRoot
13299
13461
  })
13300
13462
  );
13301
13463
  }
@@ -13308,9 +13470,11 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
13308
13470
  static forDeletion({
13309
13471
  baseDir = process.cwd(),
13310
13472
  relativeDirPath,
13311
- relativeFilePath
13473
+ relativeFilePath,
13474
+ global = false
13312
13475
  }) {
13313
- const isRoot = relativeFilePath === "AGENTS.md" && relativeDirPath === ".";
13476
+ const paths = this.getSettablePaths({ global });
13477
+ const isRoot = relativeFilePath === paths.root.relativeFilePath;
13314
13478
  return new _OpenCodeRule({
13315
13479
  baseDir,
13316
13480
  relativeDirPath,
@@ -13768,42 +13932,66 @@ var toolRuleFactories = /* @__PURE__ */ new Map([
13768
13932
  "antigravity",
13769
13933
  {
13770
13934
  class: AntigravityRule,
13771
- meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
13935
+ meta: {
13936
+ extension: "md",
13937
+ supportsGlobal: false,
13938
+ ruleDiscoveryMode: "auto"
13939
+ }
13772
13940
  }
13773
13941
  ],
13774
13942
  [
13775
13943
  "augmentcode",
13776
13944
  {
13777
13945
  class: AugmentcodeRule,
13778
- meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
13946
+ meta: {
13947
+ extension: "md",
13948
+ supportsGlobal: false,
13949
+ ruleDiscoveryMode: "auto"
13950
+ }
13779
13951
  }
13780
13952
  ],
13781
13953
  [
13782
13954
  "augmentcode-legacy",
13783
13955
  {
13784
13956
  class: AugmentcodeLegacyRule,
13785
- meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
13957
+ meta: {
13958
+ extension: "md",
13959
+ supportsGlobal: false,
13960
+ ruleDiscoveryMode: "toon"
13961
+ }
13786
13962
  }
13787
13963
  ],
13788
13964
  [
13789
13965
  "claudecode",
13790
13966
  {
13791
13967
  class: ClaudecodeRule,
13792
- meta: { extension: "md", supportsGlobal: true, ruleDiscoveryMode: "auto" }
13968
+ meta: {
13969
+ extension: "md",
13970
+ supportsGlobal: true,
13971
+ ruleDiscoveryMode: "auto"
13972
+ }
13793
13973
  }
13794
13974
  ],
13795
13975
  [
13796
13976
  "claudecode-legacy",
13797
13977
  {
13798
13978
  class: ClaudecodeLegacyRule,
13799
- meta: { extension: "md", supportsGlobal: true, ruleDiscoveryMode: "claudecode-legacy" }
13979
+ meta: {
13980
+ extension: "md",
13981
+ supportsGlobal: true,
13982
+ ruleDiscoveryMode: "claudecode-legacy"
13983
+ }
13800
13984
  }
13801
13985
  ],
13802
13986
  [
13803
13987
  "cline",
13804
13988
  {
13805
13989
  class: ClineRule,
13806
- meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
13990
+ meta: {
13991
+ extension: "md",
13992
+ supportsGlobal: false,
13993
+ ruleDiscoveryMode: "auto"
13994
+ }
13807
13995
  }
13808
13996
  ],
13809
13997
  [
@@ -13826,7 +14014,7 @@ var toolRuleFactories = /* @__PURE__ */ new Map([
13826
14014
  class: CopilotRule,
13827
14015
  meta: {
13828
14016
  extension: "md",
13829
- supportsGlobal: false,
14017
+ supportsGlobal: true,
13830
14018
  ruleDiscoveryMode: "auto"
13831
14019
  }
13832
14020
  }
@@ -13876,42 +14064,66 @@ var toolRuleFactories = /* @__PURE__ */ new Map([
13876
14064
  "junie",
13877
14065
  {
13878
14066
  class: JunieRule,
13879
- meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
14067
+ meta: {
14068
+ extension: "md",
14069
+ supportsGlobal: false,
14070
+ ruleDiscoveryMode: "toon"
14071
+ }
13880
14072
  }
13881
14073
  ],
13882
14074
  [
13883
14075
  "kilo",
13884
14076
  {
13885
14077
  class: KiloRule,
13886
- meta: { extension: "md", supportsGlobal: true, ruleDiscoveryMode: "auto" }
14078
+ meta: {
14079
+ extension: "md",
14080
+ supportsGlobal: true,
14081
+ ruleDiscoveryMode: "auto"
14082
+ }
13887
14083
  }
13888
14084
  ],
13889
14085
  [
13890
14086
  "kiro",
13891
14087
  {
13892
14088
  class: KiroRule,
13893
- meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
14089
+ meta: {
14090
+ extension: "md",
14091
+ supportsGlobal: false,
14092
+ ruleDiscoveryMode: "toon"
14093
+ }
13894
14094
  }
13895
14095
  ],
13896
14096
  [
13897
14097
  "opencode",
13898
14098
  {
13899
14099
  class: OpenCodeRule,
13900
- meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
14100
+ meta: {
14101
+ extension: "md",
14102
+ supportsGlobal: true,
14103
+ ruleDiscoveryMode: "toon"
14104
+ }
13901
14105
  }
13902
14106
  ],
13903
14107
  [
13904
14108
  "qwencode",
13905
14109
  {
13906
14110
  class: QwencodeRule,
13907
- meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
14111
+ meta: {
14112
+ extension: "md",
14113
+ supportsGlobal: false,
14114
+ ruleDiscoveryMode: "toon"
14115
+ }
13908
14116
  }
13909
14117
  ],
13910
14118
  [
13911
14119
  "replit",
13912
14120
  {
13913
14121
  class: ReplitRule,
13914
- meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
14122
+ meta: {
14123
+ extension: "md",
14124
+ supportsGlobal: false,
14125
+ ruleDiscoveryMode: "auto"
14126
+ }
13915
14127
  }
13916
14128
  ],
13917
14129
  [
@@ -13933,14 +14145,22 @@ var toolRuleFactories = /* @__PURE__ */ new Map([
13933
14145
  "warp",
13934
14146
  {
13935
14147
  class: WarpRule,
13936
- meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
14148
+ meta: {
14149
+ extension: "md",
14150
+ supportsGlobal: false,
14151
+ ruleDiscoveryMode: "toon"
14152
+ }
13937
14153
  }
13938
14154
  ],
13939
14155
  [
13940
14156
  "windsurf",
13941
14157
  {
13942
14158
  class: WindsurfRule,
13943
- meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
14159
+ meta: {
14160
+ extension: "md",
14161
+ supportsGlobal: false,
14162
+ ruleDiscoveryMode: "auto"
14163
+ }
13944
14164
  }
13945
14165
  ]
13946
14166
  ]);
@@ -14088,7 +14308,9 @@ var RulesProcessor = class extends FeatureProcessor {
14088
14308
  })
14089
14309
  );
14090
14310
  } else if (this.toolTarget === "claudecode-legacy") {
14091
- const paths = ClaudecodeLegacyRule.getSettablePaths({ global: this.global });
14311
+ const paths = ClaudecodeLegacyRule.getSettablePaths({
14312
+ global: this.global
14313
+ });
14092
14314
  toolRules.push(
14093
14315
  new ClaudecodeLegacyRule({
14094
14316
  baseDir: this.baseDir,
@@ -14173,8 +14395,11 @@ var RulesProcessor = class extends FeatureProcessor {
14173
14395
  logger.debug(`Found ${files.length} rulesync files`);
14174
14396
  const rulesyncRules = await Promise.all(
14175
14397
  files.map((file) => {
14176
- const relativeFilePath = relative4(rulesyncBaseDir, file);
14177
- checkPathTraversal({ relativePath: relativeFilePath, intendedRootDir: rulesyncBaseDir });
14398
+ const relativeFilePath = relative5(rulesyncBaseDir, file);
14399
+ checkPathTraversal({
14400
+ relativePath: relativeFilePath,
14401
+ intendedRootDir: rulesyncBaseDir
14402
+ });
14178
14403
  return RulesyncRule.fromFile({
14179
14404
  relativeFilePath
14180
14405
  });
@@ -14225,7 +14450,9 @@ var RulesProcessor = class extends FeatureProcessor {
14225
14450
  } = {}) {
14226
14451
  try {
14227
14452
  const factory = this.getFactory(this.toolTarget);
14228
- const settablePaths = factory.class.getSettablePaths({ global: this.global });
14453
+ const settablePaths = factory.class.getSettablePaths({
14454
+ global: this.global
14455
+ });
14229
14456
  const rootToolRules = await (async () => {
14230
14457
  if (!settablePaths.root) {
14231
14458
  return [];
@@ -14242,7 +14469,7 @@ var RulesProcessor = class extends FeatureProcessor {
14242
14469
  (filePath) => factory.class.forDeletion({
14243
14470
  baseDir: this.baseDir,
14244
14471
  relativeDirPath: settablePaths.root?.relativeDirPath ?? ".",
14245
- relativeFilePath: basename24(filePath),
14472
+ relativeFilePath: basename10(filePath),
14246
14473
  global: this.global
14247
14474
  })
14248
14475
  ).filter((rule) => rule.isDeletable());
@@ -14251,7 +14478,7 @@ var RulesProcessor = class extends FeatureProcessor {
14251
14478
  rootFilePaths.map(
14252
14479
  (filePath) => factory.class.fromFile({
14253
14480
  baseDir: this.baseDir,
14254
- relativeFilePath: basename24(filePath),
14481
+ relativeFilePath: basename10(filePath),
14255
14482
  global: this.global
14256
14483
  })
14257
14484
  )
@@ -14275,7 +14502,7 @@ var RulesProcessor = class extends FeatureProcessor {
14275
14502
  (filePath) => factory.class.forDeletion({
14276
14503
  baseDir: this.baseDir,
14277
14504
  relativeDirPath: settablePaths.root?.relativeDirPath ?? ".",
14278
- relativeFilePath: basename24(filePath),
14505
+ relativeFilePath: basename10(filePath),
14279
14506
  global: this.global
14280
14507
  })
14281
14508
  ).filter((rule) => rule.isDeletable());
@@ -14291,7 +14518,7 @@ var RulesProcessor = class extends FeatureProcessor {
14291
14518
  );
14292
14519
  if (forDeletion) {
14293
14520
  return nonRootFilePaths.map((filePath) => {
14294
- const relativeFilePath = relative4(nonRootBaseDir, filePath);
14521
+ const relativeFilePath = relative5(nonRootBaseDir, filePath);
14295
14522
  checkPathTraversal({
14296
14523
  relativePath: relativeFilePath,
14297
14524
  intendedRootDir: nonRootBaseDir
@@ -14306,8 +14533,11 @@ var RulesProcessor = class extends FeatureProcessor {
14306
14533
  }
14307
14534
  return await Promise.all(
14308
14535
  nonRootFilePaths.map((filePath) => {
14309
- const relativeFilePath = relative4(nonRootBaseDir, filePath);
14310
- checkPathTraversal({ relativePath: relativeFilePath, intendedRootDir: nonRootBaseDir });
14536
+ const relativeFilePath = relative5(nonRootBaseDir, filePath);
14537
+ checkPathTraversal({
14538
+ relativePath: relativeFilePath,
14539
+ intendedRootDir: nonRootBaseDir
14540
+ });
14311
14541
  return factory.class.fromFile({
14312
14542
  baseDir: this.baseDir,
14313
14543
  relativeFilePath,