rulesync 8.0.0 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{chunk-GB6XLCGB.js → chunk-K4IN6URH.js} +222 -41
- package/dist/cli/index.cjs +270 -47
- package/dist/cli/index.js +51 -7
- package/dist/index.cjs +221 -41
- package/dist/index.js +1 -1
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -262,12 +262,13 @@ var FeaturesSchema = import_mini.z.array(FeatureSchema);
|
|
|
262
262
|
var FeatureOptionsSchema = import_mini.z.record(import_mini.z.string(), import_mini.z.unknown());
|
|
263
263
|
var FeatureValueSchema = import_mini.z.union([import_mini.z.boolean(), FeatureOptionsSchema]);
|
|
264
264
|
var PerFeatureConfigSchema = import_mini.z.record(import_mini.z.string(), FeatureValueSchema);
|
|
265
|
+
var PerTargetFeaturesValueSchema = import_mini.z.union([
|
|
266
|
+
import_mini.z.array(import_mini.z.enum(ALL_FEATURES_WITH_WILDCARD)),
|
|
267
|
+
PerFeatureConfigSchema
|
|
268
|
+
]);
|
|
265
269
|
var RulesyncFeaturesSchema = import_mini.z.union([
|
|
266
270
|
import_mini.z.array(import_mini.z.enum(ALL_FEATURES_WITH_WILDCARD)),
|
|
267
|
-
import_mini.z.record(
|
|
268
|
-
import_mini.z.string(),
|
|
269
|
-
import_mini.z.union([import_mini.z.array(import_mini.z.enum(ALL_FEATURES_WITH_WILDCARD)), PerFeatureConfigSchema])
|
|
270
|
-
)
|
|
271
|
+
import_mini.z.record(import_mini.z.string(), PerTargetFeaturesValueSchema)
|
|
271
272
|
]);
|
|
272
273
|
var isFeatureValueEnabled = (value) => {
|
|
273
274
|
if (value === true) return true;
|
|
@@ -310,6 +311,14 @@ var ALL_TOOL_TARGETS_WITH_WILDCARD = [...ALL_TOOL_TARGETS, "*"];
|
|
|
310
311
|
var ToolTargetSchema = import_mini2.z.enum(ALL_TOOL_TARGETS);
|
|
311
312
|
var ToolTargetsSchema = import_mini2.z.array(ToolTargetSchema);
|
|
312
313
|
var RulesyncTargetsSchema = import_mini2.z.array(import_mini2.z.enum(ALL_TOOL_TARGETS_WITH_WILDCARD));
|
|
314
|
+
var RulesyncConfigTargetsObjectSchema = import_mini2.z.record(import_mini2.z.string(), PerTargetFeaturesValueSchema);
|
|
315
|
+
var RulesyncConfigTargetsSchema = import_mini2.z.union([
|
|
316
|
+
RulesyncTargetsSchema,
|
|
317
|
+
RulesyncConfigTargetsObjectSchema
|
|
318
|
+
]);
|
|
319
|
+
var isRulesyncConfigTargetsObject = (value) => {
|
|
320
|
+
return !Array.isArray(value);
|
|
321
|
+
};
|
|
313
322
|
|
|
314
323
|
// src/utils/validation.ts
|
|
315
324
|
function findControlCharacter(value) {
|
|
@@ -346,7 +355,7 @@ var SourceEntrySchema = import_mini3.z.object({
|
|
|
346
355
|
});
|
|
347
356
|
var ConfigParamsSchema = import_mini3.z.object({
|
|
348
357
|
baseDirs: import_mini3.z.array(import_mini3.z.string()),
|
|
349
|
-
targets:
|
|
358
|
+
targets: RulesyncConfigTargetsSchema,
|
|
350
359
|
features: RulesyncFeaturesSchema,
|
|
351
360
|
verbose: import_mini3.z.boolean(),
|
|
352
361
|
delete: import_mini3.z.boolean(),
|
|
@@ -356,6 +365,7 @@ var ConfigParamsSchema = import_mini3.z.object({
|
|
|
356
365
|
simulateCommands: (0, import_mini3.optional)(import_mini3.z.boolean()),
|
|
357
366
|
simulateSubagents: (0, import_mini3.optional)(import_mini3.z.boolean()),
|
|
358
367
|
simulateSkills: (0, import_mini3.optional)(import_mini3.z.boolean()),
|
|
368
|
+
gitignoreTargetsOnly: (0, import_mini3.optional)(import_mini3.z.boolean()),
|
|
359
369
|
dryRun: (0, import_mini3.optional)(import_mini3.z.boolean()),
|
|
360
370
|
check: (0, import_mini3.optional)(import_mini3.z.boolean()),
|
|
361
371
|
// Declarative skill sources
|
|
@@ -372,10 +382,42 @@ var CONFLICTING_TARGET_PAIRS = [
|
|
|
372
382
|
["claudecode", "claudecode-legacy"]
|
|
373
383
|
];
|
|
374
384
|
var LEGACY_TARGETS = ["augmentcode-legacy", "claudecode-legacy"];
|
|
385
|
+
var assertTargetsFeaturesExclusive = ({
|
|
386
|
+
targets,
|
|
387
|
+
features
|
|
388
|
+
}) => {
|
|
389
|
+
const targetsIsObject = targets !== void 0 && !Array.isArray(targets);
|
|
390
|
+
const featuresIsObject = features !== void 0 && !Array.isArray(features);
|
|
391
|
+
if (targetsIsObject && features !== void 0) {
|
|
392
|
+
throw new Error(
|
|
393
|
+
"Invalid config: when 'targets' is in object form, 'features' must be omitted. Declare per-target features inside the 'targets' object instead."
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
if (featuresIsObject && targets !== void 0) {
|
|
397
|
+
throw new Error(
|
|
398
|
+
"Invalid config: when 'features' is in object form, 'targets' must be omitted. Migrate to the 'targets' object form, e.g. `targets: { claudecode: [...] }`."
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
var assertTargetsOrFeaturesProvided = ({
|
|
403
|
+
targets,
|
|
404
|
+
features
|
|
405
|
+
}) => {
|
|
406
|
+
if (targets === void 0 && features === void 0) {
|
|
407
|
+
throw new Error("Invalid config: at least one of 'targets' or 'features' must be provided.");
|
|
408
|
+
}
|
|
409
|
+
};
|
|
375
410
|
var Config = class _Config {
|
|
376
411
|
baseDirs;
|
|
377
412
|
targets;
|
|
378
413
|
features;
|
|
414
|
+
/**
|
|
415
|
+
* Cached list of validated `ToolTarget` keys for the object form of
|
|
416
|
+
* `targets`. Populated in the constructor after `validateObjectFormTargetKeys`
|
|
417
|
+
* so `getTargets()` does not rebuild the `ALL_TOOL_TARGETS` set on every call.
|
|
418
|
+
* Undefined when `this.targets` is in array form.
|
|
419
|
+
*/
|
|
420
|
+
objectFormTargetKeys;
|
|
379
421
|
verbose;
|
|
380
422
|
delete;
|
|
381
423
|
global;
|
|
@@ -383,6 +425,7 @@ var Config = class _Config {
|
|
|
383
425
|
simulateCommands;
|
|
384
426
|
simulateSubagents;
|
|
385
427
|
simulateSkills;
|
|
428
|
+
gitignoreTargetsOnly;
|
|
386
429
|
dryRun;
|
|
387
430
|
check;
|
|
388
431
|
sources;
|
|
@@ -397,17 +440,24 @@ var Config = class _Config {
|
|
|
397
440
|
simulateCommands,
|
|
398
441
|
simulateSubagents,
|
|
399
442
|
simulateSkills,
|
|
443
|
+
gitignoreTargetsOnly,
|
|
400
444
|
dryRun,
|
|
401
445
|
check,
|
|
402
446
|
sources
|
|
403
447
|
}) {
|
|
404
|
-
|
|
448
|
+
assertTargetsFeaturesExclusive({ targets, features });
|
|
449
|
+
assertTargetsOrFeaturesProvided({ targets, features });
|
|
450
|
+
const resolvedTargets = targets ?? [];
|
|
451
|
+
const resolvedFeatures = features ?? [];
|
|
452
|
+
this.validateObjectFormTargetKeys(resolvedTargets);
|
|
453
|
+
this.validateConflictingTargets(resolvedTargets);
|
|
405
454
|
if (dryRun && check) {
|
|
406
455
|
throw new Error("--dry-run and --check cannot be used together");
|
|
407
456
|
}
|
|
408
457
|
this.baseDirs = baseDirs;
|
|
409
|
-
this.targets =
|
|
410
|
-
this.features =
|
|
458
|
+
this.targets = resolvedTargets;
|
|
459
|
+
this.features = resolvedFeatures;
|
|
460
|
+
this.objectFormTargetKeys = isRulesyncConfigTargetsObject(resolvedTargets) ? _Config.filterValidToolTargets(Object.keys(resolvedTargets)) : void 0;
|
|
411
461
|
this.verbose = verbose;
|
|
412
462
|
this.delete = isDelete;
|
|
413
463
|
this.global = global ?? false;
|
|
@@ -415,15 +465,42 @@ var Config = class _Config {
|
|
|
415
465
|
this.simulateCommands = simulateCommands ?? false;
|
|
416
466
|
this.simulateSubagents = simulateSubagents ?? false;
|
|
417
467
|
this.simulateSkills = simulateSkills ?? false;
|
|
468
|
+
this.gitignoreTargetsOnly = gitignoreTargetsOnly ?? true;
|
|
418
469
|
this.dryRun = dryRun ?? false;
|
|
419
470
|
this.check = check ?? false;
|
|
420
471
|
this.sources = sources ?? [];
|
|
421
472
|
}
|
|
473
|
+
/**
|
|
474
|
+
* Rejects unknown keys (and the special `*` key) in the object form of
|
|
475
|
+
* `targets`. For the array form this is already enforced at the Zod schema
|
|
476
|
+
* level via `z.enum(ALL_TOOL_TARGETS_WITH_WILDCARD)`; for the object form
|
|
477
|
+
* `z.record(z.string(), ...)` intentionally accepts any string key (to work
|
|
478
|
+
* around zod's `z.record(z.enum(...))` requiring ALL enum members), so
|
|
479
|
+
* runtime validation lives here instead.
|
|
480
|
+
*/
|
|
481
|
+
validateObjectFormTargetKeys(targets) {
|
|
482
|
+
if (Array.isArray(targets)) return;
|
|
483
|
+
const validTargets = new Set(ALL_TOOL_TARGETS);
|
|
484
|
+
for (const key of Object.keys(targets)) {
|
|
485
|
+
if (key === "*") {
|
|
486
|
+
throw new Error(
|
|
487
|
+
"Invalid target '*' in object form: wildcard is only supported in the array form `targets: ['*']`. Per-target options cannot be attached to a wildcard."
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
if (!validTargets.has(key)) {
|
|
491
|
+
throw new Error(`Unknown target '${key}'. Valid targets: ${ALL_TOOL_TARGETS.join(", ")}.`);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
422
495
|
validateConflictingTargets(targets) {
|
|
496
|
+
const has = (target) => {
|
|
497
|
+
if (Array.isArray(targets)) {
|
|
498
|
+
return targets.includes(target);
|
|
499
|
+
}
|
|
500
|
+
return Object.prototype.hasOwnProperty.call(targets, target);
|
|
501
|
+
};
|
|
423
502
|
for (const [target1, target2] of CONFLICTING_TARGET_PAIRS) {
|
|
424
|
-
|
|
425
|
-
const hasTarget2 = targets.includes(target2);
|
|
426
|
-
if (hasTarget1 && hasTarget2) {
|
|
503
|
+
if (has(target1) && has(target2)) {
|
|
427
504
|
throw new Error(
|
|
428
505
|
`Conflicting targets: '${target1}' and '${target2}' cannot be used together. Please choose one.`
|
|
429
506
|
);
|
|
@@ -433,16 +510,45 @@ var Config = class _Config {
|
|
|
433
510
|
getBaseDirs() {
|
|
434
511
|
return this.baseDirs;
|
|
435
512
|
}
|
|
513
|
+
/**
|
|
514
|
+
* Filter an arbitrary string-key list down to the known `ToolTarget` set,
|
|
515
|
+
* skipping `*` (which is only meaningful as an array element, not a key).
|
|
516
|
+
*/
|
|
517
|
+
static filterValidToolTargets(keys) {
|
|
518
|
+
const validTargets = new Set(ALL_TOOL_TARGETS);
|
|
519
|
+
const result = [];
|
|
520
|
+
for (const key of keys) {
|
|
521
|
+
if (key === "*") continue;
|
|
522
|
+
if (!validTargets.has(key)) continue;
|
|
523
|
+
result.push(key);
|
|
524
|
+
}
|
|
525
|
+
return result;
|
|
526
|
+
}
|
|
436
527
|
getTargets() {
|
|
437
|
-
if (this.
|
|
528
|
+
if (this.objectFormTargetKeys !== void 0) {
|
|
529
|
+
return this.objectFormTargetKeys;
|
|
530
|
+
}
|
|
531
|
+
const arrayTargets = Array.isArray(this.targets) ? this.targets : [];
|
|
532
|
+
if (!Array.isArray(this.features)) {
|
|
533
|
+
return _Config.filterValidToolTargets(Object.keys(this.features));
|
|
534
|
+
}
|
|
535
|
+
if (arrayTargets.includes("*")) {
|
|
438
536
|
return ALL_TOOL_TARGETS.filter(
|
|
439
537
|
// eslint-disable-next-line no-type-assertion/no-type-assertion
|
|
440
538
|
(target) => !LEGACY_TARGETS.includes(target)
|
|
441
539
|
);
|
|
442
540
|
}
|
|
443
|
-
return
|
|
541
|
+
return arrayTargets.filter((target) => target !== "*");
|
|
444
542
|
}
|
|
445
543
|
getFeatures(target) {
|
|
544
|
+
if (isRulesyncConfigTargetsObject(this.targets)) {
|
|
545
|
+
if (target) {
|
|
546
|
+
const value = this.targets[target];
|
|
547
|
+
if (!value) return [];
|
|
548
|
+
return _Config.normalizeTargetFeatures(value);
|
|
549
|
+
}
|
|
550
|
+
return _Config.collectAllFeatures(Object.values(this.targets));
|
|
551
|
+
}
|
|
446
552
|
if (!Array.isArray(this.features)) {
|
|
447
553
|
const perTargetFeatures = this.features;
|
|
448
554
|
if (target) {
|
|
@@ -452,20 +558,7 @@ var Config = class _Config {
|
|
|
452
558
|
}
|
|
453
559
|
return _Config.normalizeTargetFeatures(targetFeatures);
|
|
454
560
|
}
|
|
455
|
-
|
|
456
|
-
for (const features of Object.values(perTargetFeatures)) {
|
|
457
|
-
if (!features) continue;
|
|
458
|
-
const normalized = _Config.normalizeTargetFeatures(features);
|
|
459
|
-
for (const feature of normalized) {
|
|
460
|
-
if (!allFeatures.includes(feature)) {
|
|
461
|
-
allFeatures.push(feature);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
if (allFeatures.length === ALL_FEATURES.length) {
|
|
465
|
-
return allFeatures;
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
return allFeatures;
|
|
561
|
+
return _Config.collectAllFeatures(Object.values(perTargetFeatures));
|
|
469
562
|
}
|
|
470
563
|
if (this.features.includes("*")) {
|
|
471
564
|
return [...ALL_FEATURES];
|
|
@@ -493,23 +586,40 @@ var Config = class _Config {
|
|
|
493
586
|
}
|
|
494
587
|
return enabled;
|
|
495
588
|
}
|
|
589
|
+
/**
|
|
590
|
+
* Collect the union of features across all per-target values.
|
|
591
|
+
* Used when `getFeatures()` is called without a target in object mode.
|
|
592
|
+
*/
|
|
593
|
+
static collectAllFeatures(values) {
|
|
594
|
+
const allFeatures = [];
|
|
595
|
+
for (const value of values) {
|
|
596
|
+
if (!value) continue;
|
|
597
|
+
const normalized = _Config.normalizeTargetFeatures(value);
|
|
598
|
+
for (const feature of normalized) {
|
|
599
|
+
if (!allFeatures.includes(feature)) {
|
|
600
|
+
allFeatures.push(feature);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
if (allFeatures.length === ALL_FEATURES.length) {
|
|
604
|
+
return allFeatures;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return allFeatures;
|
|
608
|
+
}
|
|
496
609
|
/**
|
|
497
610
|
* Returns the per-feature options object for a given target/feature, if any.
|
|
498
611
|
* Returns `undefined` when no per-feature options were provided or when the
|
|
499
612
|
* feature is not enabled for the given target.
|
|
500
613
|
*/
|
|
501
614
|
getFeatureOptions(target, feature) {
|
|
502
|
-
|
|
615
|
+
const value = isRulesyncConfigTargetsObject(this.targets) ? this.targets[target] : !Array.isArray(this.features) ? this.features[target] : void 0;
|
|
616
|
+
if (!value || Array.isArray(value)) {
|
|
503
617
|
return void 0;
|
|
504
618
|
}
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
const perFeature = targetFeatures;
|
|
510
|
-
const value = perFeature[feature];
|
|
511
|
-
if (value && typeof value === "object" && isFeatureValueEnabled(value)) {
|
|
512
|
-
return value;
|
|
619
|
+
const perFeature = value;
|
|
620
|
+
const featureValue = perFeature[feature];
|
|
621
|
+
if (featureValue && typeof featureValue === "object" && isFeatureValueEnabled(featureValue)) {
|
|
622
|
+
return featureValue;
|
|
513
623
|
}
|
|
514
624
|
return void 0;
|
|
515
625
|
}
|
|
@@ -517,6 +627,13 @@ var Config = class _Config {
|
|
|
517
627
|
* Check if per-target features configuration is being used.
|
|
518
628
|
*/
|
|
519
629
|
hasPerTargetFeatures() {
|
|
630
|
+
return isRulesyncConfigTargetsObject(this.targets) || !Array.isArray(this.features);
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Returns true if the deprecated object form under `features` is in use.
|
|
634
|
+
* Callers can use this to emit a migration warning.
|
|
635
|
+
*/
|
|
636
|
+
hasDeprecatedFeaturesObjectForm() {
|
|
520
637
|
return !Array.isArray(this.features);
|
|
521
638
|
}
|
|
522
639
|
getVerbose() {
|
|
@@ -540,6 +657,9 @@ var Config = class _Config {
|
|
|
540
657
|
getSimulateSkills() {
|
|
541
658
|
return this.simulateSkills;
|
|
542
659
|
}
|
|
660
|
+
getGitignoreTargetsOnly() {
|
|
661
|
+
return this.gitignoreTargetsOnly;
|
|
662
|
+
}
|
|
543
663
|
getDryRun() {
|
|
544
664
|
return this.dryRun;
|
|
545
665
|
}
|
|
@@ -558,6 +678,17 @@ var Config = class _Config {
|
|
|
558
678
|
}
|
|
559
679
|
};
|
|
560
680
|
|
|
681
|
+
// src/config/deprecation-warnings.ts
|
|
682
|
+
var deprecationWarningEmitted = false;
|
|
683
|
+
var emitFeaturesObjectFormDeprecationWarning = () => {
|
|
684
|
+
if (deprecationWarningEmitted) return;
|
|
685
|
+
if (process.env.RULESYNC_SILENT_DEPRECATION) return;
|
|
686
|
+
deprecationWarningEmitted = true;
|
|
687
|
+
console.warn(
|
|
688
|
+
"[rulesync] DEPRECATED: 'features' object form is deprecated. Use the new 'targets' object form instead: `targets: { claudecode: { rules: true, ignore: { fileMode: 'local' } } }`. See https://github.com/dyoshikawa/rulesync/blob/main/docs/guide/configuration.md for the migration guide."
|
|
689
|
+
);
|
|
690
|
+
};
|
|
691
|
+
|
|
561
692
|
// src/config/config-resolver.ts
|
|
562
693
|
var getDefaults = () => ({
|
|
563
694
|
targets: ["agentsmd"],
|
|
@@ -571,6 +702,7 @@ var getDefaults = () => ({
|
|
|
571
702
|
simulateCommands: false,
|
|
572
703
|
simulateSubagents: false,
|
|
573
704
|
simulateSkills: false,
|
|
705
|
+
gitignoreTargetsOnly: true,
|
|
574
706
|
dryRun: false,
|
|
575
707
|
check: false,
|
|
576
708
|
sources: []
|
|
@@ -583,6 +715,10 @@ var loadConfigFromFile = async (filePath) => {
|
|
|
583
715
|
const jsonData = (0, import_jsonc_parser.parse)(fileContent);
|
|
584
716
|
const parsed = ConfigFileSchema.parse(jsonData);
|
|
585
717
|
const { $schema: _schema, ...configParams } = parsed;
|
|
718
|
+
assertTargetsFeaturesExclusive({
|
|
719
|
+
targets: configParams.targets,
|
|
720
|
+
features: configParams.features
|
|
721
|
+
});
|
|
586
722
|
return configParams;
|
|
587
723
|
};
|
|
588
724
|
var mergeConfigs = (baseConfig, localConfig) => {
|
|
@@ -597,6 +733,7 @@ var mergeConfigs = (baseConfig, localConfig) => {
|
|
|
597
733
|
simulateCommands: localConfig.simulateCommands ?? baseConfig.simulateCommands,
|
|
598
734
|
simulateSubagents: localConfig.simulateSubagents ?? baseConfig.simulateSubagents,
|
|
599
735
|
simulateSkills: localConfig.simulateSkills ?? baseConfig.simulateSkills,
|
|
736
|
+
gitignoreTargetsOnly: localConfig.gitignoreTargetsOnly ?? baseConfig.gitignoreTargetsOnly,
|
|
600
737
|
dryRun: localConfig.dryRun ?? baseConfig.dryRun,
|
|
601
738
|
check: localConfig.check ?? baseConfig.check,
|
|
602
739
|
sources: localConfig.sources ?? baseConfig.sources
|
|
@@ -615,6 +752,7 @@ var ConfigResolver = class {
|
|
|
615
752
|
simulateCommands,
|
|
616
753
|
simulateSubagents,
|
|
617
754
|
simulateSkills,
|
|
755
|
+
gitignoreTargetsOnly,
|
|
618
756
|
dryRun,
|
|
619
757
|
check
|
|
620
758
|
}) {
|
|
@@ -624,13 +762,35 @@ var ConfigResolver = class {
|
|
|
624
762
|
const localConfigPath = (0, import_node_path4.join)(configDir, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH);
|
|
625
763
|
const localConfig = await loadConfigFromFile(localConfigPath);
|
|
626
764
|
const configByFile = mergeConfigs(baseConfig, localConfig);
|
|
765
|
+
try {
|
|
766
|
+
assertTargetsFeaturesExclusive({
|
|
767
|
+
targets: configByFile.targets,
|
|
768
|
+
features: configByFile.features
|
|
769
|
+
});
|
|
770
|
+
} catch (error) {
|
|
771
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
772
|
+
throw new Error(
|
|
773
|
+
`${detail} (detected after merging '${validatedConfigPath}' with '${localConfigPath}' \u2014 the two files combined produce the invalid combination; remove the conflicting field from one of them).`,
|
|
774
|
+
{ cause: error }
|
|
775
|
+
);
|
|
776
|
+
}
|
|
627
777
|
const resolvedGlobal = global ?? configByFile.global ?? getDefaults().global;
|
|
628
778
|
const resolvedSimulateCommands = simulateCommands ?? configByFile.simulateCommands ?? getDefaults().simulateCommands;
|
|
629
779
|
const resolvedSimulateSubagents = simulateSubagents ?? configByFile.simulateSubagents ?? getDefaults().simulateSubagents;
|
|
630
780
|
const resolvedSimulateSkills = simulateSkills ?? configByFile.simulateSkills ?? getDefaults().simulateSkills;
|
|
781
|
+
const resolvedGitignoreTargetsOnly = gitignoreTargetsOnly ?? configByFile.gitignoreTargetsOnly ?? getDefaults().gitignoreTargetsOnly;
|
|
782
|
+
const userProvidedFeatures = features ?? configByFile.features;
|
|
783
|
+
const userProvidedTargets = targets ?? configByFile.targets;
|
|
784
|
+
const targetsIsObject = userProvidedTargets !== void 0 && !Array.isArray(userProvidedTargets);
|
|
785
|
+
const featuresIsObject = userProvidedFeatures !== void 0 && !Array.isArray(userProvidedFeatures);
|
|
786
|
+
if (featuresIsObject) {
|
|
787
|
+
emitFeaturesObjectFormDeprecationWarning();
|
|
788
|
+
}
|
|
789
|
+
const resolvedFeatures = userProvidedFeatures ?? (targetsIsObject ? void 0 : getDefaults().features);
|
|
790
|
+
const resolvedTargets = userProvidedTargets ?? (featuresIsObject ? void 0 : getDefaults().targets);
|
|
631
791
|
const configParams = {
|
|
632
|
-
targets:
|
|
633
|
-
features:
|
|
792
|
+
targets: resolvedTargets,
|
|
793
|
+
features: resolvedFeatures,
|
|
634
794
|
verbose: verbose ?? configByFile.verbose ?? getDefaults().verbose,
|
|
635
795
|
delete: isDelete ?? configByFile.delete ?? getDefaults().delete,
|
|
636
796
|
baseDirs: getBaseDirsInLightOfGlobal({
|
|
@@ -642,6 +802,7 @@ var ConfigResolver = class {
|
|
|
642
802
|
simulateCommands: resolvedSimulateCommands,
|
|
643
803
|
simulateSubagents: resolvedSimulateSubagents,
|
|
644
804
|
simulateSkills: resolvedSimulateSkills,
|
|
805
|
+
gitignoreTargetsOnly: resolvedGitignoreTargetsOnly,
|
|
645
806
|
dryRun: dryRun ?? configByFile.dryRun ?? getDefaults().dryRun,
|
|
646
807
|
check: check ?? configByFile.check ?? getDefaults().check,
|
|
647
808
|
sources: configByFile.sources ?? getDefaults().sources
|
|
@@ -14807,12 +14968,16 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
|
|
|
14807
14968
|
const body = rulesyncSubagent.getBody();
|
|
14808
14969
|
const fileContent = stringifyFrontmatter(body, copilotFrontmatter);
|
|
14809
14970
|
const paths = this.getSettablePaths({ global });
|
|
14971
|
+
let relativeFilePath = rulesyncSubagent.getRelativeFilePath();
|
|
14972
|
+
if (!relativeFilePath.endsWith(".agent.md")) {
|
|
14973
|
+
relativeFilePath = relativeFilePath.replace(/\.md$/, ".agent.md");
|
|
14974
|
+
}
|
|
14810
14975
|
return new _CopilotSubagent({
|
|
14811
14976
|
baseDir,
|
|
14812
14977
|
frontmatter: copilotFrontmatter,
|
|
14813
14978
|
body,
|
|
14814
14979
|
relativeDirPath: paths.relativeDirPath,
|
|
14815
|
-
relativeFilePath
|
|
14980
|
+
relativeFilePath,
|
|
14816
14981
|
fileContent,
|
|
14817
14982
|
validate,
|
|
14818
14983
|
global
|
|
@@ -19331,7 +19496,8 @@ var rulesProcessorToolTargets = [
|
|
|
19331
19496
|
var RulesProcessorToolTargetSchema = import_mini70.z.enum(rulesProcessorToolTargets);
|
|
19332
19497
|
var formatRulePaths = (rules) => rules.map((r) => (0, import_node_path138.join)(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
|
|
19333
19498
|
var RulesFeatureOptionsSchema = import_mini70.z.looseObject({
|
|
19334
|
-
ruleDiscoveryMode: import_mini70.z.optional(import_mini70.z.enum(["none", "explicit"]))
|
|
19499
|
+
ruleDiscoveryMode: import_mini70.z.optional(import_mini70.z.enum(["none", "explicit"])),
|
|
19500
|
+
includeLocalRoot: import_mini70.z.optional(import_mini70.z.boolean())
|
|
19335
19501
|
});
|
|
19336
19502
|
var resolveRuleDiscoveryMode = ({
|
|
19337
19503
|
defaultMode,
|
|
@@ -19352,6 +19518,19 @@ var resolveRuleDiscoveryMode = ({
|
|
|
19352
19518
|
}
|
|
19353
19519
|
return parsed.data.ruleDiscoveryMode === "none" ? "auto" : "toon";
|
|
19354
19520
|
};
|
|
19521
|
+
var IncludeLocalRootSchema = import_mini70.z.looseObject({
|
|
19522
|
+
includeLocalRoot: import_mini70.z.optional(import_mini70.z.boolean())
|
|
19523
|
+
});
|
|
19524
|
+
var resolveIncludeLocalRoot = (options) => {
|
|
19525
|
+
if (!options) return true;
|
|
19526
|
+
const parsed = IncludeLocalRootSchema.safeParse(options);
|
|
19527
|
+
if (!parsed.success) {
|
|
19528
|
+
throw new Error(
|
|
19529
|
+
`Invalid options for rules feature: ${parsed.error.message}. \`includeLocalRoot\` must be a boolean.`
|
|
19530
|
+
);
|
|
19531
|
+
}
|
|
19532
|
+
return parsed.data.includeLocalRoot ?? true;
|
|
19533
|
+
};
|
|
19355
19534
|
var toolRuleFactories = /* @__PURE__ */ new Map([
|
|
19356
19535
|
[
|
|
19357
19536
|
"agentsmd",
|
|
@@ -19715,7 +19894,8 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
19715
19894
|
global: this.global
|
|
19716
19895
|
});
|
|
19717
19896
|
}).filter((rule) => rule !== null);
|
|
19718
|
-
|
|
19897
|
+
const includeLocalRoot = resolveIncludeLocalRoot(this.featureOptions);
|
|
19898
|
+
if (localRootRules.length > 0 && !this.global && includeLocalRoot) {
|
|
19719
19899
|
const localRootRule = localRootRules[0];
|
|
19720
19900
|
if (localRootRule && factory.class.isTargetedByRulesyncRule(localRootRule)) {
|
|
19721
19901
|
this.handleLocalRootRule(toolRules, localRootRule, factory);
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rulesync",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.2.0",
|
|
4
4
|
"description": "Unified AI rules management CLI tool that generates configuration files for various AI development tools",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"tsx": "4.21.0",
|
|
97
97
|
"typescript": "5.9.3",
|
|
98
98
|
"typescript-eslint": "8.57.1",
|
|
99
|
+
"vite": "7.3.1",
|
|
99
100
|
"vitepress": "1.6.4",
|
|
100
101
|
"vitest": "4.1.0"
|
|
101
102
|
},
|