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/cli/index.cjs
CHANGED
|
@@ -44,12 +44,13 @@ var FeaturesSchema = import_mini.z.array(FeatureSchema);
|
|
|
44
44
|
var FeatureOptionsSchema = import_mini.z.record(import_mini.z.string(), import_mini.z.unknown());
|
|
45
45
|
var FeatureValueSchema = import_mini.z.union([import_mini.z.boolean(), FeatureOptionsSchema]);
|
|
46
46
|
var PerFeatureConfigSchema = import_mini.z.record(import_mini.z.string(), FeatureValueSchema);
|
|
47
|
+
var PerTargetFeaturesValueSchema = import_mini.z.union([
|
|
48
|
+
import_mini.z.array(import_mini.z.enum(ALL_FEATURES_WITH_WILDCARD)),
|
|
49
|
+
PerFeatureConfigSchema
|
|
50
|
+
]);
|
|
47
51
|
var RulesyncFeaturesSchema = import_mini.z.union([
|
|
48
52
|
import_mini.z.array(import_mini.z.enum(ALL_FEATURES_WITH_WILDCARD)),
|
|
49
|
-
import_mini.z.record(
|
|
50
|
-
import_mini.z.string(),
|
|
51
|
-
import_mini.z.union([import_mini.z.array(import_mini.z.enum(ALL_FEATURES_WITH_WILDCARD)), PerFeatureConfigSchema])
|
|
52
|
-
)
|
|
53
|
+
import_mini.z.record(import_mini.z.string(), PerTargetFeaturesValueSchema)
|
|
53
54
|
]);
|
|
54
55
|
var isFeatureValueEnabled = (value) => {
|
|
55
56
|
if (value === true) return true;
|
|
@@ -951,6 +952,14 @@ var ALL_TOOL_TARGETS_WITH_WILDCARD = [...ALL_TOOL_TARGETS, "*"];
|
|
|
951
952
|
var ToolTargetSchema = import_mini3.z.enum(ALL_TOOL_TARGETS);
|
|
952
953
|
var ToolTargetsSchema = import_mini3.z.array(ToolTargetSchema);
|
|
953
954
|
var RulesyncTargetsSchema = import_mini3.z.array(import_mini3.z.enum(ALL_TOOL_TARGETS_WITH_WILDCARD));
|
|
955
|
+
var RulesyncConfigTargetsObjectSchema = import_mini3.z.record(import_mini3.z.string(), PerTargetFeaturesValueSchema);
|
|
956
|
+
var RulesyncConfigTargetsSchema = import_mini3.z.union([
|
|
957
|
+
RulesyncTargetsSchema,
|
|
958
|
+
RulesyncConfigTargetsObjectSchema
|
|
959
|
+
]);
|
|
960
|
+
var isRulesyncConfigTargetsObject = (value) => {
|
|
961
|
+
return !Array.isArray(value);
|
|
962
|
+
};
|
|
954
963
|
|
|
955
964
|
// src/features/commands/rulesync-command.ts
|
|
956
965
|
var RulesyncCommandFrontmatterSchema = import_mini4.z.looseObject({
|
|
@@ -13495,12 +13504,16 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
|
|
|
13495
13504
|
const body = rulesyncSubagent.getBody();
|
|
13496
13505
|
const fileContent = stringifyFrontmatter(body, copilotFrontmatter);
|
|
13497
13506
|
const paths = this.getSettablePaths({ global });
|
|
13507
|
+
let relativeFilePath = rulesyncSubagent.getRelativeFilePath();
|
|
13508
|
+
if (!relativeFilePath.endsWith(".agent.md")) {
|
|
13509
|
+
relativeFilePath = relativeFilePath.replace(/\.md$/, ".agent.md");
|
|
13510
|
+
}
|
|
13498
13511
|
return new _CopilotSubagent({
|
|
13499
13512
|
baseDir,
|
|
13500
13513
|
frontmatter: copilotFrontmatter,
|
|
13501
13514
|
body,
|
|
13502
13515
|
relativeDirPath: paths.relativeDirPath,
|
|
13503
|
-
relativeFilePath
|
|
13516
|
+
relativeFilePath,
|
|
13504
13517
|
fileContent,
|
|
13505
13518
|
validate,
|
|
13506
13519
|
global
|
|
@@ -18019,7 +18032,8 @@ var rulesProcessorToolTargets = [
|
|
|
18019
18032
|
var RulesProcessorToolTargetSchema = import_mini65.z.enum(rulesProcessorToolTargets);
|
|
18020
18033
|
var formatRulePaths = (rules) => rules.map((r) => (0, import_node_path131.join)(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
|
|
18021
18034
|
var RulesFeatureOptionsSchema = import_mini65.z.looseObject({
|
|
18022
|
-
ruleDiscoveryMode: import_mini65.z.optional(import_mini65.z.enum(["none", "explicit"]))
|
|
18035
|
+
ruleDiscoveryMode: import_mini65.z.optional(import_mini65.z.enum(["none", "explicit"])),
|
|
18036
|
+
includeLocalRoot: import_mini65.z.optional(import_mini65.z.boolean())
|
|
18023
18037
|
});
|
|
18024
18038
|
var resolveRuleDiscoveryMode = ({
|
|
18025
18039
|
defaultMode,
|
|
@@ -18040,6 +18054,19 @@ var resolveRuleDiscoveryMode = ({
|
|
|
18040
18054
|
}
|
|
18041
18055
|
return parsed.data.ruleDiscoveryMode === "none" ? "auto" : "toon";
|
|
18042
18056
|
};
|
|
18057
|
+
var IncludeLocalRootSchema = import_mini65.z.looseObject({
|
|
18058
|
+
includeLocalRoot: import_mini65.z.optional(import_mini65.z.boolean())
|
|
18059
|
+
});
|
|
18060
|
+
var resolveIncludeLocalRoot = (options) => {
|
|
18061
|
+
if (!options) return true;
|
|
18062
|
+
const parsed = IncludeLocalRootSchema.safeParse(options);
|
|
18063
|
+
if (!parsed.success) {
|
|
18064
|
+
throw new Error(
|
|
18065
|
+
`Invalid options for rules feature: ${parsed.error.message}. \`includeLocalRoot\` must be a boolean.`
|
|
18066
|
+
);
|
|
18067
|
+
}
|
|
18068
|
+
return parsed.data.includeLocalRoot ?? true;
|
|
18069
|
+
};
|
|
18043
18070
|
var toolRuleFactories = /* @__PURE__ */ new Map([
|
|
18044
18071
|
[
|
|
18045
18072
|
"agentsmd",
|
|
@@ -18403,7 +18430,8 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
18403
18430
|
global: this.global
|
|
18404
18431
|
});
|
|
18405
18432
|
}).filter((rule) => rule !== null);
|
|
18406
|
-
|
|
18433
|
+
const includeLocalRoot = resolveIncludeLocalRoot(this.featureOptions);
|
|
18434
|
+
if (localRootRules.length > 0 && !this.global && includeLocalRoot) {
|
|
18407
18435
|
const localRootRule = localRootRules[0];
|
|
18408
18436
|
if (localRootRule && factory.class.isTargetedByRulesyncRule(localRootRule)) {
|
|
18409
18437
|
this.handleLocalRootRule(toolRules, localRootRule, factory);
|
|
@@ -19975,7 +20003,7 @@ var SourceEntrySchema = import_mini69.z.object({
|
|
|
19975
20003
|
});
|
|
19976
20004
|
var ConfigParamsSchema = import_mini69.z.object({
|
|
19977
20005
|
baseDirs: import_mini69.z.array(import_mini69.z.string()),
|
|
19978
|
-
targets:
|
|
20006
|
+
targets: RulesyncConfigTargetsSchema,
|
|
19979
20007
|
features: RulesyncFeaturesSchema,
|
|
19980
20008
|
verbose: import_mini69.z.boolean(),
|
|
19981
20009
|
delete: import_mini69.z.boolean(),
|
|
@@ -19985,6 +20013,7 @@ var ConfigParamsSchema = import_mini69.z.object({
|
|
|
19985
20013
|
simulateCommands: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
19986
20014
|
simulateSubagents: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
19987
20015
|
simulateSkills: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
20016
|
+
gitignoreTargetsOnly: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
19988
20017
|
dryRun: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
19989
20018
|
check: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
19990
20019
|
// Declarative skill sources
|
|
@@ -20001,10 +20030,42 @@ var CONFLICTING_TARGET_PAIRS = [
|
|
|
20001
20030
|
["claudecode", "claudecode-legacy"]
|
|
20002
20031
|
];
|
|
20003
20032
|
var LEGACY_TARGETS = ["augmentcode-legacy", "claudecode-legacy"];
|
|
20033
|
+
var assertTargetsFeaturesExclusive = ({
|
|
20034
|
+
targets,
|
|
20035
|
+
features
|
|
20036
|
+
}) => {
|
|
20037
|
+
const targetsIsObject = targets !== void 0 && !Array.isArray(targets);
|
|
20038
|
+
const featuresIsObject = features !== void 0 && !Array.isArray(features);
|
|
20039
|
+
if (targetsIsObject && features !== void 0) {
|
|
20040
|
+
throw new Error(
|
|
20041
|
+
"Invalid config: when 'targets' is in object form, 'features' must be omitted. Declare per-target features inside the 'targets' object instead."
|
|
20042
|
+
);
|
|
20043
|
+
}
|
|
20044
|
+
if (featuresIsObject && targets !== void 0) {
|
|
20045
|
+
throw new Error(
|
|
20046
|
+
"Invalid config: when 'features' is in object form, 'targets' must be omitted. Migrate to the 'targets' object form, e.g. `targets: { claudecode: [...] }`."
|
|
20047
|
+
);
|
|
20048
|
+
}
|
|
20049
|
+
};
|
|
20050
|
+
var assertTargetsOrFeaturesProvided = ({
|
|
20051
|
+
targets,
|
|
20052
|
+
features
|
|
20053
|
+
}) => {
|
|
20054
|
+
if (targets === void 0 && features === void 0) {
|
|
20055
|
+
throw new Error("Invalid config: at least one of 'targets' or 'features' must be provided.");
|
|
20056
|
+
}
|
|
20057
|
+
};
|
|
20004
20058
|
var Config = class _Config {
|
|
20005
20059
|
baseDirs;
|
|
20006
20060
|
targets;
|
|
20007
20061
|
features;
|
|
20062
|
+
/**
|
|
20063
|
+
* Cached list of validated `ToolTarget` keys for the object form of
|
|
20064
|
+
* `targets`. Populated in the constructor after `validateObjectFormTargetKeys`
|
|
20065
|
+
* so `getTargets()` does not rebuild the `ALL_TOOL_TARGETS` set on every call.
|
|
20066
|
+
* Undefined when `this.targets` is in array form.
|
|
20067
|
+
*/
|
|
20068
|
+
objectFormTargetKeys;
|
|
20008
20069
|
verbose;
|
|
20009
20070
|
delete;
|
|
20010
20071
|
global;
|
|
@@ -20012,6 +20073,7 @@ var Config = class _Config {
|
|
|
20012
20073
|
simulateCommands;
|
|
20013
20074
|
simulateSubagents;
|
|
20014
20075
|
simulateSkills;
|
|
20076
|
+
gitignoreTargetsOnly;
|
|
20015
20077
|
dryRun;
|
|
20016
20078
|
check;
|
|
20017
20079
|
sources;
|
|
@@ -20026,17 +20088,24 @@ var Config = class _Config {
|
|
|
20026
20088
|
simulateCommands,
|
|
20027
20089
|
simulateSubagents,
|
|
20028
20090
|
simulateSkills,
|
|
20091
|
+
gitignoreTargetsOnly,
|
|
20029
20092
|
dryRun,
|
|
20030
20093
|
check,
|
|
20031
20094
|
sources
|
|
20032
20095
|
}) {
|
|
20033
|
-
|
|
20096
|
+
assertTargetsFeaturesExclusive({ targets, features });
|
|
20097
|
+
assertTargetsOrFeaturesProvided({ targets, features });
|
|
20098
|
+
const resolvedTargets = targets ?? [];
|
|
20099
|
+
const resolvedFeatures = features ?? [];
|
|
20100
|
+
this.validateObjectFormTargetKeys(resolvedTargets);
|
|
20101
|
+
this.validateConflictingTargets(resolvedTargets);
|
|
20034
20102
|
if (dryRun && check) {
|
|
20035
20103
|
throw new Error("--dry-run and --check cannot be used together");
|
|
20036
20104
|
}
|
|
20037
20105
|
this.baseDirs = baseDirs;
|
|
20038
|
-
this.targets =
|
|
20039
|
-
this.features =
|
|
20106
|
+
this.targets = resolvedTargets;
|
|
20107
|
+
this.features = resolvedFeatures;
|
|
20108
|
+
this.objectFormTargetKeys = isRulesyncConfigTargetsObject(resolvedTargets) ? _Config.filterValidToolTargets(Object.keys(resolvedTargets)) : void 0;
|
|
20040
20109
|
this.verbose = verbose;
|
|
20041
20110
|
this.delete = isDelete;
|
|
20042
20111
|
this.global = global ?? false;
|
|
@@ -20044,15 +20113,42 @@ var Config = class _Config {
|
|
|
20044
20113
|
this.simulateCommands = simulateCommands ?? false;
|
|
20045
20114
|
this.simulateSubagents = simulateSubagents ?? false;
|
|
20046
20115
|
this.simulateSkills = simulateSkills ?? false;
|
|
20116
|
+
this.gitignoreTargetsOnly = gitignoreTargetsOnly ?? true;
|
|
20047
20117
|
this.dryRun = dryRun ?? false;
|
|
20048
20118
|
this.check = check ?? false;
|
|
20049
20119
|
this.sources = sources ?? [];
|
|
20050
20120
|
}
|
|
20121
|
+
/**
|
|
20122
|
+
* Rejects unknown keys (and the special `*` key) in the object form of
|
|
20123
|
+
* `targets`. For the array form this is already enforced at the Zod schema
|
|
20124
|
+
* level via `z.enum(ALL_TOOL_TARGETS_WITH_WILDCARD)`; for the object form
|
|
20125
|
+
* `z.record(z.string(), ...)` intentionally accepts any string key (to work
|
|
20126
|
+
* around zod's `z.record(z.enum(...))` requiring ALL enum members), so
|
|
20127
|
+
* runtime validation lives here instead.
|
|
20128
|
+
*/
|
|
20129
|
+
validateObjectFormTargetKeys(targets) {
|
|
20130
|
+
if (Array.isArray(targets)) return;
|
|
20131
|
+
const validTargets = new Set(ALL_TOOL_TARGETS);
|
|
20132
|
+
for (const key of Object.keys(targets)) {
|
|
20133
|
+
if (key === "*") {
|
|
20134
|
+
throw new Error(
|
|
20135
|
+
"Invalid target '*' in object form: wildcard is only supported in the array form `targets: ['*']`. Per-target options cannot be attached to a wildcard."
|
|
20136
|
+
);
|
|
20137
|
+
}
|
|
20138
|
+
if (!validTargets.has(key)) {
|
|
20139
|
+
throw new Error(`Unknown target '${key}'. Valid targets: ${ALL_TOOL_TARGETS.join(", ")}.`);
|
|
20140
|
+
}
|
|
20141
|
+
}
|
|
20142
|
+
}
|
|
20051
20143
|
validateConflictingTargets(targets) {
|
|
20144
|
+
const has = (target) => {
|
|
20145
|
+
if (Array.isArray(targets)) {
|
|
20146
|
+
return targets.includes(target);
|
|
20147
|
+
}
|
|
20148
|
+
return Object.prototype.hasOwnProperty.call(targets, target);
|
|
20149
|
+
};
|
|
20052
20150
|
for (const [target1, target2] of CONFLICTING_TARGET_PAIRS) {
|
|
20053
|
-
|
|
20054
|
-
const hasTarget2 = targets.includes(target2);
|
|
20055
|
-
if (hasTarget1 && hasTarget2) {
|
|
20151
|
+
if (has(target1) && has(target2)) {
|
|
20056
20152
|
throw new Error(
|
|
20057
20153
|
`Conflicting targets: '${target1}' and '${target2}' cannot be used together. Please choose one.`
|
|
20058
20154
|
);
|
|
@@ -20062,16 +20158,45 @@ var Config = class _Config {
|
|
|
20062
20158
|
getBaseDirs() {
|
|
20063
20159
|
return this.baseDirs;
|
|
20064
20160
|
}
|
|
20161
|
+
/**
|
|
20162
|
+
* Filter an arbitrary string-key list down to the known `ToolTarget` set,
|
|
20163
|
+
* skipping `*` (which is only meaningful as an array element, not a key).
|
|
20164
|
+
*/
|
|
20165
|
+
static filterValidToolTargets(keys) {
|
|
20166
|
+
const validTargets = new Set(ALL_TOOL_TARGETS);
|
|
20167
|
+
const result = [];
|
|
20168
|
+
for (const key of keys) {
|
|
20169
|
+
if (key === "*") continue;
|
|
20170
|
+
if (!validTargets.has(key)) continue;
|
|
20171
|
+
result.push(key);
|
|
20172
|
+
}
|
|
20173
|
+
return result;
|
|
20174
|
+
}
|
|
20065
20175
|
getTargets() {
|
|
20066
|
-
if (this.
|
|
20176
|
+
if (this.objectFormTargetKeys !== void 0) {
|
|
20177
|
+
return this.objectFormTargetKeys;
|
|
20178
|
+
}
|
|
20179
|
+
const arrayTargets = Array.isArray(this.targets) ? this.targets : [];
|
|
20180
|
+
if (!Array.isArray(this.features)) {
|
|
20181
|
+
return _Config.filterValidToolTargets(Object.keys(this.features));
|
|
20182
|
+
}
|
|
20183
|
+
if (arrayTargets.includes("*")) {
|
|
20067
20184
|
return ALL_TOOL_TARGETS.filter(
|
|
20068
20185
|
// eslint-disable-next-line no-type-assertion/no-type-assertion
|
|
20069
20186
|
(target) => !LEGACY_TARGETS.includes(target)
|
|
20070
20187
|
);
|
|
20071
20188
|
}
|
|
20072
|
-
return
|
|
20189
|
+
return arrayTargets.filter((target) => target !== "*");
|
|
20073
20190
|
}
|
|
20074
20191
|
getFeatures(target) {
|
|
20192
|
+
if (isRulesyncConfigTargetsObject(this.targets)) {
|
|
20193
|
+
if (target) {
|
|
20194
|
+
const value = this.targets[target];
|
|
20195
|
+
if (!value) return [];
|
|
20196
|
+
return _Config.normalizeTargetFeatures(value);
|
|
20197
|
+
}
|
|
20198
|
+
return _Config.collectAllFeatures(Object.values(this.targets));
|
|
20199
|
+
}
|
|
20075
20200
|
if (!Array.isArray(this.features)) {
|
|
20076
20201
|
const perTargetFeatures = this.features;
|
|
20077
20202
|
if (target) {
|
|
@@ -20081,20 +20206,7 @@ var Config = class _Config {
|
|
|
20081
20206
|
}
|
|
20082
20207
|
return _Config.normalizeTargetFeatures(targetFeatures);
|
|
20083
20208
|
}
|
|
20084
|
-
|
|
20085
|
-
for (const features of Object.values(perTargetFeatures)) {
|
|
20086
|
-
if (!features) continue;
|
|
20087
|
-
const normalized = _Config.normalizeTargetFeatures(features);
|
|
20088
|
-
for (const feature of normalized) {
|
|
20089
|
-
if (!allFeatures.includes(feature)) {
|
|
20090
|
-
allFeatures.push(feature);
|
|
20091
|
-
}
|
|
20092
|
-
}
|
|
20093
|
-
if (allFeatures.length === ALL_FEATURES.length) {
|
|
20094
|
-
return allFeatures;
|
|
20095
|
-
}
|
|
20096
|
-
}
|
|
20097
|
-
return allFeatures;
|
|
20209
|
+
return _Config.collectAllFeatures(Object.values(perTargetFeatures));
|
|
20098
20210
|
}
|
|
20099
20211
|
if (this.features.includes("*")) {
|
|
20100
20212
|
return [...ALL_FEATURES];
|
|
@@ -20122,23 +20234,40 @@ var Config = class _Config {
|
|
|
20122
20234
|
}
|
|
20123
20235
|
return enabled;
|
|
20124
20236
|
}
|
|
20237
|
+
/**
|
|
20238
|
+
* Collect the union of features across all per-target values.
|
|
20239
|
+
* Used when `getFeatures()` is called without a target in object mode.
|
|
20240
|
+
*/
|
|
20241
|
+
static collectAllFeatures(values) {
|
|
20242
|
+
const allFeatures = [];
|
|
20243
|
+
for (const value of values) {
|
|
20244
|
+
if (!value) continue;
|
|
20245
|
+
const normalized = _Config.normalizeTargetFeatures(value);
|
|
20246
|
+
for (const feature of normalized) {
|
|
20247
|
+
if (!allFeatures.includes(feature)) {
|
|
20248
|
+
allFeatures.push(feature);
|
|
20249
|
+
}
|
|
20250
|
+
}
|
|
20251
|
+
if (allFeatures.length === ALL_FEATURES.length) {
|
|
20252
|
+
return allFeatures;
|
|
20253
|
+
}
|
|
20254
|
+
}
|
|
20255
|
+
return allFeatures;
|
|
20256
|
+
}
|
|
20125
20257
|
/**
|
|
20126
20258
|
* Returns the per-feature options object for a given target/feature, if any.
|
|
20127
20259
|
* Returns `undefined` when no per-feature options were provided or when the
|
|
20128
20260
|
* feature is not enabled for the given target.
|
|
20129
20261
|
*/
|
|
20130
20262
|
getFeatureOptions(target, feature) {
|
|
20131
|
-
|
|
20132
|
-
|
|
20133
|
-
}
|
|
20134
|
-
const targetFeatures = this.features[target];
|
|
20135
|
-
if (!targetFeatures || Array.isArray(targetFeatures)) {
|
|
20263
|
+
const value = isRulesyncConfigTargetsObject(this.targets) ? this.targets[target] : !Array.isArray(this.features) ? this.features[target] : void 0;
|
|
20264
|
+
if (!value || Array.isArray(value)) {
|
|
20136
20265
|
return void 0;
|
|
20137
20266
|
}
|
|
20138
|
-
const perFeature =
|
|
20139
|
-
const
|
|
20140
|
-
if (
|
|
20141
|
-
return
|
|
20267
|
+
const perFeature = value;
|
|
20268
|
+
const featureValue = perFeature[feature];
|
|
20269
|
+
if (featureValue && typeof featureValue === "object" && isFeatureValueEnabled(featureValue)) {
|
|
20270
|
+
return featureValue;
|
|
20142
20271
|
}
|
|
20143
20272
|
return void 0;
|
|
20144
20273
|
}
|
|
@@ -20146,6 +20275,13 @@ var Config = class _Config {
|
|
|
20146
20275
|
* Check if per-target features configuration is being used.
|
|
20147
20276
|
*/
|
|
20148
20277
|
hasPerTargetFeatures() {
|
|
20278
|
+
return isRulesyncConfigTargetsObject(this.targets) || !Array.isArray(this.features);
|
|
20279
|
+
}
|
|
20280
|
+
/**
|
|
20281
|
+
* Returns true if the deprecated object form under `features` is in use.
|
|
20282
|
+
* Callers can use this to emit a migration warning.
|
|
20283
|
+
*/
|
|
20284
|
+
hasDeprecatedFeaturesObjectForm() {
|
|
20149
20285
|
return !Array.isArray(this.features);
|
|
20150
20286
|
}
|
|
20151
20287
|
getVerbose() {
|
|
@@ -20169,6 +20305,9 @@ var Config = class _Config {
|
|
|
20169
20305
|
getSimulateSkills() {
|
|
20170
20306
|
return this.simulateSkills;
|
|
20171
20307
|
}
|
|
20308
|
+
getGitignoreTargetsOnly() {
|
|
20309
|
+
return this.gitignoreTargetsOnly;
|
|
20310
|
+
}
|
|
20172
20311
|
getDryRun() {
|
|
20173
20312
|
return this.dryRun;
|
|
20174
20313
|
}
|
|
@@ -20187,6 +20326,17 @@ var Config = class _Config {
|
|
|
20187
20326
|
}
|
|
20188
20327
|
};
|
|
20189
20328
|
|
|
20329
|
+
// src/config/deprecation-warnings.ts
|
|
20330
|
+
var deprecationWarningEmitted = false;
|
|
20331
|
+
var emitFeaturesObjectFormDeprecationWarning = () => {
|
|
20332
|
+
if (deprecationWarningEmitted) return;
|
|
20333
|
+
if (process.env.RULESYNC_SILENT_DEPRECATION) return;
|
|
20334
|
+
deprecationWarningEmitted = true;
|
|
20335
|
+
console.warn(
|
|
20336
|
+
"[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."
|
|
20337
|
+
);
|
|
20338
|
+
};
|
|
20339
|
+
|
|
20190
20340
|
// src/config/config-resolver.ts
|
|
20191
20341
|
var getDefaults = () => ({
|
|
20192
20342
|
targets: ["agentsmd"],
|
|
@@ -20200,6 +20350,7 @@ var getDefaults = () => ({
|
|
|
20200
20350
|
simulateCommands: false,
|
|
20201
20351
|
simulateSubagents: false,
|
|
20202
20352
|
simulateSkills: false,
|
|
20353
|
+
gitignoreTargetsOnly: true,
|
|
20203
20354
|
dryRun: false,
|
|
20204
20355
|
check: false,
|
|
20205
20356
|
sources: []
|
|
@@ -20212,6 +20363,10 @@ var loadConfigFromFile = async (filePath) => {
|
|
|
20212
20363
|
const jsonData = (0, import_jsonc_parser4.parse)(fileContent);
|
|
20213
20364
|
const parsed = ConfigFileSchema.parse(jsonData);
|
|
20214
20365
|
const { $schema: _schema, ...configParams } = parsed;
|
|
20366
|
+
assertTargetsFeaturesExclusive({
|
|
20367
|
+
targets: configParams.targets,
|
|
20368
|
+
features: configParams.features
|
|
20369
|
+
});
|
|
20215
20370
|
return configParams;
|
|
20216
20371
|
};
|
|
20217
20372
|
var mergeConfigs = (baseConfig, localConfig) => {
|
|
@@ -20226,6 +20381,7 @@ var mergeConfigs = (baseConfig, localConfig) => {
|
|
|
20226
20381
|
simulateCommands: localConfig.simulateCommands ?? baseConfig.simulateCommands,
|
|
20227
20382
|
simulateSubagents: localConfig.simulateSubagents ?? baseConfig.simulateSubagents,
|
|
20228
20383
|
simulateSkills: localConfig.simulateSkills ?? baseConfig.simulateSkills,
|
|
20384
|
+
gitignoreTargetsOnly: localConfig.gitignoreTargetsOnly ?? baseConfig.gitignoreTargetsOnly,
|
|
20229
20385
|
dryRun: localConfig.dryRun ?? baseConfig.dryRun,
|
|
20230
20386
|
check: localConfig.check ?? baseConfig.check,
|
|
20231
20387
|
sources: localConfig.sources ?? baseConfig.sources
|
|
@@ -20244,6 +20400,7 @@ var ConfigResolver = class {
|
|
|
20244
20400
|
simulateCommands,
|
|
20245
20401
|
simulateSubagents,
|
|
20246
20402
|
simulateSkills,
|
|
20403
|
+
gitignoreTargetsOnly,
|
|
20247
20404
|
dryRun,
|
|
20248
20405
|
check
|
|
20249
20406
|
}) {
|
|
@@ -20253,13 +20410,35 @@ var ConfigResolver = class {
|
|
|
20253
20410
|
const localConfigPath = (0, import_node_path134.join)(configDir, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH);
|
|
20254
20411
|
const localConfig = await loadConfigFromFile(localConfigPath);
|
|
20255
20412
|
const configByFile = mergeConfigs(baseConfig, localConfig);
|
|
20413
|
+
try {
|
|
20414
|
+
assertTargetsFeaturesExclusive({
|
|
20415
|
+
targets: configByFile.targets,
|
|
20416
|
+
features: configByFile.features
|
|
20417
|
+
});
|
|
20418
|
+
} catch (error) {
|
|
20419
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
20420
|
+
throw new Error(
|
|
20421
|
+
`${detail} (detected after merging '${validatedConfigPath}' with '${localConfigPath}' \u2014 the two files combined produce the invalid combination; remove the conflicting field from one of them).`,
|
|
20422
|
+
{ cause: error }
|
|
20423
|
+
);
|
|
20424
|
+
}
|
|
20256
20425
|
const resolvedGlobal = global ?? configByFile.global ?? getDefaults().global;
|
|
20257
20426
|
const resolvedSimulateCommands = simulateCommands ?? configByFile.simulateCommands ?? getDefaults().simulateCommands;
|
|
20258
20427
|
const resolvedSimulateSubagents = simulateSubagents ?? configByFile.simulateSubagents ?? getDefaults().simulateSubagents;
|
|
20259
20428
|
const resolvedSimulateSkills = simulateSkills ?? configByFile.simulateSkills ?? getDefaults().simulateSkills;
|
|
20429
|
+
const resolvedGitignoreTargetsOnly = gitignoreTargetsOnly ?? configByFile.gitignoreTargetsOnly ?? getDefaults().gitignoreTargetsOnly;
|
|
20430
|
+
const userProvidedFeatures = features ?? configByFile.features;
|
|
20431
|
+
const userProvidedTargets = targets ?? configByFile.targets;
|
|
20432
|
+
const targetsIsObject = userProvidedTargets !== void 0 && !Array.isArray(userProvidedTargets);
|
|
20433
|
+
const featuresIsObject = userProvidedFeatures !== void 0 && !Array.isArray(userProvidedFeatures);
|
|
20434
|
+
if (featuresIsObject) {
|
|
20435
|
+
emitFeaturesObjectFormDeprecationWarning();
|
|
20436
|
+
}
|
|
20437
|
+
const resolvedFeatures = userProvidedFeatures ?? (targetsIsObject ? void 0 : getDefaults().features);
|
|
20438
|
+
const resolvedTargets = userProvidedTargets ?? (featuresIsObject ? void 0 : getDefaults().targets);
|
|
20260
20439
|
const configParams = {
|
|
20261
|
-
targets:
|
|
20262
|
-
features:
|
|
20440
|
+
targets: resolvedTargets,
|
|
20441
|
+
features: resolvedFeatures,
|
|
20263
20442
|
verbose: verbose ?? configByFile.verbose ?? getDefaults().verbose,
|
|
20264
20443
|
delete: isDelete ?? configByFile.delete ?? getDefaults().delete,
|
|
20265
20444
|
baseDirs: getBaseDirsInLightOfGlobal({
|
|
@@ -20271,6 +20450,7 @@ var ConfigResolver = class {
|
|
|
20271
20450
|
simulateCommands: resolvedSimulateCommands,
|
|
20272
20451
|
simulateSubagents: resolvedSimulateSubagents,
|
|
20273
20452
|
simulateSkills: resolvedSimulateSkills,
|
|
20453
|
+
gitignoreTargetsOnly: resolvedGitignoreTargetsOnly,
|
|
20274
20454
|
dryRun: dryRun ?? configByFile.dryRun ?? getDefaults().dryRun,
|
|
20275
20455
|
check: check ?? configByFile.check ?? getDefaults().check,
|
|
20276
20456
|
sources: configByFile.sources ?? getDefaults().sources
|
|
@@ -21860,6 +22040,7 @@ var GITIGNORE_ENTRY_REGISTRY = [
|
|
|
21860
22040
|
feature: "general",
|
|
21861
22041
|
entry: "**/.claude/settings.local.json"
|
|
21862
22042
|
},
|
|
22043
|
+
{ target: "claudecode", feature: "general", entry: "**/.claude/*.lock" },
|
|
21863
22044
|
// Cline
|
|
21864
22045
|
{ target: "cline", feature: "rules", entry: "**/.clinerules/" },
|
|
21865
22046
|
{ target: "cline", feature: "commands", entry: "**/.clinerules/workflows/" },
|
|
@@ -21968,6 +22149,11 @@ var GITIGNORE_ENTRY_REGISTRY = [
|
|
|
21968
22149
|
{ target: "opencode", feature: "skills", entry: "**/.opencode/skill/" },
|
|
21969
22150
|
{ target: "opencode", feature: "mcp", entry: "**/.opencode/plugins/" },
|
|
21970
22151
|
{ target: "opencode", feature: "general", entry: "**/.opencode/memories/" },
|
|
22152
|
+
{
|
|
22153
|
+
target: "opencode",
|
|
22154
|
+
feature: "general",
|
|
22155
|
+
entry: "**/.opencode/package-lock.json"
|
|
22156
|
+
},
|
|
21971
22157
|
// Qwen Code
|
|
21972
22158
|
{ target: "qwencode", feature: "rules", entry: "**/QWEN.md" },
|
|
21973
22159
|
{ target: "qwencode", feature: "general", entry: "**/.qwen/memories/" },
|
|
@@ -22473,6 +22659,12 @@ async function importCommand(logger5, options) {
|
|
|
22473
22659
|
if (!options.targets) {
|
|
22474
22660
|
throw new CLIError("No tools found in --targets", ErrorCodes.IMPORT_FAILED);
|
|
22475
22661
|
}
|
|
22662
|
+
if (!Array.isArray(options.targets)) {
|
|
22663
|
+
throw new CLIError(
|
|
22664
|
+
"--targets object form is not supported on the command line",
|
|
22665
|
+
ErrorCodes.IMPORT_FAILED
|
|
22666
|
+
);
|
|
22667
|
+
}
|
|
22476
22668
|
if (options.targets.length > 1) {
|
|
22477
22669
|
throw new CLIError("Only one tool can be imported at a time", ErrorCodes.IMPORT_FAILED);
|
|
22478
22670
|
}
|
|
@@ -22541,7 +22733,8 @@ async function createConfigFile() {
|
|
|
22541
22733
|
global: false,
|
|
22542
22734
|
simulateCommands: false,
|
|
22543
22735
|
simulateSubagents: false,
|
|
22544
|
-
simulateSkills: false
|
|
22736
|
+
simulateSkills: false,
|
|
22737
|
+
gitignoreTargetsOnly: true
|
|
22545
22738
|
},
|
|
22546
22739
|
null,
|
|
22547
22740
|
2
|
|
@@ -25152,6 +25345,35 @@ async function mcpCommand(logger5, { version }) {
|
|
|
25152
25345
|
});
|
|
25153
25346
|
}
|
|
25154
25347
|
|
|
25348
|
+
// src/cli/commands/resolve-gitignore-targets.ts
|
|
25349
|
+
var import_node_path152 = require("path");
|
|
25350
|
+
var resolveGitignoreTargets = async ({
|
|
25351
|
+
cliTargets,
|
|
25352
|
+
cwd = process.cwd()
|
|
25353
|
+
}) => {
|
|
25354
|
+
if (cliTargets !== void 0) {
|
|
25355
|
+
return cliTargets;
|
|
25356
|
+
}
|
|
25357
|
+
const baseConfigPath = (0, import_node_path152.join)(cwd, RULESYNC_CONFIG_RELATIVE_FILE_PATH);
|
|
25358
|
+
const localConfigPath = (0, import_node_path152.join)(cwd, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH);
|
|
25359
|
+
const [hasBase, hasLocal] = await Promise.all([
|
|
25360
|
+
fileExists(baseConfigPath),
|
|
25361
|
+
fileExists(localConfigPath)
|
|
25362
|
+
]);
|
|
25363
|
+
if (!hasBase && !hasLocal) {
|
|
25364
|
+
return void 0;
|
|
25365
|
+
}
|
|
25366
|
+
const config = await ConfigResolver.resolve({});
|
|
25367
|
+
if (config.getGitignoreTargetsOnly()) {
|
|
25368
|
+
const targets = config.getTargets();
|
|
25369
|
+
if (targets.includes("agentsmd")) {
|
|
25370
|
+
return targets;
|
|
25371
|
+
}
|
|
25372
|
+
return [...targets, "agentsmd"];
|
|
25373
|
+
}
|
|
25374
|
+
return void 0;
|
|
25375
|
+
};
|
|
25376
|
+
|
|
25155
25377
|
// src/lib/update.ts
|
|
25156
25378
|
var crypto = __toESM(require("crypto"), 1);
|
|
25157
25379
|
var fs = __toESM(require("fs"), 1);
|
|
@@ -25554,7 +25776,7 @@ function wrapCommand({
|
|
|
25554
25776
|
}
|
|
25555
25777
|
|
|
25556
25778
|
// src/cli/index.ts
|
|
25557
|
-
var getVersion = () => "8.
|
|
25779
|
+
var getVersion = () => "8.2.0";
|
|
25558
25780
|
function wrapCommand2(name, errorCode, handler) {
|
|
25559
25781
|
return wrapCommand({ name, errorCode, handler, getVersion });
|
|
25560
25782
|
}
|
|
@@ -25577,11 +25799,12 @@ var main = async () => {
|
|
|
25577
25799
|
parseCommaSeparatedList
|
|
25578
25800
|
).option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").action(
|
|
25579
25801
|
wrapCommand2("gitignore", "GITIGNORE_FAILED", async (logger5, options) => {
|
|
25802
|
+
const cliTargets = options.targets;
|
|
25803
|
+
const cliFeatures = options.features;
|
|
25804
|
+
const resolvedTargets = await resolveGitignoreTargets({ cliTargets });
|
|
25580
25805
|
await gitignoreCommand(logger5, {
|
|
25581
|
-
|
|
25582
|
-
|
|
25583
|
-
// eslint-disable-next-line no-type-assertion/no-type-assertion
|
|
25584
|
-
features: options.features
|
|
25806
|
+
targets: resolvedTargets ? [...resolvedTargets] : void 0,
|
|
25807
|
+
features: cliFeatures
|
|
25585
25808
|
});
|
|
25586
25809
|
})
|
|
25587
25810
|
);
|
package/dist/cli/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
RULESYNC_HOOKS_FILE_NAME,
|
|
25
25
|
RULESYNC_HOOKS_RELATIVE_FILE_PATH,
|
|
26
26
|
RULESYNC_IGNORE_RELATIVE_FILE_PATH,
|
|
27
|
+
RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH,
|
|
27
28
|
RULESYNC_MCP_FILE_NAME,
|
|
28
29
|
RULESYNC_MCP_RELATIVE_FILE_PATH,
|
|
29
30
|
RULESYNC_MCP_SCHEMA_URL,
|
|
@@ -72,7 +73,7 @@ import {
|
|
|
72
73
|
stringifyFrontmatter,
|
|
73
74
|
toPosixPath,
|
|
74
75
|
writeFileContent
|
|
75
|
-
} from "../chunk-
|
|
76
|
+
} from "../chunk-K4IN6URH.js";
|
|
76
77
|
|
|
77
78
|
// src/cli/index.ts
|
|
78
79
|
import { Command } from "commander";
|
|
@@ -1196,6 +1197,7 @@ var GITIGNORE_ENTRY_REGISTRY = [
|
|
|
1196
1197
|
feature: "general",
|
|
1197
1198
|
entry: "**/.claude/settings.local.json"
|
|
1198
1199
|
},
|
|
1200
|
+
{ target: "claudecode", feature: "general", entry: "**/.claude/*.lock" },
|
|
1199
1201
|
// Cline
|
|
1200
1202
|
{ target: "cline", feature: "rules", entry: "**/.clinerules/" },
|
|
1201
1203
|
{ target: "cline", feature: "commands", entry: "**/.clinerules/workflows/" },
|
|
@@ -1304,6 +1306,11 @@ var GITIGNORE_ENTRY_REGISTRY = [
|
|
|
1304
1306
|
{ target: "opencode", feature: "skills", entry: "**/.opencode/skill/" },
|
|
1305
1307
|
{ target: "opencode", feature: "mcp", entry: "**/.opencode/plugins/" },
|
|
1306
1308
|
{ target: "opencode", feature: "general", entry: "**/.opencode/memories/" },
|
|
1309
|
+
{
|
|
1310
|
+
target: "opencode",
|
|
1311
|
+
feature: "general",
|
|
1312
|
+
entry: "**/.opencode/package-lock.json"
|
|
1313
|
+
},
|
|
1307
1314
|
// Qwen Code
|
|
1308
1315
|
{ target: "qwencode", feature: "rules", entry: "**/QWEN.md" },
|
|
1309
1316
|
{ target: "qwencode", feature: "general", entry: "**/.qwen/memories/" },
|
|
@@ -1545,6 +1552,12 @@ async function importCommand(logger5, options) {
|
|
|
1545
1552
|
if (!options.targets) {
|
|
1546
1553
|
throw new CLIError("No tools found in --targets", ErrorCodes.IMPORT_FAILED);
|
|
1547
1554
|
}
|
|
1555
|
+
if (!Array.isArray(options.targets)) {
|
|
1556
|
+
throw new CLIError(
|
|
1557
|
+
"--targets object form is not supported on the command line",
|
|
1558
|
+
ErrorCodes.IMPORT_FAILED
|
|
1559
|
+
);
|
|
1560
|
+
}
|
|
1548
1561
|
if (options.targets.length > 1) {
|
|
1549
1562
|
throw new CLIError("Only one tool can be imported at a time", ErrorCodes.IMPORT_FAILED);
|
|
1550
1563
|
}
|
|
@@ -1613,7 +1626,8 @@ async function createConfigFile() {
|
|
|
1613
1626
|
global: false,
|
|
1614
1627
|
simulateCommands: false,
|
|
1615
1628
|
simulateSubagents: false,
|
|
1616
|
-
simulateSkills: false
|
|
1629
|
+
simulateSkills: false,
|
|
1630
|
+
gitignoreTargetsOnly: true
|
|
1617
1631
|
},
|
|
1618
1632
|
null,
|
|
1619
1633
|
2
|
|
@@ -4078,6 +4092,35 @@ async function mcpCommand(logger5, { version }) {
|
|
|
4078
4092
|
});
|
|
4079
4093
|
}
|
|
4080
4094
|
|
|
4095
|
+
// src/cli/commands/resolve-gitignore-targets.ts
|
|
4096
|
+
import { join as join13 } from "path";
|
|
4097
|
+
var resolveGitignoreTargets = async ({
|
|
4098
|
+
cliTargets,
|
|
4099
|
+
cwd = process.cwd()
|
|
4100
|
+
}) => {
|
|
4101
|
+
if (cliTargets !== void 0) {
|
|
4102
|
+
return cliTargets;
|
|
4103
|
+
}
|
|
4104
|
+
const baseConfigPath = join13(cwd, RULESYNC_CONFIG_RELATIVE_FILE_PATH);
|
|
4105
|
+
const localConfigPath = join13(cwd, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH);
|
|
4106
|
+
const [hasBase, hasLocal] = await Promise.all([
|
|
4107
|
+
fileExists(baseConfigPath),
|
|
4108
|
+
fileExists(localConfigPath)
|
|
4109
|
+
]);
|
|
4110
|
+
if (!hasBase && !hasLocal) {
|
|
4111
|
+
return void 0;
|
|
4112
|
+
}
|
|
4113
|
+
const config = await ConfigResolver.resolve({});
|
|
4114
|
+
if (config.getGitignoreTargetsOnly()) {
|
|
4115
|
+
const targets = config.getTargets();
|
|
4116
|
+
if (targets.includes("agentsmd")) {
|
|
4117
|
+
return targets;
|
|
4118
|
+
}
|
|
4119
|
+
return [...targets, "agentsmd"];
|
|
4120
|
+
}
|
|
4121
|
+
return void 0;
|
|
4122
|
+
};
|
|
4123
|
+
|
|
4081
4124
|
// src/lib/update.ts
|
|
4082
4125
|
import * as crypto from "crypto";
|
|
4083
4126
|
import * as fs from "fs";
|
|
@@ -4480,7 +4523,7 @@ function wrapCommand({
|
|
|
4480
4523
|
}
|
|
4481
4524
|
|
|
4482
4525
|
// src/cli/index.ts
|
|
4483
|
-
var getVersion = () => "8.
|
|
4526
|
+
var getVersion = () => "8.2.0";
|
|
4484
4527
|
function wrapCommand2(name, errorCode, handler) {
|
|
4485
4528
|
return wrapCommand({ name, errorCode, handler, getVersion });
|
|
4486
4529
|
}
|
|
@@ -4503,11 +4546,12 @@ var main = async () => {
|
|
|
4503
4546
|
parseCommaSeparatedList
|
|
4504
4547
|
).option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").action(
|
|
4505
4548
|
wrapCommand2("gitignore", "GITIGNORE_FAILED", async (logger5, options) => {
|
|
4549
|
+
const cliTargets = options.targets;
|
|
4550
|
+
const cliFeatures = options.features;
|
|
4551
|
+
const resolvedTargets = await resolveGitignoreTargets({ cliTargets });
|
|
4506
4552
|
await gitignoreCommand(logger5, {
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
// eslint-disable-next-line no-type-assertion/no-type-assertion
|
|
4510
|
-
features: options.features
|
|
4553
|
+
targets: resolvedTargets ? [...resolvedTargets] : void 0,
|
|
4554
|
+
features: cliFeatures
|
|
4511
4555
|
});
|
|
4512
4556
|
})
|
|
4513
4557
|
);
|