rulesync 7.4.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.
@@ -675,7 +675,7 @@ var SimulatedCommand = class _SimulatedCommand extends ToolCommand {
675
675
  return {
676
676
  baseDir,
677
677
  relativeDirPath: _SimulatedCommand.getSettablePaths().relativeDirPath,
678
- relativeFilePath: (0, import_node_path4.basename)(relativeFilePath),
678
+ relativeFilePath,
679
679
  frontmatter: result.data,
680
680
  body: content.trim(),
681
681
  validate
@@ -732,7 +732,7 @@ var AgentsmdCommand = class _AgentsmdCommand extends SimulatedCommand {
732
732
  return new _AgentsmdCommand({
733
733
  baseDir,
734
734
  relativeDirPath: _AgentsmdCommand.getSettablePaths().relativeDirPath,
735
- relativeFilePath: (0, import_node_path5.basename)(relativeFilePath),
735
+ relativeFilePath,
736
736
  frontmatter: result.data,
737
737
  body: content.trim(),
738
738
  validate
@@ -841,6 +841,16 @@ var RulesyncCommand = class _RulesyncCommand extends RulesyncFile {
841
841
  getBody() {
842
842
  return this.body;
843
843
  }
844
+ withRelativeFilePath(newRelativeFilePath) {
845
+ return new _RulesyncCommand({
846
+ baseDir: this.getBaseDir(),
847
+ relativeDirPath: this.getRelativeDirPath(),
848
+ relativeFilePath: newRelativeFilePath,
849
+ frontmatter: this.getFrontmatter(),
850
+ body: this.getBody(),
851
+ fileContent: this.getFileContent()
852
+ });
853
+ }
844
854
  validate() {
845
855
  if (!this.frontmatter) {
846
856
  return { success: true, error: null };
@@ -871,11 +881,10 @@ var RulesyncCommand = class _RulesyncCommand extends RulesyncFile {
871
881
  if (!result.success) {
872
882
  throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${formatError(result.error)}`);
873
883
  }
874
- const filename = (0, import_node_path6.basename)(relativeFilePath);
875
884
  return new _RulesyncCommand({
876
885
  baseDir: process.cwd(),
877
886
  relativeDirPath: _RulesyncCommand.getSettablePaths().relativeDirPath,
878
- relativeFilePath: filename,
887
+ relativeFilePath,
879
888
  frontmatter: result.data,
880
889
  body: content.trim(),
881
890
  fileContent
@@ -1034,7 +1043,7 @@ ${body}${turboDirective}`;
1034
1043
  return new _AntigravityCommand({
1035
1044
  baseDir,
1036
1045
  relativeDirPath: _AntigravityCommand.getSettablePaths().relativeDirPath,
1037
- relativeFilePath: (0, import_node_path7.basename)(relativeFilePath),
1046
+ relativeFilePath,
1038
1047
  frontmatter: result.data,
1039
1048
  body: content.trim(),
1040
1049
  fileContent,
@@ -1180,7 +1189,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
1180
1189
  return new _ClaudecodeCommand({
1181
1190
  baseDir,
1182
1191
  relativeDirPath: paths.relativeDirPath,
1183
- relativeFilePath: (0, import_node_path8.basename)(relativeFilePath),
1192
+ relativeFilePath,
1184
1193
  frontmatter: result.data,
1185
1194
  body: content.trim(),
1186
1195
  validate
@@ -1270,7 +1279,7 @@ var ClineCommand = class _ClineCommand extends ToolCommand {
1270
1279
  return new _ClineCommand({
1271
1280
  baseDir,
1272
1281
  relativeDirPath: paths.relativeDirPath,
1273
- relativeFilePath: (0, import_node_path9.basename)(relativeFilePath),
1282
+ relativeFilePath,
1274
1283
  fileContent: content.trim(),
1275
1284
  validate
1276
1285
  });
@@ -1357,7 +1366,7 @@ var CodexcliCommand = class _CodexcliCommand extends ToolCommand {
1357
1366
  return new _CodexcliCommand({
1358
1367
  baseDir,
1359
1368
  relativeDirPath: paths.relativeDirPath,
1360
- relativeFilePath: (0, import_node_path10.basename)(relativeFilePath),
1369
+ relativeFilePath,
1361
1370
  fileContent: content.trim(),
1362
1371
  validate
1363
1372
  });
@@ -1490,7 +1499,7 @@ var CopilotCommand = class _CopilotCommand extends ToolCommand {
1490
1499
  return new _CopilotCommand({
1491
1500
  baseDir,
1492
1501
  relativeDirPath: paths.relativeDirPath,
1493
- relativeFilePath: (0, import_node_path11.basename)(relativeFilePath),
1502
+ relativeFilePath,
1494
1503
  frontmatter: result.data,
1495
1504
  body: content.trim(),
1496
1505
  validate
@@ -1582,7 +1591,7 @@ var CursorCommand = class _CursorCommand extends ToolCommand {
1582
1591
  return new _CursorCommand({
1583
1592
  baseDir,
1584
1593
  relativeDirPath: paths.relativeDirPath,
1585
- relativeFilePath: (0, import_node_path12.basename)(relativeFilePath),
1594
+ relativeFilePath,
1586
1595
  fileContent: content.trim(),
1587
1596
  validate
1588
1597
  });
@@ -1637,7 +1646,7 @@ var FactorydroidCommand = class _FactorydroidCommand extends SimulatedCommand {
1637
1646
  return new _FactorydroidCommand({
1638
1647
  baseDir,
1639
1648
  relativeDirPath: paths.relativeDirPath,
1640
- relativeFilePath: (0, import_node_path13.basename)(relativeFilePath),
1649
+ relativeFilePath,
1641
1650
  frontmatter: result.data,
1642
1651
  body: content.trim(),
1643
1652
  validate
@@ -1769,7 +1778,7 @@ ${geminiFrontmatter.prompt}
1769
1778
  return new _GeminiCliCommand({
1770
1779
  baseDir,
1771
1780
  relativeDirPath: paths.relativeDirPath,
1772
- relativeFilePath: (0, import_node_path14.basename)(relativeFilePath),
1781
+ relativeFilePath,
1773
1782
  fileContent,
1774
1783
  validate
1775
1784
  });
@@ -1866,7 +1875,7 @@ var KiloCommand = class _KiloCommand extends ToolCommand {
1866
1875
  return new _KiloCommand({
1867
1876
  baseDir,
1868
1877
  relativeDirPath: paths.relativeDirPath,
1869
- relativeFilePath: (0, import_node_path15.basename)(relativeFilePath),
1878
+ relativeFilePath,
1870
1879
  fileContent: content.trim(),
1871
1880
  validate
1872
1881
  });
@@ -1947,7 +1956,7 @@ var KiroCommand = class _KiroCommand extends ToolCommand {
1947
1956
  return new _KiroCommand({
1948
1957
  baseDir,
1949
1958
  relativeDirPath: paths.relativeDirPath,
1950
- relativeFilePath: (0, import_node_path16.basename)(relativeFilePath),
1959
+ relativeFilePath,
1951
1960
  fileContent: content.trim(),
1952
1961
  validate
1953
1962
  });
@@ -2079,7 +2088,7 @@ var OpenCodeCommand = class _OpenCodeCommand extends ToolCommand {
2079
2088
  return new _OpenCodeCommand({
2080
2089
  baseDir,
2081
2090
  relativeDirPath: paths.relativeDirPath,
2082
- relativeFilePath: (0, import_node_path17.basename)(relativeFilePath),
2091
+ relativeFilePath,
2083
2092
  frontmatter: result.data,
2084
2093
  body: content.trim(),
2085
2094
  validate
@@ -2224,7 +2233,7 @@ var RooCommand = class _RooCommand extends ToolCommand {
2224
2233
  return new _RooCommand({
2225
2234
  baseDir,
2226
2235
  relativeDirPath: _RooCommand.getSettablePaths().relativeDirPath,
2227
- relativeFilePath: (0, import_node_path18.basename)(relativeFilePath),
2236
+ relativeFilePath,
2228
2237
  frontmatter: result.data,
2229
2238
  body: content.trim(),
2230
2239
  fileContent,
@@ -2271,42 +2280,78 @@ var toolCommandFactories = /* @__PURE__ */ new Map([
2271
2280
  "agentsmd",
2272
2281
  {
2273
2282
  class: AgentsmdCommand,
2274
- meta: { extension: "md", supportsProject: true, supportsGlobal: false, isSimulated: true }
2283
+ meta: {
2284
+ extension: "md",
2285
+ supportsProject: true,
2286
+ supportsGlobal: false,
2287
+ isSimulated: true,
2288
+ supportsSubdirectory: false
2289
+ }
2275
2290
  }
2276
2291
  ],
2277
2292
  [
2278
2293
  "antigravity",
2279
2294
  {
2280
2295
  class: AntigravityCommand,
2281
- meta: { extension: "md", supportsProject: true, supportsGlobal: false, isSimulated: false }
2296
+ meta: {
2297
+ extension: "md",
2298
+ supportsProject: true,
2299
+ supportsGlobal: false,
2300
+ isSimulated: false,
2301
+ supportsSubdirectory: false
2302
+ }
2282
2303
  }
2283
2304
  ],
2284
2305
  [
2285
2306
  "claudecode",
2286
2307
  {
2287
2308
  class: ClaudecodeCommand,
2288
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2309
+ meta: {
2310
+ extension: "md",
2311
+ supportsProject: true,
2312
+ supportsGlobal: true,
2313
+ isSimulated: false,
2314
+ supportsSubdirectory: true
2315
+ }
2289
2316
  }
2290
2317
  ],
2291
2318
  [
2292
2319
  "claudecode-legacy",
2293
2320
  {
2294
2321
  class: ClaudecodeCommand,
2295
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2322
+ meta: {
2323
+ extension: "md",
2324
+ supportsProject: true,
2325
+ supportsGlobal: true,
2326
+ isSimulated: false,
2327
+ supportsSubdirectory: true
2328
+ }
2296
2329
  }
2297
2330
  ],
2298
2331
  [
2299
2332
  "cline",
2300
2333
  {
2301
2334
  class: ClineCommand,
2302
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2335
+ meta: {
2336
+ extension: "md",
2337
+ supportsProject: true,
2338
+ supportsGlobal: true,
2339
+ isSimulated: false,
2340
+ supportsSubdirectory: false
2341
+ }
2303
2342
  }
2304
2343
  ],
2305
2344
  [
2306
2345
  "codexcli",
2307
2346
  {
2308
2347
  class: CodexcliCommand,
2309
- meta: { extension: "md", supportsProject: false, supportsGlobal: true, isSimulated: false }
2348
+ meta: {
2349
+ extension: "md",
2350
+ supportsProject: false,
2351
+ supportsGlobal: true,
2352
+ isSimulated: false,
2353
+ supportsSubdirectory: false
2354
+ }
2310
2355
  }
2311
2356
  ],
2312
2357
  [
@@ -2317,7 +2362,8 @@ var toolCommandFactories = /* @__PURE__ */ new Map([
2317
2362
  extension: "prompt.md",
2318
2363
  supportsProject: true,
2319
2364
  supportsGlobal: false,
2320
- isSimulated: false
2365
+ isSimulated: false,
2366
+ supportsSubdirectory: false
2321
2367
  }
2322
2368
  }
2323
2369
  ],
@@ -2325,49 +2371,91 @@ var toolCommandFactories = /* @__PURE__ */ new Map([
2325
2371
  "cursor",
2326
2372
  {
2327
2373
  class: CursorCommand,
2328
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2374
+ meta: {
2375
+ extension: "md",
2376
+ supportsProject: true,
2377
+ supportsGlobal: true,
2378
+ isSimulated: false,
2379
+ supportsSubdirectory: false
2380
+ }
2329
2381
  }
2330
2382
  ],
2331
2383
  [
2332
2384
  "factorydroid",
2333
2385
  {
2334
2386
  class: FactorydroidCommand,
2335
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: true }
2387
+ meta: {
2388
+ extension: "md",
2389
+ supportsProject: true,
2390
+ supportsGlobal: true,
2391
+ isSimulated: true,
2392
+ supportsSubdirectory: false
2393
+ }
2336
2394
  }
2337
2395
  ],
2338
2396
  [
2339
2397
  "geminicli",
2340
2398
  {
2341
2399
  class: GeminiCliCommand,
2342
- meta: { extension: "toml", supportsProject: true, supportsGlobal: true, isSimulated: false }
2400
+ meta: {
2401
+ extension: "toml",
2402
+ supportsProject: true,
2403
+ supportsGlobal: true,
2404
+ isSimulated: false,
2405
+ supportsSubdirectory: true
2406
+ }
2343
2407
  }
2344
2408
  ],
2345
2409
  [
2346
2410
  "kilo",
2347
2411
  {
2348
2412
  class: KiloCommand,
2349
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2413
+ meta: {
2414
+ extension: "md",
2415
+ supportsProject: true,
2416
+ supportsGlobal: true,
2417
+ isSimulated: false,
2418
+ supportsSubdirectory: false
2419
+ }
2350
2420
  }
2351
2421
  ],
2352
2422
  [
2353
2423
  "kiro",
2354
2424
  {
2355
2425
  class: KiroCommand,
2356
- meta: { extension: "md", supportsProject: true, supportsGlobal: false, isSimulated: false }
2426
+ meta: {
2427
+ extension: "md",
2428
+ supportsProject: true,
2429
+ supportsGlobal: false,
2430
+ isSimulated: false,
2431
+ supportsSubdirectory: false
2432
+ }
2357
2433
  }
2358
2434
  ],
2359
2435
  [
2360
2436
  "opencode",
2361
2437
  {
2362
2438
  class: OpenCodeCommand,
2363
- meta: { extension: "md", supportsProject: true, supportsGlobal: true, isSimulated: false }
2439
+ meta: {
2440
+ extension: "md",
2441
+ supportsProject: true,
2442
+ supportsGlobal: true,
2443
+ isSimulated: false,
2444
+ supportsSubdirectory: true
2445
+ }
2364
2446
  }
2365
2447
  ],
2366
2448
  [
2367
2449
  "roo",
2368
2450
  {
2369
2451
  class: RooCommand,
2370
- meta: { extension: "md", supportsProject: true, supportsGlobal: false, isSimulated: false }
2452
+ meta: {
2453
+ extension: "md",
2454
+ supportsProject: true,
2455
+ supportsGlobal: false,
2456
+ isSimulated: false,
2457
+ supportsSubdirectory: true
2458
+ }
2371
2459
  }
2372
2460
  ]
2373
2461
  ]);
@@ -2420,13 +2508,27 @@ var CommandsProcessor = class extends FeatureProcessor {
2420
2508
  (file) => file instanceof RulesyncCommand
2421
2509
  );
2422
2510
  const factory = this.getFactory(this.toolTarget);
2511
+ const flattenedPathOrigins = /* @__PURE__ */ new Map();
2423
2512
  const toolCommands = rulesyncCommands.map((rulesyncCommand) => {
2424
2513
  if (!factory.class.isTargetedByRulesyncCommand(rulesyncCommand)) {
2425
2514
  return null;
2426
2515
  }
2516
+ const originalRelativePath = rulesyncCommand.getRelativeFilePath();
2517
+ const commandToConvert = factory.meta.supportsSubdirectory ? rulesyncCommand : this.flattenRelativeFilePath(rulesyncCommand);
2518
+ if (!factory.meta.supportsSubdirectory) {
2519
+ const flattenedPath = commandToConvert.getRelativeFilePath();
2520
+ const firstOrigin = flattenedPathOrigins.get(flattenedPath);
2521
+ if (firstOrigin && firstOrigin !== originalRelativePath) {
2522
+ logger.warn(
2523
+ `Command path collision detected while flattening for ${this.toolTarget}: "${firstOrigin}" and "${originalRelativePath}" both map to "${flattenedPath}". The later command will overwrite the earlier one.`
2524
+ );
2525
+ } else if (!firstOrigin) {
2526
+ flattenedPathOrigins.set(flattenedPath, originalRelativePath);
2527
+ }
2528
+ }
2427
2529
  return factory.class.fromRulesyncCommand({
2428
2530
  baseDir: this.baseDir,
2429
- rulesyncCommand,
2531
+ rulesyncCommand: commandToConvert,
2430
2532
  global: this.global
2431
2533
  });
2432
2534
  }).filter((command) => command !== null);
@@ -2441,17 +2543,26 @@ var CommandsProcessor = class extends FeatureProcessor {
2441
2543
  });
2442
2544
  return rulesyncCommands;
2443
2545
  }
2546
+ flattenRelativeFilePath(rulesyncCommand) {
2547
+ const flatPath = (0, import_node_path19.basename)(rulesyncCommand.getRelativeFilePath());
2548
+ if (flatPath === rulesyncCommand.getRelativeFilePath()) return rulesyncCommand;
2549
+ return rulesyncCommand.withRelativeFilePath(flatPath);
2550
+ }
2551
+ safeRelativePath(basePath, fullPath) {
2552
+ const rel = (0, import_node_path19.relative)(basePath, fullPath);
2553
+ checkPathTraversal({ relativePath: rel, intendedRootDir: basePath });
2554
+ return rel;
2555
+ }
2444
2556
  /**
2445
2557
  * Implementation of abstract method from FeatureProcessor
2446
2558
  * Load and parse rulesync command files from .rulesync/commands/ directory
2447
2559
  */
2448
2560
  async loadRulesyncFiles() {
2449
- const rulesyncCommandPaths = await findFilesByGlobs(
2450
- (0, import_node_path19.join)(RulesyncCommand.getSettablePaths().relativeDirPath, "*.md")
2451
- );
2561
+ const basePath = RulesyncCommand.getSettablePaths().relativeDirPath;
2562
+ const rulesyncCommandPaths = await findFilesByGlobs((0, import_node_path19.join)(basePath, "**", "*.md"));
2452
2563
  const rulesyncCommands = await Promise.all(
2453
2564
  rulesyncCommandPaths.map(
2454
- (path4) => RulesyncCommand.fromFile({ relativeFilePath: (0, import_node_path19.basename)(path4) })
2565
+ (path4) => RulesyncCommand.fromFile({ relativeFilePath: this.safeRelativePath(basePath, path4) })
2455
2566
  )
2456
2567
  );
2457
2568
  logger.debug(`Successfully loaded ${rulesyncCommands.length} rulesync commands`);
@@ -2466,15 +2577,15 @@ var CommandsProcessor = class extends FeatureProcessor {
2466
2577
  } = {}) {
2467
2578
  const factory = this.getFactory(this.toolTarget);
2468
2579
  const paths = factory.class.getSettablePaths({ global: this.global });
2469
- const commandFilePaths = await findFilesByGlobs(
2470
- (0, import_node_path19.join)(this.baseDir, paths.relativeDirPath, `*.${factory.meta.extension}`)
2471
- );
2580
+ const baseDirFull = (0, import_node_path19.join)(this.baseDir, paths.relativeDirPath);
2581
+ const globPattern = factory.meta.supportsSubdirectory ? (0, import_node_path19.join)(baseDirFull, "**", `*.${factory.meta.extension}`) : (0, import_node_path19.join)(baseDirFull, `*.${factory.meta.extension}`);
2582
+ const commandFilePaths = await findFilesByGlobs(globPattern);
2472
2583
  if (forDeletion) {
2473
2584
  const toolCommands2 = commandFilePaths.map(
2474
2585
  (path4) => factory.class.forDeletion({
2475
2586
  baseDir: this.baseDir,
2476
2587
  relativeDirPath: paths.relativeDirPath,
2477
- relativeFilePath: (0, import_node_path19.basename)(path4),
2588
+ relativeFilePath: this.safeRelativePath(baseDirFull, path4),
2478
2589
  global: this.global
2479
2590
  })
2480
2591
  ).filter((cmd) => cmd.isDeletable());
@@ -2485,7 +2596,7 @@ var CommandsProcessor = class extends FeatureProcessor {
2485
2596
  commandFilePaths.map(
2486
2597
  (path4) => factory.class.fromFile({
2487
2598
  baseDir: this.baseDir,
2488
- relativeFilePath: (0, import_node_path19.basename)(path4),
2599
+ relativeFilePath: this.safeRelativePath(baseDirFull, path4),
2489
2600
  global: this.global
2490
2601
  })
2491
2602
  )
@@ -18887,7 +18998,7 @@ async function updateCommand(currentVersion, options) {
18887
18998
  }
18888
18999
 
18889
19000
  // src/cli/index.ts
18890
- var getVersion = () => "7.4.0";
19001
+ var getVersion = () => "7.5.0";
18891
19002
  var main = async () => {
18892
19003
  const program = new import_commander.Command();
18893
19004
  const version = getVersion();
package/dist/cli/index.js CHANGED
@@ -60,7 +60,7 @@ import {
60
60
  removeTempDirectory,
61
61
  stringifyFrontmatter,
62
62
  writeFileContent
63
- } from "../chunk-UCC3WPDL.js";
63
+ } from "../chunk-WZ7IUX6M.js";
64
64
 
65
65
  // src/cli/index.ts
66
66
  import { Command } from "commander";
@@ -3790,7 +3790,7 @@ async function updateCommand(currentVersion, options) {
3790
3790
  }
3791
3791
 
3792
3792
  // src/cli/index.ts
3793
- var getVersion = () => "7.4.0";
3793
+ var getVersion = () => "7.5.0";
3794
3794
  var main = async () => {
3795
3795
  const program = new Command();
3796
3796
  const version = getVersion();