rulesync 7.4.0 → 7.6.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.
@@ -112,6 +112,7 @@ var ALL_TOOL_TARGETS = [
112
112
  "cursor",
113
113
  "factorydroid",
114
114
  "geminicli",
115
+ "goose",
115
116
  "junie",
116
117
  "kilo",
117
118
  "kiro",
@@ -602,10 +603,10 @@ function getBaseDirsInLightOfGlobal({
602
603
 
603
604
  // src/lib/generate.ts
604
605
  import { intersection } from "es-toolkit";
605
- import { join as join109 } from "path";
606
+ import { join as join110 } from "path";
606
607
 
607
608
  // src/features/commands/commands-processor.ts
608
- import { basename as basename16, join as join19 } from "path";
609
+ import { basename as basename2, join as join19, relative as relative3 } from "path";
609
610
  import { z as z12 } from "zod/mini";
610
611
 
611
612
  // src/types/feature-processor.ts
@@ -671,7 +672,7 @@ var FeatureProcessor = class {
671
672
  };
672
673
 
673
674
  // src/features/commands/agentsmd-command.ts
674
- import { basename as basename2, join as join5 } from "path";
675
+ import { join as join5 } from "path";
675
676
 
676
677
  // src/utils/frontmatter.ts
677
678
  import matter from "gray-matter";
@@ -724,7 +725,7 @@ function parseFrontmatter(content) {
724
725
  }
725
726
 
726
727
  // src/features/commands/simulated-command.ts
727
- import { basename, join as join4 } from "path";
728
+ import { join as join4 } from "path";
728
729
  import { z as z4 } from "zod/mini";
729
730
 
730
731
  // src/types/ai-file.ts
@@ -972,7 +973,7 @@ var SimulatedCommand = class _SimulatedCommand extends ToolCommand {
972
973
  return {
973
974
  baseDir,
974
975
  relativeDirPath: _SimulatedCommand.getSettablePaths().relativeDirPath,
975
- relativeFilePath: basename(relativeFilePath),
976
+ relativeFilePath,
976
977
  frontmatter: result.data,
977
978
  body: content.trim(),
978
979
  validate
@@ -1029,7 +1030,7 @@ var AgentsmdCommand = class _AgentsmdCommand extends SimulatedCommand {
1029
1030
  return new _AgentsmdCommand({
1030
1031
  baseDir,
1031
1032
  relativeDirPath: _AgentsmdCommand.getSettablePaths().relativeDirPath,
1032
- relativeFilePath: basename2(relativeFilePath),
1033
+ relativeFilePath,
1033
1034
  frontmatter: result.data,
1034
1035
  body: content.trim(),
1035
1036
  validate
@@ -1053,7 +1054,7 @@ var AgentsmdCommand = class _AgentsmdCommand extends SimulatedCommand {
1053
1054
  };
1054
1055
 
1055
1056
  // src/features/commands/antigravity-command.ts
1056
- import { basename as basename4, join as join7 } from "path";
1057
+ import { basename, join as join7 } from "path";
1057
1058
  import { z as z6 } from "zod/mini";
1058
1059
 
1059
1060
  // src/utils/type-guards.ts
@@ -1062,7 +1063,7 @@ function isRecord(value) {
1062
1063
  }
1063
1064
 
1064
1065
  // src/features/commands/rulesync-command.ts
1065
- import { basename as basename3, join as join6 } from "path";
1066
+ import { join as join6 } from "path";
1066
1067
  import { z as z5 } from "zod/mini";
1067
1068
 
1068
1069
  // src/types/rulesync-file.ts
@@ -1106,6 +1107,16 @@ var RulesyncCommand = class _RulesyncCommand extends RulesyncFile {
1106
1107
  getBody() {
1107
1108
  return this.body;
1108
1109
  }
1110
+ withRelativeFilePath(newRelativeFilePath) {
1111
+ return new _RulesyncCommand({
1112
+ baseDir: this.getBaseDir(),
1113
+ relativeDirPath: this.getRelativeDirPath(),
1114
+ relativeFilePath: newRelativeFilePath,
1115
+ frontmatter: this.getFrontmatter(),
1116
+ body: this.getBody(),
1117
+ fileContent: this.getFileContent()
1118
+ });
1119
+ }
1109
1120
  validate() {
1110
1121
  if (!this.frontmatter) {
1111
1122
  return { success: true, error: null };
@@ -1136,11 +1147,10 @@ var RulesyncCommand = class _RulesyncCommand extends RulesyncFile {
1136
1147
  if (!result.success) {
1137
1148
  throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${formatError(result.error)}`);
1138
1149
  }
1139
- const filename = basename3(relativeFilePath);
1140
1150
  return new _RulesyncCommand({
1141
1151
  baseDir: process.cwd(),
1142
1152
  relativeDirPath: _RulesyncCommand.getSettablePaths().relativeDirPath,
1143
- relativeFilePath: filename,
1153
+ relativeFilePath,
1144
1154
  frontmatter: result.data,
1145
1155
  body: content.trim(),
1146
1156
  fileContent
@@ -1255,7 +1265,7 @@ ${body}${turboDirective}`;
1255
1265
  const antigravityTrigger = antigravityConfig && typeof antigravityConfig.trigger === "string" ? antigravityConfig.trigger : void 0;
1256
1266
  const rootTrigger = typeof rulesyncFrontmatter.trigger === "string" ? rulesyncFrontmatter.trigger : void 0;
1257
1267
  const bodyTriggerMatch = rulesyncCommand.getBody().match(/trigger:\s*(\/[\w-]+)/);
1258
- const filenameTrigger = `/${basename4(rulesyncCommand.getRelativeFilePath(), ".md")}`;
1268
+ const filenameTrigger = `/${basename(rulesyncCommand.getRelativeFilePath(), ".md")}`;
1259
1269
  return antigravityTrigger || rootTrigger || (bodyTriggerMatch ? bodyTriggerMatch[1] : void 0) || filenameTrigger;
1260
1270
  }
1261
1271
  validate() {
@@ -1299,7 +1309,7 @@ ${body}${turboDirective}`;
1299
1309
  return new _AntigravityCommand({
1300
1310
  baseDir,
1301
1311
  relativeDirPath: _AntigravityCommand.getSettablePaths().relativeDirPath,
1302
- relativeFilePath: basename4(relativeFilePath),
1312
+ relativeFilePath,
1303
1313
  frontmatter: result.data,
1304
1314
  body: content.trim(),
1305
1315
  fileContent,
@@ -1324,7 +1334,7 @@ ${body}${turboDirective}`;
1324
1334
  };
1325
1335
 
1326
1336
  // src/features/commands/claudecode-command.ts
1327
- import { basename as basename5, join as join8 } from "path";
1337
+ import { join as join8 } from "path";
1328
1338
  import { z as z7 } from "zod/mini";
1329
1339
  var ClaudecodeCommandFrontmatterSchema = z7.looseObject({
1330
1340
  description: z7.string(),
@@ -1445,7 +1455,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
1445
1455
  return new _ClaudecodeCommand({
1446
1456
  baseDir,
1447
1457
  relativeDirPath: paths.relativeDirPath,
1448
- relativeFilePath: basename5(relativeFilePath),
1458
+ relativeFilePath,
1449
1459
  frontmatter: result.data,
1450
1460
  body: content.trim(),
1451
1461
  validate
@@ -1468,7 +1478,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
1468
1478
  };
1469
1479
 
1470
1480
  // src/features/commands/cline-command.ts
1471
- import { basename as basename6, join as join9 } from "path";
1481
+ import { join as join9 } from "path";
1472
1482
  var ClineCommand = class _ClineCommand extends ToolCommand {
1473
1483
  static getSettablePaths({ global } = {}) {
1474
1484
  if (global) {
@@ -1535,7 +1545,7 @@ var ClineCommand = class _ClineCommand extends ToolCommand {
1535
1545
  return new _ClineCommand({
1536
1546
  baseDir,
1537
1547
  relativeDirPath: paths.relativeDirPath,
1538
- relativeFilePath: basename6(relativeFilePath),
1548
+ relativeFilePath,
1539
1549
  fileContent: content.trim(),
1540
1550
  validate
1541
1551
  });
@@ -1556,7 +1566,7 @@ var ClineCommand = class _ClineCommand extends ToolCommand {
1556
1566
  };
1557
1567
 
1558
1568
  // src/features/commands/codexcli-command.ts
1559
- import { basename as basename7, join as join10 } from "path";
1569
+ import { join as join10 } from "path";
1560
1570
  var CodexcliCommand = class _CodexcliCommand extends ToolCommand {
1561
1571
  static getSettablePaths({ global } = {}) {
1562
1572
  if (!global) {
@@ -1622,7 +1632,7 @@ var CodexcliCommand = class _CodexcliCommand extends ToolCommand {
1622
1632
  return new _CodexcliCommand({
1623
1633
  baseDir,
1624
1634
  relativeDirPath: paths.relativeDirPath,
1625
- relativeFilePath: basename7(relativeFilePath),
1635
+ relativeFilePath,
1626
1636
  fileContent: content.trim(),
1627
1637
  validate
1628
1638
  });
@@ -1643,7 +1653,7 @@ var CodexcliCommand = class _CodexcliCommand extends ToolCommand {
1643
1653
  };
1644
1654
 
1645
1655
  // src/features/commands/copilot-command.ts
1646
- import { basename as basename8, join as join11 } from "path";
1656
+ import { join as join11 } from "path";
1647
1657
  import { z as z8 } from "zod/mini";
1648
1658
  var CopilotCommandFrontmatterSchema = z8.looseObject({
1649
1659
  mode: z8.optional(z8.string()),
@@ -1755,7 +1765,7 @@ var CopilotCommand = class _CopilotCommand extends ToolCommand {
1755
1765
  return new _CopilotCommand({
1756
1766
  baseDir,
1757
1767
  relativeDirPath: paths.relativeDirPath,
1758
- relativeFilePath: basename8(relativeFilePath),
1768
+ relativeFilePath,
1759
1769
  frontmatter: result.data,
1760
1770
  body: content.trim(),
1761
1771
  validate
@@ -1784,7 +1794,7 @@ var CopilotCommand = class _CopilotCommand extends ToolCommand {
1784
1794
  };
1785
1795
 
1786
1796
  // src/features/commands/cursor-command.ts
1787
- import { basename as basename9, join as join12 } from "path";
1797
+ import { join as join12 } from "path";
1788
1798
  var CursorCommand = class _CursorCommand extends ToolCommand {
1789
1799
  static getSettablePaths(_options = {}) {
1790
1800
  return {
@@ -1847,7 +1857,7 @@ var CursorCommand = class _CursorCommand extends ToolCommand {
1847
1857
  return new _CursorCommand({
1848
1858
  baseDir,
1849
1859
  relativeDirPath: paths.relativeDirPath,
1850
- relativeFilePath: basename9(relativeFilePath),
1860
+ relativeFilePath,
1851
1861
  fileContent: content.trim(),
1852
1862
  validate
1853
1863
  });
@@ -1868,7 +1878,7 @@ var CursorCommand = class _CursorCommand extends ToolCommand {
1868
1878
  };
1869
1879
 
1870
1880
  // src/features/commands/factorydroid-command.ts
1871
- import { basename as basename10, join as join13 } from "path";
1881
+ import { join as join13 } from "path";
1872
1882
  var FactorydroidCommand = class _FactorydroidCommand extends SimulatedCommand {
1873
1883
  static getSettablePaths(_options) {
1874
1884
  return {
@@ -1902,7 +1912,7 @@ var FactorydroidCommand = class _FactorydroidCommand extends SimulatedCommand {
1902
1912
  return new _FactorydroidCommand({
1903
1913
  baseDir,
1904
1914
  relativeDirPath: paths.relativeDirPath,
1905
- relativeFilePath: basename10(relativeFilePath),
1915
+ relativeFilePath,
1906
1916
  frontmatter: result.data,
1907
1917
  body: content.trim(),
1908
1918
  validate
@@ -1926,7 +1936,7 @@ var FactorydroidCommand = class _FactorydroidCommand extends SimulatedCommand {
1926
1936
  };
1927
1937
 
1928
1938
  // src/features/commands/geminicli-command.ts
1929
- import { basename as basename11, join as join14 } from "path";
1939
+ import { join as join14 } from "path";
1930
1940
  import { parse as parseToml } from "smol-toml";
1931
1941
  import { z as z9 } from "zod/mini";
1932
1942
  var GeminiCliCommandFrontmatterSchema = z9.looseObject({
@@ -2034,7 +2044,7 @@ ${geminiFrontmatter.prompt}
2034
2044
  return new _GeminiCliCommand({
2035
2045
  baseDir,
2036
2046
  relativeDirPath: paths.relativeDirPath,
2037
- relativeFilePath: basename11(relativeFilePath),
2047
+ relativeFilePath,
2038
2048
  fileContent,
2039
2049
  validate
2040
2050
  });
@@ -2071,7 +2081,7 @@ prompt = ""`;
2071
2081
  };
2072
2082
 
2073
2083
  // src/features/commands/kilo-command.ts
2074
- import { basename as basename12, join as join15 } from "path";
2084
+ import { join as join15 } from "path";
2075
2085
  var KiloCommand = class _KiloCommand extends ToolCommand {
2076
2086
  static getSettablePaths(_options = {}) {
2077
2087
  return {
@@ -2131,7 +2141,7 @@ var KiloCommand = class _KiloCommand extends ToolCommand {
2131
2141
  return new _KiloCommand({
2132
2142
  baseDir,
2133
2143
  relativeDirPath: paths.relativeDirPath,
2134
- relativeFilePath: basename12(relativeFilePath),
2144
+ relativeFilePath,
2135
2145
  fileContent: content.trim(),
2136
2146
  validate
2137
2147
  });
@@ -2152,7 +2162,7 @@ var KiloCommand = class _KiloCommand extends ToolCommand {
2152
2162
  };
2153
2163
 
2154
2164
  // src/features/commands/kiro-command.ts
2155
- import { basename as basename13, join as join16 } from "path";
2165
+ import { join as join16 } from "path";
2156
2166
  var KiroCommand = class _KiroCommand extends ToolCommand {
2157
2167
  static getSettablePaths(_options = {}) {
2158
2168
  return {
@@ -2212,7 +2222,7 @@ var KiroCommand = class _KiroCommand extends ToolCommand {
2212
2222
  return new _KiroCommand({
2213
2223
  baseDir,
2214
2224
  relativeDirPath: paths.relativeDirPath,
2215
- relativeFilePath: basename13(relativeFilePath),
2225
+ relativeFilePath,
2216
2226
  fileContent: content.trim(),
2217
2227
  validate
2218
2228
  });
@@ -2233,7 +2243,7 @@ var KiroCommand = class _KiroCommand extends ToolCommand {
2233
2243
  };
2234
2244
 
2235
2245
  // src/features/commands/opencode-command.ts
2236
- import { basename as basename14, join as join17 } from "path";
2246
+ import { join as join17 } from "path";
2237
2247
  import { optional as optional2, z as z10 } from "zod/mini";
2238
2248
  var OpenCodeCommandFrontmatterSchema = z10.looseObject({
2239
2249
  description: z10.string(),
@@ -2344,7 +2354,7 @@ var OpenCodeCommand = class _OpenCodeCommand extends ToolCommand {
2344
2354
  return new _OpenCodeCommand({
2345
2355
  baseDir,
2346
2356
  relativeDirPath: paths.relativeDirPath,
2347
- relativeFilePath: basename14(relativeFilePath),
2357
+ relativeFilePath,
2348
2358
  frontmatter: result.data,
2349
2359
  body: content.trim(),
2350
2360
  validate
@@ -2373,7 +2383,7 @@ var OpenCodeCommand = class _OpenCodeCommand extends ToolCommand {
2373
2383
  };
2374
2384
 
2375
2385
  // src/features/commands/roo-command.ts
2376
- import { basename as basename15, join as join18 } from "path";
2386
+ import { join as join18 } from "path";
2377
2387
  import { optional as optional3, z as z11 } from "zod/mini";
2378
2388
  var RooCommandFrontmatterSchema = z11.looseObject({
2379
2389
  description: z11.string(),
@@ -2489,7 +2499,7 @@ var RooCommand = class _RooCommand extends ToolCommand {
2489
2499
  return new _RooCommand({
2490
2500
  baseDir,
2491
2501
  relativeDirPath: _RooCommand.getSettablePaths().relativeDirPath,
2492
- relativeFilePath: basename15(relativeFilePath),
2502
+ relativeFilePath,
2493
2503
  frontmatter: result.data,
2494
2504
  body: content.trim(),
2495
2505
  fileContent,
@@ -2536,42 +2546,78 @@ var toolCommandFactories = /* @__PURE__ */ new Map([
2536
2546
  "agentsmd",
2537
2547
  {
2538
2548
  class: AgentsmdCommand,
2539
- meta: { extension: "md", supportsProject: true, supportsGlobal: false, isSimulated: true }
2549
+ meta: {
2550
+ extension: "md",
2551
+ supportsProject: true,
2552
+ supportsGlobal: false,
2553
+ isSimulated: true,
2554
+ supportsSubdirectory: false
2555
+ }
2540
2556
  }
2541
2557
  ],
2542
2558
  [
2543
2559
  "antigravity",
2544
2560
  {
2545
2561
  class: AntigravityCommand,
2546
- meta: { extension: "md", supportsProject: true, supportsGlobal: false, isSimulated: false }
2562
+ meta: {
2563
+ extension: "md",
2564
+ supportsProject: true,
2565
+ supportsGlobal: false,
2566
+ isSimulated: false,
2567
+ supportsSubdirectory: false
2568
+ }
2547
2569
  }
2548
2570
  ],
2549
2571
  [
2550
2572
  "claudecode",
2551
2573
  {
2552
2574
  class: ClaudecodeCommand,
2553
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2575
+ meta: {
2576
+ extension: "md",
2577
+ supportsProject: true,
2578
+ supportsGlobal: true,
2579
+ isSimulated: false,
2580
+ supportsSubdirectory: true
2581
+ }
2554
2582
  }
2555
2583
  ],
2556
2584
  [
2557
2585
  "claudecode-legacy",
2558
2586
  {
2559
2587
  class: ClaudecodeCommand,
2560
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2588
+ meta: {
2589
+ extension: "md",
2590
+ supportsProject: true,
2591
+ supportsGlobal: true,
2592
+ isSimulated: false,
2593
+ supportsSubdirectory: true
2594
+ }
2561
2595
  }
2562
2596
  ],
2563
2597
  [
2564
2598
  "cline",
2565
2599
  {
2566
2600
  class: ClineCommand,
2567
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2601
+ meta: {
2602
+ extension: "md",
2603
+ supportsProject: true,
2604
+ supportsGlobal: true,
2605
+ isSimulated: false,
2606
+ supportsSubdirectory: false
2607
+ }
2568
2608
  }
2569
2609
  ],
2570
2610
  [
2571
2611
  "codexcli",
2572
2612
  {
2573
2613
  class: CodexcliCommand,
2574
- meta: { extension: "md", supportsProject: false, supportsGlobal: true, isSimulated: false }
2614
+ meta: {
2615
+ extension: "md",
2616
+ supportsProject: false,
2617
+ supportsGlobal: true,
2618
+ isSimulated: false,
2619
+ supportsSubdirectory: false
2620
+ }
2575
2621
  }
2576
2622
  ],
2577
2623
  [
@@ -2582,7 +2628,8 @@ var toolCommandFactories = /* @__PURE__ */ new Map([
2582
2628
  extension: "prompt.md",
2583
2629
  supportsProject: true,
2584
2630
  supportsGlobal: false,
2585
- isSimulated: false
2631
+ isSimulated: false,
2632
+ supportsSubdirectory: false
2586
2633
  }
2587
2634
  }
2588
2635
  ],
@@ -2590,49 +2637,91 @@ var toolCommandFactories = /* @__PURE__ */ new Map([
2590
2637
  "cursor",
2591
2638
  {
2592
2639
  class: CursorCommand,
2593
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2640
+ meta: {
2641
+ extension: "md",
2642
+ supportsProject: true,
2643
+ supportsGlobal: true,
2644
+ isSimulated: false,
2645
+ supportsSubdirectory: false
2646
+ }
2594
2647
  }
2595
2648
  ],
2596
2649
  [
2597
2650
  "factorydroid",
2598
2651
  {
2599
2652
  class: FactorydroidCommand,
2600
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: true }
2653
+ meta: {
2654
+ extension: "md",
2655
+ supportsProject: true,
2656
+ supportsGlobal: true,
2657
+ isSimulated: true,
2658
+ supportsSubdirectory: false
2659
+ }
2601
2660
  }
2602
2661
  ],
2603
2662
  [
2604
2663
  "geminicli",
2605
2664
  {
2606
2665
  class: GeminiCliCommand,
2607
- meta: { extension: "toml", supportsProject: true, supportsGlobal: true, isSimulated: false }
2666
+ meta: {
2667
+ extension: "toml",
2668
+ supportsProject: true,
2669
+ supportsGlobal: true,
2670
+ isSimulated: false,
2671
+ supportsSubdirectory: true
2672
+ }
2608
2673
  }
2609
2674
  ],
2610
2675
  [
2611
2676
  "kilo",
2612
2677
  {
2613
2678
  class: KiloCommand,
2614
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2679
+ meta: {
2680
+ extension: "md",
2681
+ supportsProject: true,
2682
+ supportsGlobal: true,
2683
+ isSimulated: false,
2684
+ supportsSubdirectory: false
2685
+ }
2615
2686
  }
2616
2687
  ],
2617
2688
  [
2618
2689
  "kiro",
2619
2690
  {
2620
2691
  class: KiroCommand,
2621
- meta: { extension: "md", supportsProject: true, supportsGlobal: false, isSimulated: false }
2692
+ meta: {
2693
+ extension: "md",
2694
+ supportsProject: true,
2695
+ supportsGlobal: false,
2696
+ isSimulated: false,
2697
+ supportsSubdirectory: false
2698
+ }
2622
2699
  }
2623
2700
  ],
2624
2701
  [
2625
2702
  "opencode",
2626
2703
  {
2627
2704
  class: OpenCodeCommand,
2628
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2705
+ meta: {
2706
+ extension: "md",
2707
+ supportsProject: true,
2708
+ supportsGlobal: true,
2709
+ isSimulated: false,
2710
+ supportsSubdirectory: true
2711
+ }
2629
2712
  }
2630
2713
  ],
2631
2714
  [
2632
2715
  "roo",
2633
2716
  {
2634
2717
  class: RooCommand,
2635
- meta: { extension: "md", supportsProject: true, supportsGlobal: false, isSimulated: false }
2718
+ meta: {
2719
+ extension: "md",
2720
+ supportsProject: true,
2721
+ supportsGlobal: false,
2722
+ isSimulated: false,
2723
+ supportsSubdirectory: true
2724
+ }
2636
2725
  }
2637
2726
  ]
2638
2727
  ]);
@@ -2685,13 +2774,27 @@ var CommandsProcessor = class extends FeatureProcessor {
2685
2774
  (file) => file instanceof RulesyncCommand
2686
2775
  );
2687
2776
  const factory = this.getFactory(this.toolTarget);
2777
+ const flattenedPathOrigins = /* @__PURE__ */ new Map();
2688
2778
  const toolCommands = rulesyncCommands.map((rulesyncCommand) => {
2689
2779
  if (!factory.class.isTargetedByRulesyncCommand(rulesyncCommand)) {
2690
2780
  return null;
2691
2781
  }
2782
+ const originalRelativePath = rulesyncCommand.getRelativeFilePath();
2783
+ const commandToConvert = factory.meta.supportsSubdirectory ? rulesyncCommand : this.flattenRelativeFilePath(rulesyncCommand);
2784
+ if (!factory.meta.supportsSubdirectory) {
2785
+ const flattenedPath = commandToConvert.getRelativeFilePath();
2786
+ const firstOrigin = flattenedPathOrigins.get(flattenedPath);
2787
+ if (firstOrigin && firstOrigin !== originalRelativePath) {
2788
+ logger.warn(
2789
+ `Command path collision detected while flattening for ${this.toolTarget}: "${firstOrigin}" and "${originalRelativePath}" both map to "${flattenedPath}". The later command will overwrite the earlier one.`
2790
+ );
2791
+ } else if (!firstOrigin) {
2792
+ flattenedPathOrigins.set(flattenedPath, originalRelativePath);
2793
+ }
2794
+ }
2692
2795
  return factory.class.fromRulesyncCommand({
2693
2796
  baseDir: this.baseDir,
2694
- rulesyncCommand,
2797
+ rulesyncCommand: commandToConvert,
2695
2798
  global: this.global
2696
2799
  });
2697
2800
  }).filter((command) => command !== null);
@@ -2706,17 +2809,26 @@ var CommandsProcessor = class extends FeatureProcessor {
2706
2809
  });
2707
2810
  return rulesyncCommands;
2708
2811
  }
2812
+ flattenRelativeFilePath(rulesyncCommand) {
2813
+ const flatPath = basename2(rulesyncCommand.getRelativeFilePath());
2814
+ if (flatPath === rulesyncCommand.getRelativeFilePath()) return rulesyncCommand;
2815
+ return rulesyncCommand.withRelativeFilePath(flatPath);
2816
+ }
2817
+ safeRelativePath(basePath, fullPath) {
2818
+ const rel = relative3(basePath, fullPath);
2819
+ checkPathTraversal({ relativePath: rel, intendedRootDir: basePath });
2820
+ return rel;
2821
+ }
2709
2822
  /**
2710
2823
  * Implementation of abstract method from FeatureProcessor
2711
2824
  * Load and parse rulesync command files from .rulesync/commands/ directory
2712
2825
  */
2713
2826
  async loadRulesyncFiles() {
2714
- const rulesyncCommandPaths = await findFilesByGlobs(
2715
- join19(RulesyncCommand.getSettablePaths().relativeDirPath, "*.md")
2716
- );
2827
+ const basePath = RulesyncCommand.getSettablePaths().relativeDirPath;
2828
+ const rulesyncCommandPaths = await findFilesByGlobs(join19(basePath, "**", "*.md"));
2717
2829
  const rulesyncCommands = await Promise.all(
2718
2830
  rulesyncCommandPaths.map(
2719
- (path3) => RulesyncCommand.fromFile({ relativeFilePath: basename16(path3) })
2831
+ (path3) => RulesyncCommand.fromFile({ relativeFilePath: this.safeRelativePath(basePath, path3) })
2720
2832
  )
2721
2833
  );
2722
2834
  logger.debug(`Successfully loaded ${rulesyncCommands.length} rulesync commands`);
@@ -2731,15 +2843,15 @@ var CommandsProcessor = class extends FeatureProcessor {
2731
2843
  } = {}) {
2732
2844
  const factory = this.getFactory(this.toolTarget);
2733
2845
  const paths = factory.class.getSettablePaths({ global: this.global });
2734
- const commandFilePaths = await findFilesByGlobs(
2735
- join19(this.baseDir, paths.relativeDirPath, `*.${factory.meta.extension}`)
2736
- );
2846
+ const baseDirFull = join19(this.baseDir, paths.relativeDirPath);
2847
+ const globPattern = factory.meta.supportsSubdirectory ? join19(baseDirFull, "**", `*.${factory.meta.extension}`) : join19(baseDirFull, `*.${factory.meta.extension}`);
2848
+ const commandFilePaths = await findFilesByGlobs(globPattern);
2737
2849
  if (forDeletion) {
2738
2850
  const toolCommands2 = commandFilePaths.map(
2739
2851
  (path3) => factory.class.forDeletion({
2740
2852
  baseDir: this.baseDir,
2741
2853
  relativeDirPath: paths.relativeDirPath,
2742
- relativeFilePath: basename16(path3),
2854
+ relativeFilePath: this.safeRelativePath(baseDirFull, path3),
2743
2855
  global: this.global
2744
2856
  })
2745
2857
  ).filter((cmd) => cmd.isDeletable());
@@ -2750,7 +2862,7 @@ var CommandsProcessor = class extends FeatureProcessor {
2750
2862
  commandFilePaths.map(
2751
2863
  (path3) => factory.class.fromFile({
2752
2864
  baseDir: this.baseDir,
2753
- relativeFilePath: basename16(path3),
2865
+ relativeFilePath: this.safeRelativePath(baseDirFull, path3),
2754
2866
  global: this.global
2755
2867
  })
2756
2868
  )
@@ -5337,24 +5449,25 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
5337
5449
  getToml() {
5338
5450
  return this.toml;
5339
5451
  }
5340
- static getSettablePaths({ global } = {}) {
5341
- if (!global) {
5342
- throw new Error("CodexcliMcp only supports global mode. Please pass { global: true }.");
5343
- }
5452
+ static getSettablePaths(_options = {}) {
5344
5453
  return {
5345
5454
  relativeDirPath: ".codex",
5346
5455
  relativeFilePath: "config.toml"
5347
5456
  };
5348
5457
  }
5458
+ /**
5459
+ * config.toml may contain other Codex settings, so it should not be deleted.
5460
+ */
5461
+ isDeletable() {
5462
+ return false;
5463
+ }
5349
5464
  static async fromFile({
5350
5465
  baseDir = process.cwd(),
5351
5466
  validate = true,
5352
5467
  global = false
5353
5468
  }) {
5354
5469
  const paths = this.getSettablePaths({ global });
5355
- const fileContent = await readFileContent(
5356
- join41(baseDir, paths.relativeDirPath, paths.relativeFilePath)
5357
- );
5470
+ const fileContent = await readFileContentOrNull(join41(baseDir, paths.relativeDirPath, paths.relativeFilePath)) ?? smolToml.stringify({});
5358
5471
  return new _CodexcliMcp({
5359
5472
  baseDir,
5360
5473
  relativeDirPath: paths.relativeDirPath,
@@ -6410,7 +6523,7 @@ var toolMcpFactories = /* @__PURE__ */ new Map([
6410
6523
  {
6411
6524
  class: CodexcliMcp,
6412
6525
  meta: {
6413
- supportsProject: false,
6526
+ supportsProject: true,
6414
6527
  supportsGlobal: true,
6415
6528
  supportsEnabledTools: true,
6416
6529
  supportsDisabledTools: true
@@ -6670,8 +6783,8 @@ var McpProcessor = class extends FeatureProcessor {
6670
6783
 
6671
6784
  // src/features/rules/rules-processor.ts
6672
6785
  import { encode } from "@toon-format/toon";
6673
- import { basename as basename24, join as join108, relative as relative4 } from "path";
6674
- import { z as z49 } from "zod/mini";
6786
+ import { basename as basename10, join as join109, relative as relative5 } from "path";
6787
+ import { z as z50 } from "zod/mini";
6675
6788
 
6676
6789
  // src/constants/general.ts
6677
6790
  var SKILL_FILE_NAME = "SKILL.md";
@@ -6687,7 +6800,7 @@ import { z as z20 } from "zod/mini";
6687
6800
  import { join as join52 } from "path";
6688
6801
 
6689
6802
  // src/types/ai-dir.ts
6690
- import path2, { basename as basename17, join as join51, relative as relative3, resolve as resolve4 } from "path";
6803
+ import path2, { basename as basename3, join as join51, relative as relative4, resolve as resolve4 } from "path";
6691
6804
  var AiDir = class {
6692
6805
  /**
6693
6806
  * @example "."
@@ -6747,7 +6860,7 @@ var AiDir = class {
6747
6860
  const fullPath = path2.join(this.baseDir, this.relativeDirPath, this.dirName);
6748
6861
  const resolvedFull = resolve4(fullPath);
6749
6862
  const resolvedBase = resolve4(this.baseDir);
6750
- const rel = relative3(resolvedBase, resolvedFull);
6863
+ const rel = relative4(resolvedBase, resolvedFull);
6751
6864
  if (rel.startsWith("..") || path2.isAbsolute(rel)) {
6752
6865
  throw new Error(
6753
6866
  `Path traversal detected: Final path escapes baseDir. baseDir="${this.baseDir}", relativeDirPath="${this.relativeDirPath}", dirName="${this.dirName}"`
@@ -6784,12 +6897,12 @@ var AiDir = class {
6784
6897
  const dirPath = join51(baseDir, relativeDirPath, dirName);
6785
6898
  const glob = join51(dirPath, "**", "*");
6786
6899
  const filePaths = await findFilesByGlobs(glob, { type: "file" });
6787
- const filteredPaths = filePaths.filter((filePath) => basename17(filePath) !== excludeFileName);
6900
+ const filteredPaths = filePaths.filter((filePath) => basename3(filePath) !== excludeFileName);
6788
6901
  const files = await Promise.all(
6789
6902
  filteredPaths.map(async (filePath) => {
6790
6903
  const fileBuffer = await readFileBuffer(filePath);
6791
6904
  return {
6792
- relativeFilePathToDirPath: relative3(dirPath, filePath),
6905
+ relativeFilePathToDirPath: relative4(dirPath, filePath),
6793
6906
  fileBuffer
6794
6907
  };
6795
6908
  })
@@ -7139,7 +7252,7 @@ var FactorydroidSkill = class _FactorydroidSkill extends SimulatedSkill {
7139
7252
  };
7140
7253
 
7141
7254
  // src/features/skills/skills-processor.ts
7142
- import { basename as basename19, join as join71 } from "path";
7255
+ import { basename as basename5, join as join71 } from "path";
7143
7256
  import { z as z34 } from "zod/mini";
7144
7257
 
7145
7258
  // src/types/dir-feature-processor.ts
@@ -9346,7 +9459,7 @@ var RooSkill = class _RooSkill extends ToolSkill {
9346
9459
  };
9347
9460
 
9348
9461
  // src/features/skills/skills-utils.ts
9349
- import { basename as basename18, join as join70 } from "path";
9462
+ import { basename as basename4, join as join70 } from "path";
9350
9463
  async function getLocalSkillDirNames(baseDir) {
9351
9464
  const skillsDir = join70(baseDir, RULESYNC_SKILLS_RELATIVE_DIR_PATH);
9352
9465
  const names = /* @__PURE__ */ new Set();
@@ -9355,8 +9468,8 @@ async function getLocalSkillDirNames(baseDir) {
9355
9468
  }
9356
9469
  const dirPaths = await findFilesByGlobs(join70(skillsDir, "*"), { type: "dir" });
9357
9470
  for (const dirPath of dirPaths) {
9358
- const name = basename18(dirPath);
9359
- if (name === basename18(RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH)) continue;
9471
+ const name = basename4(dirPath);
9472
+ if (name === basename4(RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH)) continue;
9360
9473
  names.add(name);
9361
9474
  }
9362
9475
  return names;
@@ -9578,7 +9691,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
9578
9691
  let curatedSkills = [];
9579
9692
  if (await directoryExists(curatedDirPath)) {
9580
9693
  const curatedDirPaths = await findFilesByGlobs(join71(curatedDirPath, "*"), { type: "dir" });
9581
- const curatedDirNames = curatedDirPaths.map((path3) => basename19(path3));
9694
+ const curatedDirNames = curatedDirPaths.map((path3) => basename5(path3));
9582
9695
  const nonConflicting = curatedDirNames.filter((name) => {
9583
9696
  if (localSkillNames.has(name)) {
9584
9697
  logger.debug(`Skipping curated skill "${name}": local skill takes precedence.`);
@@ -9613,7 +9726,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
9613
9726
  const paths = factory.class.getSettablePaths({ global: this.global });
9614
9727
  const skillsDirPath = join71(this.baseDir, paths.relativeDirPath);
9615
9728
  const dirPaths = await findFilesByGlobs(join71(skillsDirPath, "*"), { type: "dir" });
9616
- const dirNames = dirPaths.map((path3) => basename19(path3));
9729
+ const dirNames = dirPaths.map((path3) => basename5(path3));
9617
9730
  const toolSkills = await Promise.all(
9618
9731
  dirNames.map(
9619
9732
  (dirName) => factory.class.fromDir({
@@ -9631,7 +9744,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
9631
9744
  const paths = factory.class.getSettablePaths({ global: this.global });
9632
9745
  const skillsDirPath = join71(this.baseDir, paths.relativeDirPath);
9633
9746
  const dirPaths = await findFilesByGlobs(join71(skillsDirPath, "*"), { type: "dir" });
9634
- const dirNames = dirPaths.map((path3) => basename19(path3));
9747
+ const dirNames = dirPaths.map((path3) => basename5(path3));
9635
9748
  const toolSkills = dirNames.map(
9636
9749
  (dirName) => factory.class.forDeletion({
9637
9750
  baseDir: this.baseDir,
@@ -9695,7 +9808,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
9695
9808
  import { join as join73 } from "path";
9696
9809
 
9697
9810
  // src/features/subagents/simulated-subagent.ts
9698
- import { basename as basename20, join as join72 } from "path";
9811
+ import { basename as basename6, join as join72 } from "path";
9699
9812
  import { z as z35 } from "zod/mini";
9700
9813
 
9701
9814
  // src/features/subagents/tool-subagent.ts
@@ -9822,7 +9935,7 @@ var SimulatedSubagent = class extends ToolSubagent {
9822
9935
  return {
9823
9936
  baseDir,
9824
9937
  relativeDirPath: this.getSettablePaths().relativeDirPath,
9825
- relativeFilePath: basename20(relativeFilePath),
9938
+ relativeFilePath: basename6(relativeFilePath),
9826
9939
  frontmatter: result.data,
9827
9940
  body: content.trim(),
9828
9941
  validate
@@ -9870,39 +9983,12 @@ var AgentsmdSubagent = class _AgentsmdSubagent extends SimulatedSubagent {
9870
9983
  }
9871
9984
  };
9872
9985
 
9873
- // src/features/subagents/codexcli-subagent.ts
9874
- import { join as join74 } from "path";
9875
- var CodexCliSubagent = class _CodexCliSubagent extends SimulatedSubagent {
9876
- static getSettablePaths() {
9877
- return {
9878
- relativeDirPath: join74(".codex", "subagents")
9879
- };
9880
- }
9881
- static async fromFile(params) {
9882
- const baseParams = await this.fromFileDefault(params);
9883
- return new _CodexCliSubagent(baseParams);
9884
- }
9885
- static fromRulesyncSubagent(params) {
9886
- const baseParams = this.fromRulesyncSubagentDefault(params);
9887
- return new _CodexCliSubagent(baseParams);
9888
- }
9889
- static isTargetedByRulesyncSubagent(rulesyncSubagent) {
9890
- return this.isTargetedByRulesyncSubagentDefault({
9891
- rulesyncSubagent,
9892
- toolTarget: "codexcli"
9893
- });
9894
- }
9895
- static forDeletion(params) {
9896
- return new _CodexCliSubagent(this.forDeletionDefault(params));
9897
- }
9898
- };
9899
-
9900
9986
  // src/features/subagents/factorydroid-subagent.ts
9901
- import { join as join75 } from "path";
9987
+ import { join as join74 } from "path";
9902
9988
  var FactorydroidSubagent = class _FactorydroidSubagent extends SimulatedSubagent {
9903
9989
  static getSettablePaths(_options) {
9904
9990
  return {
9905
- relativeDirPath: join75(".factory", "droids")
9991
+ relativeDirPath: join74(".factory", "droids")
9906
9992
  };
9907
9993
  }
9908
9994
  static async fromFile(params) {
@@ -9925,11 +10011,11 @@ var FactorydroidSubagent = class _FactorydroidSubagent extends SimulatedSubagent
9925
10011
  };
9926
10012
 
9927
10013
  // src/features/subagents/geminicli-subagent.ts
9928
- import { join as join76 } from "path";
10014
+ import { join as join75 } from "path";
9929
10015
  var GeminiCliSubagent = class _GeminiCliSubagent extends SimulatedSubagent {
9930
10016
  static getSettablePaths() {
9931
10017
  return {
9932
- relativeDirPath: join76(".gemini", "subagents")
10018
+ relativeDirPath: join75(".gemini", "subagents")
9933
10019
  };
9934
10020
  }
9935
10021
  static async fromFile(params) {
@@ -9952,11 +10038,11 @@ var GeminiCliSubagent = class _GeminiCliSubagent extends SimulatedSubagent {
9952
10038
  };
9953
10039
 
9954
10040
  // src/features/subagents/roo-subagent.ts
9955
- import { join as join77 } from "path";
10041
+ import { join as join76 } from "path";
9956
10042
  var RooSubagent = class _RooSubagent extends SimulatedSubagent {
9957
10043
  static getSettablePaths() {
9958
10044
  return {
9959
- relativeDirPath: join77(".roo", "subagents")
10045
+ relativeDirPath: join76(".roo", "subagents")
9960
10046
  };
9961
10047
  }
9962
10048
  static async fromFile(params) {
@@ -9979,15 +10065,15 @@ var RooSubagent = class _RooSubagent extends SimulatedSubagent {
9979
10065
  };
9980
10066
 
9981
10067
  // src/features/subagents/subagents-processor.ts
9982
- import { basename as basename23, join as join84 } from "path";
9983
- import { z as z42 } from "zod/mini";
10068
+ import { basename as basename9, join as join84 } from "path";
10069
+ import { z as z43 } from "zod/mini";
9984
10070
 
9985
10071
  // src/features/subagents/claudecode-subagent.ts
9986
- import { join as join79 } from "path";
10072
+ import { join as join78 } from "path";
9987
10073
  import { z as z37 } from "zod/mini";
9988
10074
 
9989
10075
  // src/features/subagents/rulesync-subagent.ts
9990
- import { basename as basename21, join as join78 } from "path";
10076
+ import { basename as basename7, join as join77 } from "path";
9991
10077
  import { z as z36 } from "zod/mini";
9992
10078
  var RulesyncSubagentFrontmatterSchema = z36.looseObject({
9993
10079
  targets: z36._default(RulesyncTargetsSchema, ["*"]),
@@ -10001,7 +10087,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
10001
10087
  const parseResult = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
10002
10088
  if (!parseResult.success && rest.validate !== false) {
10003
10089
  throw new Error(
10004
- `Invalid frontmatter in ${join78(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(parseResult.error)}`
10090
+ `Invalid frontmatter in ${join77(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(parseResult.error)}`
10005
10091
  );
10006
10092
  }
10007
10093
  const parsedFrontmatter = parseResult.success ? { ...frontmatter, ...parseResult.data } : { ...frontmatter, targets: frontmatter?.targets ?? ["*"] };
@@ -10034,7 +10120,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
10034
10120
  return {
10035
10121
  success: false,
10036
10122
  error: new Error(
10037
- `Invalid frontmatter in ${join78(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10123
+ `Invalid frontmatter in ${join77(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10038
10124
  )
10039
10125
  };
10040
10126
  }
@@ -10043,14 +10129,14 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
10043
10129
  relativeFilePath
10044
10130
  }) {
10045
10131
  const fileContent = await readFileContent(
10046
- join78(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, relativeFilePath)
10132
+ join77(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, relativeFilePath)
10047
10133
  );
10048
10134
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
10049
10135
  const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
10050
10136
  if (!result.success) {
10051
10137
  throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${formatError(result.error)}`);
10052
10138
  }
10053
- const filename = basename21(relativeFilePath);
10139
+ const filename = basename7(relativeFilePath);
10054
10140
  return new _RulesyncSubagent({
10055
10141
  baseDir: process.cwd(),
10056
10142
  relativeDirPath: this.getSettablePaths().relativeDirPath,
@@ -10078,7 +10164,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
10078
10164
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
10079
10165
  if (!result.success) {
10080
10166
  throw new Error(
10081
- `Invalid frontmatter in ${join79(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
10167
+ `Invalid frontmatter in ${join78(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
10082
10168
  );
10083
10169
  }
10084
10170
  }
@@ -10090,7 +10176,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
10090
10176
  }
10091
10177
  static getSettablePaths(_options = {}) {
10092
10178
  return {
10093
- relativeDirPath: join79(".claude", "agents")
10179
+ relativeDirPath: join78(".claude", "agents")
10094
10180
  };
10095
10181
  }
10096
10182
  getFrontmatter() {
@@ -10166,7 +10252,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
10166
10252
  return {
10167
10253
  success: false,
10168
10254
  error: new Error(
10169
- `Invalid frontmatter in ${join79(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10255
+ `Invalid frontmatter in ${join78(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10170
10256
  )
10171
10257
  };
10172
10258
  }
@@ -10184,7 +10270,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
10184
10270
  global = false
10185
10271
  }) {
10186
10272
  const paths = this.getSettablePaths({ global });
10187
- const filePath = join79(baseDir, paths.relativeDirPath, relativeFilePath);
10273
+ const filePath = join78(baseDir, paths.relativeDirPath, relativeFilePath);
10188
10274
  const fileContent = await readFileContent(filePath);
10189
10275
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
10190
10276
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -10218,14 +10304,158 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
10218
10304
  }
10219
10305
  };
10220
10306
 
10307
+ // src/features/subagents/codexcli-subagent.ts
10308
+ import { join as join79 } from "path";
10309
+ import * as smolToml2 from "smol-toml";
10310
+ import { z as z38 } from "zod/mini";
10311
+ var CodexCliSubagentTomlSchema = z38.looseObject({
10312
+ name: z38.string(),
10313
+ description: z38.optional(z38.string()),
10314
+ developer_instructions: z38.optional(z38.string()),
10315
+ model: z38.optional(z38.string()),
10316
+ model_reasoning_effort: z38.optional(z38.string()),
10317
+ sandbox_mode: z38.optional(z38.string())
10318
+ });
10319
+ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
10320
+ body;
10321
+ constructor({ body, ...rest }) {
10322
+ super({
10323
+ ...rest
10324
+ });
10325
+ this.body = body;
10326
+ }
10327
+ static getSettablePaths(_options = {}) {
10328
+ return {
10329
+ relativeDirPath: join79(".codex", "agents")
10330
+ };
10331
+ }
10332
+ getBody() {
10333
+ return this.body;
10334
+ }
10335
+ toRulesyncSubagent() {
10336
+ let parsed;
10337
+ try {
10338
+ parsed = CodexCliSubagentTomlSchema.parse(smolToml2.parse(this.body));
10339
+ } catch (error) {
10340
+ throw new Error(
10341
+ `Failed to parse TOML in ${join79(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${error instanceof Error ? error.message : String(error)}`,
10342
+ { cause: error }
10343
+ );
10344
+ }
10345
+ const { name, description, developer_instructions, ...restFields } = parsed;
10346
+ const codexcliSection = {
10347
+ ...restFields
10348
+ };
10349
+ const rulesyncFrontmatter = {
10350
+ targets: ["codexcli"],
10351
+ name,
10352
+ description: description ?? "",
10353
+ // Only include codexcli section if there are fields
10354
+ ...Object.keys(codexcliSection).length > 0 && { codexcli: codexcliSection }
10355
+ };
10356
+ return new RulesyncSubagent({
10357
+ baseDir: ".",
10358
+ frontmatter: rulesyncFrontmatter,
10359
+ body: developer_instructions ?? "",
10360
+ relativeDirPath: RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH,
10361
+ relativeFilePath: this.getRelativeFilePath().replace(/\.toml$/, ".md"),
10362
+ validate: true
10363
+ });
10364
+ }
10365
+ static fromRulesyncSubagent({
10366
+ baseDir = process.cwd(),
10367
+ rulesyncSubagent,
10368
+ validate = true,
10369
+ global = false
10370
+ }) {
10371
+ const frontmatter = rulesyncSubagent.getFrontmatter();
10372
+ const rawSection = frontmatter.codexcli ?? {};
10373
+ const {
10374
+ name: _n,
10375
+ description: _d,
10376
+ developer_instructions: _di,
10377
+ ...codexcliSection
10378
+ } = rawSection;
10379
+ const tomlObj = {
10380
+ name: frontmatter.name,
10381
+ ...frontmatter.description ? { description: frontmatter.description } : {},
10382
+ ...rulesyncSubagent.getBody() ? { developer_instructions: rulesyncSubagent.getBody() } : {},
10383
+ ...codexcliSection
10384
+ };
10385
+ const body = smolToml2.stringify(tomlObj);
10386
+ const paths = this.getSettablePaths({ global });
10387
+ const relativeFilePath = rulesyncSubagent.getRelativeFilePath().replace(/\.md$/, ".toml");
10388
+ return new _CodexCliSubagent({
10389
+ baseDir,
10390
+ body,
10391
+ relativeDirPath: paths.relativeDirPath,
10392
+ relativeFilePath,
10393
+ fileContent: body,
10394
+ validate,
10395
+ global
10396
+ });
10397
+ }
10398
+ validate() {
10399
+ try {
10400
+ const parsed = smolToml2.parse(this.body);
10401
+ CodexCliSubagentTomlSchema.parse(parsed);
10402
+ return { success: true, error: null };
10403
+ } catch (error) {
10404
+ return {
10405
+ success: false,
10406
+ error: error instanceof Error ? error : new Error(String(error))
10407
+ };
10408
+ }
10409
+ }
10410
+ static isTargetedByRulesyncSubagent(rulesyncSubagent) {
10411
+ return this.isTargetedByRulesyncSubagentDefault({
10412
+ rulesyncSubagent,
10413
+ toolTarget: "codexcli"
10414
+ });
10415
+ }
10416
+ static async fromFile({
10417
+ baseDir = process.cwd(),
10418
+ relativeFilePath,
10419
+ validate = true,
10420
+ global = false
10421
+ }) {
10422
+ const paths = this.getSettablePaths({ global });
10423
+ const filePath = join79(baseDir, paths.relativeDirPath, relativeFilePath);
10424
+ const fileContent = await readFileContent(filePath);
10425
+ return new _CodexCliSubagent({
10426
+ baseDir,
10427
+ relativeDirPath: paths.relativeDirPath,
10428
+ relativeFilePath,
10429
+ body: fileContent.trim(),
10430
+ fileContent,
10431
+ validate,
10432
+ global
10433
+ });
10434
+ }
10435
+ static forDeletion({
10436
+ baseDir = process.cwd(),
10437
+ relativeDirPath,
10438
+ relativeFilePath
10439
+ }) {
10440
+ return new _CodexCliSubagent({
10441
+ baseDir,
10442
+ relativeDirPath,
10443
+ relativeFilePath,
10444
+ body: "",
10445
+ fileContent: "",
10446
+ validate: false
10447
+ });
10448
+ }
10449
+ };
10450
+
10221
10451
  // src/features/subagents/copilot-subagent.ts
10222
10452
  import { join as join80 } from "path";
10223
- import { z as z38 } from "zod/mini";
10453
+ import { z as z39 } from "zod/mini";
10224
10454
  var REQUIRED_TOOL = "agent/runSubagent";
10225
- var CopilotSubagentFrontmatterSchema = z38.looseObject({
10226
- name: z38.string(),
10227
- description: z38.string(),
10228
- tools: z38.optional(z38.union([z38.string(), z38.array(z38.string())]))
10455
+ var CopilotSubagentFrontmatterSchema = z39.looseObject({
10456
+ name: z39.string(),
10457
+ description: z39.string(),
10458
+ tools: z39.optional(z39.union([z39.string(), z39.array(z39.string())]))
10229
10459
  });
10230
10460
  var normalizeTools = (tools) => {
10231
10461
  if (!tools) {
@@ -10386,10 +10616,10 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
10386
10616
 
10387
10617
  // src/features/subagents/cursor-subagent.ts
10388
10618
  import { join as join81 } from "path";
10389
- import { z as z39 } from "zod/mini";
10390
- var CursorSubagentFrontmatterSchema = z39.looseObject({
10391
- name: z39.string(),
10392
- description: z39.string()
10619
+ import { z as z40 } from "zod/mini";
10620
+ var CursorSubagentFrontmatterSchema = z40.looseObject({
10621
+ name: z40.string(),
10622
+ description: z40.string()
10393
10623
  });
10394
10624
  var CursorSubagent = class _CursorSubagent extends ToolSubagent {
10395
10625
  frontmatter;
@@ -10533,22 +10763,22 @@ var CursorSubagent = class _CursorSubagent extends ToolSubagent {
10533
10763
 
10534
10764
  // src/features/subagents/kiro-subagent.ts
10535
10765
  import { join as join82 } from "path";
10536
- import { z as z40 } from "zod/mini";
10537
- var KiroCliSubagentJsonSchema = z40.looseObject({
10538
- name: z40.string(),
10539
- description: z40.optional(z40.nullable(z40.string())),
10540
- prompt: z40.optional(z40.nullable(z40.string())),
10541
- tools: z40.optional(z40.nullable(z40.array(z40.string()))),
10542
- toolAliases: z40.optional(z40.nullable(z40.record(z40.string(), z40.string()))),
10543
- toolSettings: z40.optional(z40.nullable(z40.unknown())),
10544
- toolSchema: z40.optional(z40.nullable(z40.unknown())),
10545
- hooks: z40.optional(z40.nullable(z40.record(z40.string(), z40.array(z40.unknown())))),
10546
- model: z40.optional(z40.nullable(z40.string())),
10547
- mcpServers: z40.optional(z40.nullable(z40.record(z40.string(), z40.unknown()))),
10548
- useLegacyMcpJson: z40.optional(z40.nullable(z40.boolean())),
10549
- resources: z40.optional(z40.nullable(z40.array(z40.string()))),
10550
- allowedTools: z40.optional(z40.nullable(z40.array(z40.string()))),
10551
- includeMcpJson: z40.optional(z40.nullable(z40.boolean()))
10766
+ import { z as z41 } from "zod/mini";
10767
+ var KiroCliSubagentJsonSchema = z41.looseObject({
10768
+ name: z41.string(),
10769
+ description: z41.optional(z41.nullable(z41.string())),
10770
+ prompt: z41.optional(z41.nullable(z41.string())),
10771
+ tools: z41.optional(z41.nullable(z41.array(z41.string()))),
10772
+ toolAliases: z41.optional(z41.nullable(z41.record(z41.string(), z41.string()))),
10773
+ toolSettings: z41.optional(z41.nullable(z41.unknown())),
10774
+ toolSchema: z41.optional(z41.nullable(z41.unknown())),
10775
+ hooks: z41.optional(z41.nullable(z41.record(z41.string(), z41.array(z41.unknown())))),
10776
+ model: z41.optional(z41.nullable(z41.string())),
10777
+ mcpServers: z41.optional(z41.nullable(z41.record(z41.string(), z41.unknown()))),
10778
+ useLegacyMcpJson: z41.optional(z41.nullable(z41.boolean())),
10779
+ resources: z41.optional(z41.nullable(z41.array(z41.string()))),
10780
+ allowedTools: z41.optional(z41.nullable(z41.array(z41.string()))),
10781
+ includeMcpJson: z41.optional(z41.nullable(z41.boolean()))
10552
10782
  });
10553
10783
  var KiroSubagent = class _KiroSubagent extends ToolSubagent {
10554
10784
  body;
@@ -10669,12 +10899,12 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
10669
10899
  };
10670
10900
 
10671
10901
  // src/features/subagents/opencode-subagent.ts
10672
- import { basename as basename22, join as join83 } from "path";
10673
- import { z as z41 } from "zod/mini";
10674
- var OpenCodeSubagentFrontmatterSchema = z41.looseObject({
10675
- description: z41.string(),
10676
- mode: z41._default(z41.string(), "subagent"),
10677
- name: z41.optional(z41.string())
10902
+ import { basename as basename8, join as join83 } from "path";
10903
+ import { z as z42 } from "zod/mini";
10904
+ var OpenCodeSubagentFrontmatterSchema = z42.looseObject({
10905
+ description: z42.string(),
10906
+ mode: z42._default(z42.string(), "subagent"),
10907
+ name: z42.optional(z42.string())
10678
10908
  });
10679
10909
  var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
10680
10910
  frontmatter;
@@ -10711,7 +10941,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
10711
10941
  const { description, mode, name, ...opencodeSection } = this.frontmatter;
10712
10942
  const rulesyncFrontmatter = {
10713
10943
  targets: ["*"],
10714
- name: name ?? basename22(this.getRelativeFilePath(), ".md"),
10944
+ name: name ?? basename8(this.getRelativeFilePath(), ".md"),
10715
10945
  description,
10716
10946
  opencode: { mode, ...opencodeSection }
10717
10947
  };
@@ -10830,7 +11060,7 @@ var subagentsProcessorToolTargetTuple = [
10830
11060
  "opencode",
10831
11061
  "roo"
10832
11062
  ];
10833
- var SubagentsProcessorToolTargetSchema = z42.enum(subagentsProcessorToolTargetTuple);
11063
+ var SubagentsProcessorToolTargetSchema = z43.enum(subagentsProcessorToolTargetTuple);
10834
11064
  var toolSubagentFactories = /* @__PURE__ */ new Map([
10835
11065
  [
10836
11066
  "agentsmd",
@@ -10857,7 +11087,7 @@ var toolSubagentFactories = /* @__PURE__ */ new Map([
10857
11087
  "codexcli",
10858
11088
  {
10859
11089
  class: CodexCliSubagent,
10860
- meta: { supportsSimulated: true, supportsGlobal: false, filePattern: "*.md" }
11090
+ meta: { supportsSimulated: false, supportsGlobal: false, filePattern: "*.toml" }
10861
11091
  }
10862
11092
  ],
10863
11093
  [
@@ -11044,7 +11274,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
11044
11274
  (path3) => factory.class.forDeletion({
11045
11275
  baseDir: this.baseDir,
11046
11276
  relativeDirPath: paths.relativeDirPath,
11047
- relativeFilePath: basename23(path3),
11277
+ relativeFilePath: basename9(path3),
11048
11278
  global: this.global
11049
11279
  })
11050
11280
  ).filter((subagent) => subagent.isDeletable());
@@ -11057,7 +11287,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
11057
11287
  subagentFilePaths.map(
11058
11288
  (path3) => factory.class.fromFile({
11059
11289
  baseDir: this.baseDir,
11060
- relativeFilePath: basename23(path3),
11290
+ relativeFilePath: basename9(path3),
11061
11291
  global: this.global
11062
11292
  })
11063
11293
  )
@@ -11109,42 +11339,42 @@ import { join as join86 } from "path";
11109
11339
 
11110
11340
  // src/features/rules/rulesync-rule.ts
11111
11341
  import { join as join85 } from "path";
11112
- import { z as z43 } from "zod/mini";
11113
- var RulesyncRuleFrontmatterSchema = z43.object({
11114
- root: z43.optional(z43.boolean()),
11115
- localRoot: z43.optional(z43.boolean()),
11116
- targets: z43._default(RulesyncTargetsSchema, ["*"]),
11117
- description: z43.optional(z43.string()),
11118
- globs: z43.optional(z43.array(z43.string())),
11119
- agentsmd: z43.optional(
11120
- z43.object({
11342
+ import { z as z44 } from "zod/mini";
11343
+ var RulesyncRuleFrontmatterSchema = z44.object({
11344
+ root: z44.optional(z44.boolean()),
11345
+ localRoot: z44.optional(z44.boolean()),
11346
+ targets: z44._default(RulesyncTargetsSchema, ["*"]),
11347
+ description: z44.optional(z44.string()),
11348
+ globs: z44.optional(z44.array(z44.string())),
11349
+ agentsmd: z44.optional(
11350
+ z44.object({
11121
11351
  // @example "path/to/subproject"
11122
- subprojectPath: z43.optional(z43.string())
11352
+ subprojectPath: z44.optional(z44.string())
11123
11353
  })
11124
11354
  ),
11125
- claudecode: z43.optional(
11126
- z43.object({
11355
+ claudecode: z44.optional(
11356
+ z44.object({
11127
11357
  // Glob patterns for conditional rules (takes precedence over globs)
11128
11358
  // @example ["src/**/*.ts", "tests/**/*.test.ts"]
11129
- paths: z43.optional(z43.array(z43.string()))
11359
+ paths: z44.optional(z44.array(z44.string()))
11130
11360
  })
11131
11361
  ),
11132
- cursor: z43.optional(
11133
- z43.object({
11134
- alwaysApply: z43.optional(z43.boolean()),
11135
- description: z43.optional(z43.string()),
11136
- globs: z43.optional(z43.array(z43.string()))
11362
+ cursor: z44.optional(
11363
+ z44.object({
11364
+ alwaysApply: z44.optional(z44.boolean()),
11365
+ description: z44.optional(z44.string()),
11366
+ globs: z44.optional(z44.array(z44.string()))
11137
11367
  })
11138
11368
  ),
11139
- copilot: z43.optional(
11140
- z43.object({
11141
- excludeAgent: z43.optional(z43.union([z43.literal("code-review"), z43.literal("coding-agent")]))
11369
+ copilot: z44.optional(
11370
+ z44.object({
11371
+ excludeAgent: z44.optional(z44.union([z44.literal("code-review"), z44.literal("coding-agent")]))
11142
11372
  })
11143
11373
  ),
11144
- antigravity: z43.optional(
11145
- z43.looseObject({
11146
- trigger: z43.optional(z43.string()),
11147
- globs: z43.optional(z43.array(z43.string()))
11374
+ antigravity: z44.optional(
11375
+ z44.looseObject({
11376
+ trigger: z44.optional(z44.string()),
11377
+ globs: z44.optional(z44.array(z44.string()))
11148
11378
  })
11149
11379
  )
11150
11380
  });
@@ -11447,20 +11677,20 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
11447
11677
 
11448
11678
  // src/features/rules/antigravity-rule.ts
11449
11679
  import { join as join88 } from "path";
11450
- import { z as z44 } from "zod/mini";
11451
- var AntigravityRuleFrontmatterSchema = z44.looseObject({
11452
- trigger: z44.optional(
11453
- z44.union([
11454
- z44.literal("always_on"),
11455
- z44.literal("glob"),
11456
- z44.literal("manual"),
11457
- z44.literal("model_decision"),
11458
- z44.string()
11680
+ import { z as z45 } from "zod/mini";
11681
+ var AntigravityRuleFrontmatterSchema = z45.looseObject({
11682
+ trigger: z45.optional(
11683
+ z45.union([
11684
+ z45.literal("always_on"),
11685
+ z45.literal("glob"),
11686
+ z45.literal("manual"),
11687
+ z45.literal("model_decision"),
11688
+ z45.string()
11459
11689
  // accepts any string for forward compatibility
11460
11690
  ])
11461
11691
  ),
11462
- globs: z44.optional(z44.string()),
11463
- description: z44.optional(z44.string())
11692
+ globs: z45.optional(z45.string()),
11693
+ description: z45.optional(z45.string())
11464
11694
  });
11465
11695
  function parseGlobsString(globs) {
11466
11696
  if (!globs) {
@@ -12039,9 +12269,9 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
12039
12269
 
12040
12270
  // src/features/rules/claudecode-rule.ts
12041
12271
  import { join as join92 } from "path";
12042
- import { z as z45 } from "zod/mini";
12043
- var ClaudecodeRuleFrontmatterSchema = z45.object({
12044
- paths: z45.optional(z45.array(z45.string()))
12272
+ import { z as z46 } from "zod/mini";
12273
+ var ClaudecodeRuleFrontmatterSchema = z46.object({
12274
+ paths: z46.optional(z46.array(z46.string()))
12045
12275
  });
12046
12276
  var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
12047
12277
  frontmatter;
@@ -12250,9 +12480,9 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
12250
12480
 
12251
12481
  // src/features/rules/cline-rule.ts
12252
12482
  import { join as join93 } from "path";
12253
- import { z as z46 } from "zod/mini";
12254
- var ClineRuleFrontmatterSchema = z46.object({
12255
- description: z46.string()
12483
+ import { z as z47 } from "zod/mini";
12484
+ var ClineRuleFrontmatterSchema = z47.object({
12485
+ description: z47.string()
12256
12486
  });
12257
12487
  var ClineRule = class _ClineRule extends ToolRule {
12258
12488
  static getSettablePaths(_options = {}) {
@@ -12431,11 +12661,11 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
12431
12661
 
12432
12662
  // src/features/rules/copilot-rule.ts
12433
12663
  import { join as join95 } from "path";
12434
- import { z as z47 } from "zod/mini";
12435
- var CopilotRuleFrontmatterSchema = z47.object({
12436
- description: z47.optional(z47.string()),
12437
- applyTo: z47.optional(z47.string()),
12438
- excludeAgent: z47.optional(z47.union([z47.literal("code-review"), z47.literal("coding-agent")]))
12664
+ import { z as z48 } from "zod/mini";
12665
+ var CopilotRuleFrontmatterSchema = z48.object({
12666
+ description: z48.optional(z48.string()),
12667
+ applyTo: z48.optional(z48.string()),
12668
+ excludeAgent: z48.optional(z48.union([z48.literal("code-review"), z48.literal("coding-agent")]))
12439
12669
  });
12440
12670
  var CopilotRule = class _CopilotRule extends ToolRule {
12441
12671
  frontmatter;
@@ -12638,11 +12868,11 @@ var CopilotRule = class _CopilotRule extends ToolRule {
12638
12868
 
12639
12869
  // src/features/rules/cursor-rule.ts
12640
12870
  import { join as join96 } from "path";
12641
- import { z as z48 } from "zod/mini";
12642
- var CursorRuleFrontmatterSchema = z48.object({
12643
- description: z48.optional(z48.string()),
12644
- globs: z48.optional(z48.string()),
12645
- alwaysApply: z48.optional(z48.boolean())
12871
+ import { z as z49 } from "zod/mini";
12872
+ var CursorRuleFrontmatterSchema = z49.object({
12873
+ description: z49.optional(z49.string()),
12874
+ globs: z49.optional(z49.string()),
12875
+ alwaysApply: z49.optional(z49.boolean())
12646
12876
  });
12647
12877
  var CursorRule = class _CursorRule extends ToolRule {
12648
12878
  frontmatter;
@@ -13061,8 +13291,117 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
13061
13291
  }
13062
13292
  };
13063
13293
 
13064
- // src/features/rules/junie-rule.ts
13294
+ // src/features/rules/goose-rule.ts
13065
13295
  import { join as join99 } from "path";
13296
+ var GooseRule = class _GooseRule extends ToolRule {
13297
+ static getSettablePaths({
13298
+ global,
13299
+ excludeToolDir
13300
+ } = {}) {
13301
+ if (global) {
13302
+ return {
13303
+ root: {
13304
+ relativeDirPath: ".",
13305
+ relativeFilePath: ".goosehints"
13306
+ }
13307
+ };
13308
+ }
13309
+ return {
13310
+ root: {
13311
+ relativeDirPath: ".",
13312
+ relativeFilePath: ".goosehints"
13313
+ },
13314
+ nonRoot: {
13315
+ relativeDirPath: buildToolPath(".goose", "memories", excludeToolDir)
13316
+ }
13317
+ };
13318
+ }
13319
+ static async fromFile({
13320
+ baseDir = process.cwd(),
13321
+ relativeFilePath,
13322
+ validate = true,
13323
+ global = false
13324
+ }) {
13325
+ const paths = this.getSettablePaths({ global });
13326
+ const isRoot = relativeFilePath === paths.root.relativeFilePath;
13327
+ if (isRoot) {
13328
+ const relativePath2 = paths.root.relativeFilePath;
13329
+ const fileContent2 = await readFileContent(
13330
+ join99(baseDir, paths.root.relativeDirPath, relativePath2)
13331
+ );
13332
+ return new _GooseRule({
13333
+ baseDir,
13334
+ relativeDirPath: paths.root.relativeDirPath,
13335
+ relativeFilePath: paths.root.relativeFilePath,
13336
+ fileContent: fileContent2,
13337
+ validate,
13338
+ root: true
13339
+ });
13340
+ }
13341
+ if (!paths.nonRoot) {
13342
+ throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
13343
+ }
13344
+ const relativePath = join99(paths.nonRoot.relativeDirPath, relativeFilePath);
13345
+ const fileContent = await readFileContent(join99(baseDir, relativePath));
13346
+ return new _GooseRule({
13347
+ baseDir,
13348
+ relativeDirPath: paths.nonRoot.relativeDirPath,
13349
+ relativeFilePath,
13350
+ fileContent,
13351
+ validate,
13352
+ root: false
13353
+ });
13354
+ }
13355
+ static fromRulesyncRule({
13356
+ baseDir = process.cwd(),
13357
+ rulesyncRule,
13358
+ validate = true,
13359
+ global = false
13360
+ }) {
13361
+ const paths = this.getSettablePaths({ global });
13362
+ return new _GooseRule(
13363
+ this.buildToolRuleParamsDefault({
13364
+ baseDir,
13365
+ rulesyncRule,
13366
+ validate,
13367
+ rootPath: paths.root,
13368
+ nonRootPath: paths.nonRoot
13369
+ })
13370
+ );
13371
+ }
13372
+ toRulesyncRule() {
13373
+ return this.toRulesyncRuleDefault();
13374
+ }
13375
+ validate() {
13376
+ return { success: true, error: null };
13377
+ }
13378
+ static forDeletion({
13379
+ baseDir = process.cwd(),
13380
+ relativeDirPath,
13381
+ relativeFilePath,
13382
+ global = false
13383
+ }) {
13384
+ const paths = this.getSettablePaths({ global });
13385
+ const isRoot = relativeFilePath === paths.root.relativeFilePath;
13386
+ return new _GooseRule({
13387
+ baseDir,
13388
+ relativeDirPath,
13389
+ relativeFilePath,
13390
+ fileContent: "",
13391
+ validate: false,
13392
+ root: isRoot
13393
+ });
13394
+ }
13395
+ static isTargetedByRulesyncRule(rulesyncRule) {
13396
+ return this.isTargetedByRulesyncRuleDefault({
13397
+ rulesyncRule,
13398
+ toolTarget: "goose"
13399
+ });
13400
+ }
13401
+ };
13402
+
13403
+ // src/features/rules/junie-rule.ts
13404
+ import { join as join100 } from "path";
13066
13405
  var JunieRule = class _JunieRule extends ToolRule {
13067
13406
  static getSettablePaths(_options = {}) {
13068
13407
  return {
@@ -13081,8 +13420,8 @@ var JunieRule = class _JunieRule extends ToolRule {
13081
13420
  validate = true
13082
13421
  }) {
13083
13422
  const isRoot = relativeFilePath === "guidelines.md";
13084
- const relativePath = isRoot ? "guidelines.md" : join99(".junie", "memories", relativeFilePath);
13085
- const fileContent = await readFileContent(join99(baseDir, relativePath));
13423
+ const relativePath = isRoot ? "guidelines.md" : join100(".junie", "memories", relativeFilePath);
13424
+ const fileContent = await readFileContent(join100(baseDir, relativePath));
13086
13425
  return new _JunieRule({
13087
13426
  baseDir,
13088
13427
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -13137,7 +13476,7 @@ var JunieRule = class _JunieRule extends ToolRule {
13137
13476
  };
13138
13477
 
13139
13478
  // src/features/rules/kilo-rule.ts
13140
- import { join as join100 } from "path";
13479
+ import { join as join101 } from "path";
13141
13480
  var KiloRule = class _KiloRule extends ToolRule {
13142
13481
  static getSettablePaths(_options = {}) {
13143
13482
  return {
@@ -13152,7 +13491,7 @@ var KiloRule = class _KiloRule extends ToolRule {
13152
13491
  validate = true
13153
13492
  }) {
13154
13493
  const fileContent = await readFileContent(
13155
- join100(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
13494
+ join101(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
13156
13495
  );
13157
13496
  return new _KiloRule({
13158
13497
  baseDir,
@@ -13204,7 +13543,7 @@ var KiloRule = class _KiloRule extends ToolRule {
13204
13543
  };
13205
13544
 
13206
13545
  // src/features/rules/kiro-rule.ts
13207
- import { join as join101 } from "path";
13546
+ import { join as join102 } from "path";
13208
13547
  var KiroRule = class _KiroRule extends ToolRule {
13209
13548
  static getSettablePaths(_options = {}) {
13210
13549
  return {
@@ -13219,7 +13558,7 @@ var KiroRule = class _KiroRule extends ToolRule {
13219
13558
  validate = true
13220
13559
  }) {
13221
13560
  const fileContent = await readFileContent(
13222
- join101(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
13561
+ join102(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
13223
13562
  );
13224
13563
  return new _KiroRule({
13225
13564
  baseDir,
@@ -13273,7 +13612,7 @@ var KiroRule = class _KiroRule extends ToolRule {
13273
13612
  };
13274
13613
 
13275
13614
  // src/features/rules/opencode-rule.ts
13276
- import { join as join102 } from "path";
13615
+ import { join as join103 } from "path";
13277
13616
  var OpenCodeRule = class _OpenCodeRule extends ToolRule {
13278
13617
  static getSettablePaths({
13279
13618
  global,
@@ -13308,7 +13647,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
13308
13647
  if (isRoot) {
13309
13648
  const relativePath2 = paths.root.relativeFilePath;
13310
13649
  const fileContent2 = await readFileContent(
13311
- join102(baseDir, paths.root.relativeDirPath, relativePath2)
13650
+ join103(baseDir, paths.root.relativeDirPath, relativePath2)
13312
13651
  );
13313
13652
  return new _OpenCodeRule({
13314
13653
  baseDir,
@@ -13322,8 +13661,8 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
13322
13661
  if (!paths.nonRoot) {
13323
13662
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
13324
13663
  }
13325
- const relativePath = join102(paths.nonRoot.relativeDirPath, relativeFilePath);
13326
- const fileContent = await readFileContent(join102(baseDir, relativePath));
13664
+ const relativePath = join103(paths.nonRoot.relativeDirPath, relativeFilePath);
13665
+ const fileContent = await readFileContent(join103(baseDir, relativePath));
13327
13666
  return new _OpenCodeRule({
13328
13667
  baseDir,
13329
13668
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -13382,7 +13721,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
13382
13721
  };
13383
13722
 
13384
13723
  // src/features/rules/qwencode-rule.ts
13385
- import { join as join103 } from "path";
13724
+ import { join as join104 } from "path";
13386
13725
  var QwencodeRule = class _QwencodeRule extends ToolRule {
13387
13726
  static getSettablePaths(_options = {}) {
13388
13727
  return {
@@ -13401,8 +13740,8 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
13401
13740
  validate = true
13402
13741
  }) {
13403
13742
  const isRoot = relativeFilePath === "QWEN.md";
13404
- const relativePath = isRoot ? "QWEN.md" : join103(".qwen", "memories", relativeFilePath);
13405
- const fileContent = await readFileContent(join103(baseDir, relativePath));
13743
+ const relativePath = isRoot ? "QWEN.md" : join104(".qwen", "memories", relativeFilePath);
13744
+ const fileContent = await readFileContent(join104(baseDir, relativePath));
13406
13745
  return new _QwencodeRule({
13407
13746
  baseDir,
13408
13747
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -13454,7 +13793,7 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
13454
13793
  };
13455
13794
 
13456
13795
  // src/features/rules/replit-rule.ts
13457
- import { join as join104 } from "path";
13796
+ import { join as join105 } from "path";
13458
13797
  var ReplitRule = class _ReplitRule extends ToolRule {
13459
13798
  static getSettablePaths(_options = {}) {
13460
13799
  return {
@@ -13476,7 +13815,7 @@ var ReplitRule = class _ReplitRule extends ToolRule {
13476
13815
  }
13477
13816
  const relativePath = paths.root.relativeFilePath;
13478
13817
  const fileContent = await readFileContent(
13479
- join104(baseDir, paths.root.relativeDirPath, relativePath)
13818
+ join105(baseDir, paths.root.relativeDirPath, relativePath)
13480
13819
  );
13481
13820
  return new _ReplitRule({
13482
13821
  baseDir,
@@ -13542,7 +13881,7 @@ var ReplitRule = class _ReplitRule extends ToolRule {
13542
13881
  };
13543
13882
 
13544
13883
  // src/features/rules/roo-rule.ts
13545
- import { join as join105 } from "path";
13884
+ import { join as join106 } from "path";
13546
13885
  var RooRule = class _RooRule extends ToolRule {
13547
13886
  static getSettablePaths(_options = {}) {
13548
13887
  return {
@@ -13557,7 +13896,7 @@ var RooRule = class _RooRule extends ToolRule {
13557
13896
  validate = true
13558
13897
  }) {
13559
13898
  const fileContent = await readFileContent(
13560
- join105(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
13899
+ join106(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
13561
13900
  );
13562
13901
  return new _RooRule({
13563
13902
  baseDir,
@@ -13626,7 +13965,7 @@ var RooRule = class _RooRule extends ToolRule {
13626
13965
  };
13627
13966
 
13628
13967
  // src/features/rules/warp-rule.ts
13629
- import { join as join106 } from "path";
13968
+ import { join as join107 } from "path";
13630
13969
  var WarpRule = class _WarpRule extends ToolRule {
13631
13970
  constructor({ fileContent, root, ...rest }) {
13632
13971
  super({
@@ -13652,8 +13991,8 @@ var WarpRule = class _WarpRule extends ToolRule {
13652
13991
  validate = true
13653
13992
  }) {
13654
13993
  const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
13655
- const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join106(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
13656
- const fileContent = await readFileContent(join106(baseDir, relativePath));
13994
+ const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join107(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
13995
+ const fileContent = await readFileContent(join107(baseDir, relativePath));
13657
13996
  return new _WarpRule({
13658
13997
  baseDir,
13659
13998
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : ".warp",
@@ -13708,7 +14047,7 @@ var WarpRule = class _WarpRule extends ToolRule {
13708
14047
  };
13709
14048
 
13710
14049
  // src/features/rules/windsurf-rule.ts
13711
- import { join as join107 } from "path";
14050
+ import { join as join108 } from "path";
13712
14051
  var WindsurfRule = class _WindsurfRule extends ToolRule {
13713
14052
  static getSettablePaths(_options = {}) {
13714
14053
  return {
@@ -13723,7 +14062,7 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
13723
14062
  validate = true
13724
14063
  }) {
13725
14064
  const fileContent = await readFileContent(
13726
- join107(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
14065
+ join108(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
13727
14066
  );
13728
14067
  return new _WindsurfRule({
13729
14068
  baseDir,
@@ -13788,6 +14127,7 @@ var rulesProcessorToolTargets = [
13788
14127
  "cursor",
13789
14128
  "factorydroid",
13790
14129
  "geminicli",
14130
+ "goose",
13791
14131
  "junie",
13792
14132
  "kilo",
13793
14133
  "kiro",
@@ -13798,8 +14138,8 @@ var rulesProcessorToolTargets = [
13798
14138
  "warp",
13799
14139
  "windsurf"
13800
14140
  ];
13801
- var RulesProcessorToolTargetSchema = z49.enum(rulesProcessorToolTargets);
13802
- var formatRulePaths = (rules) => rules.map((r) => join108(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
14141
+ var RulesProcessorToolTargetSchema = z50.enum(rulesProcessorToolTargets);
14142
+ var formatRulePaths = (rules) => rules.map((r) => join109(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
13803
14143
  var toolRuleFactories = /* @__PURE__ */ new Map([
13804
14144
  [
13805
14145
  "agentsmd",
@@ -13890,10 +14230,7 @@ var toolRuleFactories = /* @__PURE__ */ new Map([
13890
14230
  meta: {
13891
14231
  extension: "md",
13892
14232
  supportsGlobal: true,
13893
- ruleDiscoveryMode: "toon",
13894
- additionalConventions: {
13895
- subagents: { subagentClass: CodexCliSubagent }
13896
- }
14233
+ ruleDiscoveryMode: "toon"
13897
14234
  }
13898
14235
  }
13899
14236
  ],
@@ -13949,6 +14286,17 @@ var toolRuleFactories = /* @__PURE__ */ new Map([
13949
14286
  }
13950
14287
  }
13951
14288
  ],
14289
+ [
14290
+ "goose",
14291
+ {
14292
+ class: GooseRule,
14293
+ meta: {
14294
+ extension: "md",
14295
+ supportsGlobal: true,
14296
+ ruleDiscoveryMode: "toon"
14297
+ }
14298
+ }
14299
+ ],
13952
14300
  [
13953
14301
  "junie",
13954
14302
  {
@@ -14166,7 +14514,7 @@ var RulesProcessor = class extends FeatureProcessor {
14166
14514
  }).relativeDirPath;
14167
14515
  return this.skills.filter((skill) => skillClass.isTargetedByRulesyncSkill(skill)).map((skill) => {
14168
14516
  const frontmatter = skill.getFrontmatter();
14169
- const relativePath = join108(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME);
14517
+ const relativePath = join109(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME);
14170
14518
  return {
14171
14519
  name: frontmatter.name,
14172
14520
  description: frontmatter.description,
@@ -14279,12 +14627,12 @@ var RulesProcessor = class extends FeatureProcessor {
14279
14627
  * Load and parse rulesync rule files from .rulesync/rules/ directory
14280
14628
  */
14281
14629
  async loadRulesyncFiles() {
14282
- const rulesyncBaseDir = join108(this.baseDir, RULESYNC_RULES_RELATIVE_DIR_PATH);
14283
- const files = await findFilesByGlobs(join108(rulesyncBaseDir, "**", "*.md"));
14630
+ const rulesyncBaseDir = join109(this.baseDir, RULESYNC_RULES_RELATIVE_DIR_PATH);
14631
+ const files = await findFilesByGlobs(join109(rulesyncBaseDir, "**", "*.md"));
14284
14632
  logger.debug(`Found ${files.length} rulesync files`);
14285
14633
  const rulesyncRules = await Promise.all(
14286
14634
  files.map((file) => {
14287
- const relativeFilePath = relative4(rulesyncBaseDir, file);
14635
+ const relativeFilePath = relative5(rulesyncBaseDir, file);
14288
14636
  checkPathTraversal({
14289
14637
  relativePath: relativeFilePath,
14290
14638
  intendedRootDir: rulesyncBaseDir
@@ -14347,7 +14695,7 @@ var RulesProcessor = class extends FeatureProcessor {
14347
14695
  return [];
14348
14696
  }
14349
14697
  const rootFilePaths = await findFilesByGlobs(
14350
- join108(
14698
+ join109(
14351
14699
  this.baseDir,
14352
14700
  settablePaths.root.relativeDirPath ?? ".",
14353
14701
  settablePaths.root.relativeFilePath
@@ -14358,7 +14706,7 @@ var RulesProcessor = class extends FeatureProcessor {
14358
14706
  (filePath) => factory.class.forDeletion({
14359
14707
  baseDir: this.baseDir,
14360
14708
  relativeDirPath: settablePaths.root?.relativeDirPath ?? ".",
14361
- relativeFilePath: basename24(filePath),
14709
+ relativeFilePath: basename10(filePath),
14362
14710
  global: this.global
14363
14711
  })
14364
14712
  ).filter((rule) => rule.isDeletable());
@@ -14367,7 +14715,7 @@ var RulesProcessor = class extends FeatureProcessor {
14367
14715
  rootFilePaths.map(
14368
14716
  (filePath) => factory.class.fromFile({
14369
14717
  baseDir: this.baseDir,
14370
- relativeFilePath: basename24(filePath),
14718
+ relativeFilePath: basename10(filePath),
14371
14719
  global: this.global
14372
14720
  })
14373
14721
  )
@@ -14385,13 +14733,13 @@ var RulesProcessor = class extends FeatureProcessor {
14385
14733
  return [];
14386
14734
  }
14387
14735
  const localRootFilePaths = await findFilesByGlobs(
14388
- join108(this.baseDir, settablePaths.root.relativeDirPath ?? ".", "CLAUDE.local.md")
14736
+ join109(this.baseDir, settablePaths.root.relativeDirPath ?? ".", "CLAUDE.local.md")
14389
14737
  );
14390
14738
  return localRootFilePaths.map(
14391
14739
  (filePath) => factory.class.forDeletion({
14392
14740
  baseDir: this.baseDir,
14393
14741
  relativeDirPath: settablePaths.root?.relativeDirPath ?? ".",
14394
- relativeFilePath: basename24(filePath),
14742
+ relativeFilePath: basename10(filePath),
14395
14743
  global: this.global
14396
14744
  })
14397
14745
  ).filter((rule) => rule.isDeletable());
@@ -14401,13 +14749,13 @@ var RulesProcessor = class extends FeatureProcessor {
14401
14749
  if (!settablePaths.nonRoot) {
14402
14750
  return [];
14403
14751
  }
14404
- const nonRootBaseDir = join108(this.baseDir, settablePaths.nonRoot.relativeDirPath);
14752
+ const nonRootBaseDir = join109(this.baseDir, settablePaths.nonRoot.relativeDirPath);
14405
14753
  const nonRootFilePaths = await findFilesByGlobs(
14406
- join108(nonRootBaseDir, "**", `*.${factory.meta.extension}`)
14754
+ join109(nonRootBaseDir, "**", `*.${factory.meta.extension}`)
14407
14755
  );
14408
14756
  if (forDeletion) {
14409
14757
  return nonRootFilePaths.map((filePath) => {
14410
- const relativeFilePath = relative4(nonRootBaseDir, filePath);
14758
+ const relativeFilePath = relative5(nonRootBaseDir, filePath);
14411
14759
  checkPathTraversal({
14412
14760
  relativePath: relativeFilePath,
14413
14761
  intendedRootDir: nonRootBaseDir
@@ -14422,7 +14770,7 @@ var RulesProcessor = class extends FeatureProcessor {
14422
14770
  }
14423
14771
  return await Promise.all(
14424
14772
  nonRootFilePaths.map((filePath) => {
14425
- const relativeFilePath = relative4(nonRootBaseDir, filePath);
14773
+ const relativeFilePath = relative5(nonRootBaseDir, filePath);
14426
14774
  checkPathTraversal({
14427
14775
  relativePath: relativeFilePath,
14428
14776
  intendedRootDir: nonRootBaseDir
@@ -14535,14 +14883,14 @@ s/<command> [arguments]
14535
14883
  This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
14536
14884
  The \`s\` in \`s/\` stands for *simulate*. Because custom slash commands are not built-in, this syntax provides a pseudo way to invoke them.
14537
14885
 
14538
- When users call a custom slash command, you have to look for the markdown file, \`${join108(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
14886
+ When users call a custom slash command, you have to look for the markdown file, \`${join109(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
14539
14887
  const subagentsSection = subagents ? `## Simulated Subagents
14540
14888
 
14541
14889
  Simulated subagents are specialized AI assistants that can be invoked to handle specific types of tasks. In this case, it can be appear something like custom slash commands simply. Simulated subagents can be called by custom slash commands.
14542
14890
 
14543
- When users call a simulated subagent, it will look for the corresponding markdown file, \`${join108(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "{subagent}.md")}\`, and execute its contents as the block of operations.
14891
+ When users call a simulated subagent, it will look for the corresponding markdown file, \`${join109(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "{subagent}.md")}\`, and execute its contents as the block of operations.
14544
14892
 
14545
- For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join108(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
14893
+ For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join109(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
14546
14894
  const skillsSection = skills ? this.generateSkillsSection(skills) : "";
14547
14895
  const result = [
14548
14896
  overview,
@@ -14614,7 +14962,7 @@ async function processEmptyFeatureGeneration(params) {
14614
14962
  return { count: totalCount, paths: [], hasDiff };
14615
14963
  }
14616
14964
  async function checkRulesyncDirExists(params) {
14617
- return fileExists(join109(params.baseDir, RULESYNC_RELATIVE_DIR_PATH));
14965
+ return fileExists(join110(params.baseDir, RULESYNC_RELATIVE_DIR_PATH));
14618
14966
  }
14619
14967
  async function generate(params) {
14620
14968
  const { config } = params;