rulesync 8.1.0 → 8.3.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 +2 -2
- package/dist/{chunk-FLZZ3LEK.js → chunk-RVBJT5ST.js} +1019 -610
- package/dist/cli/index.cjs +672 -253
- package/dist/cli/index.js +13 -3
- package/dist/index.cjs +1044 -635
- package/dist/index.js +1 -1
- package/package.json +5 -4
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({
|
|
@@ -19994,7 +20003,7 @@ var SourceEntrySchema = import_mini69.z.object({
|
|
|
19994
20003
|
});
|
|
19995
20004
|
var ConfigParamsSchema = import_mini69.z.object({
|
|
19996
20005
|
baseDirs: import_mini69.z.array(import_mini69.z.string()),
|
|
19997
|
-
targets:
|
|
20006
|
+
targets: RulesyncConfigTargetsSchema,
|
|
19998
20007
|
features: RulesyncFeaturesSchema,
|
|
19999
20008
|
verbose: import_mini69.z.boolean(),
|
|
20000
20009
|
delete: import_mini69.z.boolean(),
|
|
@@ -20021,10 +20030,42 @@ var CONFLICTING_TARGET_PAIRS = [
|
|
|
20021
20030
|
["claudecode", "claudecode-legacy"]
|
|
20022
20031
|
];
|
|
20023
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
|
+
};
|
|
20024
20058
|
var Config = class _Config {
|
|
20025
20059
|
baseDirs;
|
|
20026
20060
|
targets;
|
|
20027
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;
|
|
20028
20069
|
verbose;
|
|
20029
20070
|
delete;
|
|
20030
20071
|
global;
|
|
@@ -20052,13 +20093,19 @@ var Config = class _Config {
|
|
|
20052
20093
|
check,
|
|
20053
20094
|
sources
|
|
20054
20095
|
}) {
|
|
20055
|
-
|
|
20096
|
+
assertTargetsFeaturesExclusive({ targets, features });
|
|
20097
|
+
assertTargetsOrFeaturesProvided({ targets, features });
|
|
20098
|
+
const resolvedTargets = targets ?? [];
|
|
20099
|
+
const resolvedFeatures = features ?? [];
|
|
20100
|
+
this.validateObjectFormTargetKeys(resolvedTargets);
|
|
20101
|
+
this.validateConflictingTargets(resolvedTargets);
|
|
20056
20102
|
if (dryRun && check) {
|
|
20057
20103
|
throw new Error("--dry-run and --check cannot be used together");
|
|
20058
20104
|
}
|
|
20059
20105
|
this.baseDirs = baseDirs;
|
|
20060
|
-
this.targets =
|
|
20061
|
-
this.features =
|
|
20106
|
+
this.targets = resolvedTargets;
|
|
20107
|
+
this.features = resolvedFeatures;
|
|
20108
|
+
this.objectFormTargetKeys = isRulesyncConfigTargetsObject(resolvedTargets) ? _Config.filterValidToolTargets(Object.keys(resolvedTargets)) : void 0;
|
|
20062
20109
|
this.verbose = verbose;
|
|
20063
20110
|
this.delete = isDelete;
|
|
20064
20111
|
this.global = global ?? false;
|
|
@@ -20071,11 +20118,37 @@ var Config = class _Config {
|
|
|
20071
20118
|
this.check = check ?? false;
|
|
20072
20119
|
this.sources = sources ?? [];
|
|
20073
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
|
+
}
|
|
20074
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
|
+
};
|
|
20075
20150
|
for (const [target1, target2] of CONFLICTING_TARGET_PAIRS) {
|
|
20076
|
-
|
|
20077
|
-
const hasTarget2 = targets.includes(target2);
|
|
20078
|
-
if (hasTarget1 && hasTarget2) {
|
|
20151
|
+
if (has(target1) && has(target2)) {
|
|
20079
20152
|
throw new Error(
|
|
20080
20153
|
`Conflicting targets: '${target1}' and '${target2}' cannot be used together. Please choose one.`
|
|
20081
20154
|
);
|
|
@@ -20085,16 +20158,45 @@ var Config = class _Config {
|
|
|
20085
20158
|
getBaseDirs() {
|
|
20086
20159
|
return this.baseDirs;
|
|
20087
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
|
+
}
|
|
20088
20175
|
getTargets() {
|
|
20089
|
-
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("*")) {
|
|
20090
20184
|
return ALL_TOOL_TARGETS.filter(
|
|
20091
20185
|
// eslint-disable-next-line no-type-assertion/no-type-assertion
|
|
20092
20186
|
(target) => !LEGACY_TARGETS.includes(target)
|
|
20093
20187
|
);
|
|
20094
20188
|
}
|
|
20095
|
-
return
|
|
20189
|
+
return arrayTargets.filter((target) => target !== "*");
|
|
20096
20190
|
}
|
|
20097
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
|
+
}
|
|
20098
20200
|
if (!Array.isArray(this.features)) {
|
|
20099
20201
|
const perTargetFeatures = this.features;
|
|
20100
20202
|
if (target) {
|
|
@@ -20104,20 +20206,7 @@ var Config = class _Config {
|
|
|
20104
20206
|
}
|
|
20105
20207
|
return _Config.normalizeTargetFeatures(targetFeatures);
|
|
20106
20208
|
}
|
|
20107
|
-
|
|
20108
|
-
for (const features of Object.values(perTargetFeatures)) {
|
|
20109
|
-
if (!features) continue;
|
|
20110
|
-
const normalized = _Config.normalizeTargetFeatures(features);
|
|
20111
|
-
for (const feature of normalized) {
|
|
20112
|
-
if (!allFeatures.includes(feature)) {
|
|
20113
|
-
allFeatures.push(feature);
|
|
20114
|
-
}
|
|
20115
|
-
}
|
|
20116
|
-
if (allFeatures.length === ALL_FEATURES.length) {
|
|
20117
|
-
return allFeatures;
|
|
20118
|
-
}
|
|
20119
|
-
}
|
|
20120
|
-
return allFeatures;
|
|
20209
|
+
return _Config.collectAllFeatures(Object.values(perTargetFeatures));
|
|
20121
20210
|
}
|
|
20122
20211
|
if (this.features.includes("*")) {
|
|
20123
20212
|
return [...ALL_FEATURES];
|
|
@@ -20145,23 +20234,40 @@ var Config = class _Config {
|
|
|
20145
20234
|
}
|
|
20146
20235
|
return enabled;
|
|
20147
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
|
+
}
|
|
20148
20257
|
/**
|
|
20149
20258
|
* Returns the per-feature options object for a given target/feature, if any.
|
|
20150
20259
|
* Returns `undefined` when no per-feature options were provided or when the
|
|
20151
20260
|
* feature is not enabled for the given target.
|
|
20152
20261
|
*/
|
|
20153
20262
|
getFeatureOptions(target, feature) {
|
|
20154
|
-
|
|
20263
|
+
const value = isRulesyncConfigTargetsObject(this.targets) ? this.targets[target] : !Array.isArray(this.features) ? this.features[target] : void 0;
|
|
20264
|
+
if (!value || Array.isArray(value)) {
|
|
20155
20265
|
return void 0;
|
|
20156
20266
|
}
|
|
20157
|
-
const
|
|
20158
|
-
|
|
20159
|
-
|
|
20160
|
-
|
|
20161
|
-
const perFeature = targetFeatures;
|
|
20162
|
-
const value = perFeature[feature];
|
|
20163
|
-
if (value && typeof value === "object" && isFeatureValueEnabled(value)) {
|
|
20164
|
-
return value;
|
|
20267
|
+
const perFeature = value;
|
|
20268
|
+
const featureValue = perFeature[feature];
|
|
20269
|
+
if (featureValue && typeof featureValue === "object" && isFeatureValueEnabled(featureValue)) {
|
|
20270
|
+
return featureValue;
|
|
20165
20271
|
}
|
|
20166
20272
|
return void 0;
|
|
20167
20273
|
}
|
|
@@ -20169,6 +20275,13 @@ var Config = class _Config {
|
|
|
20169
20275
|
* Check if per-target features configuration is being used.
|
|
20170
20276
|
*/
|
|
20171
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() {
|
|
20172
20285
|
return !Array.isArray(this.features);
|
|
20173
20286
|
}
|
|
20174
20287
|
getVerbose() {
|
|
@@ -20213,6 +20326,17 @@ var Config = class _Config {
|
|
|
20213
20326
|
}
|
|
20214
20327
|
};
|
|
20215
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
|
+
|
|
20216
20340
|
// src/config/config-resolver.ts
|
|
20217
20341
|
var getDefaults = () => ({
|
|
20218
20342
|
targets: ["agentsmd"],
|
|
@@ -20239,6 +20363,10 @@ var loadConfigFromFile = async (filePath) => {
|
|
|
20239
20363
|
const jsonData = (0, import_jsonc_parser4.parse)(fileContent);
|
|
20240
20364
|
const parsed = ConfigFileSchema.parse(jsonData);
|
|
20241
20365
|
const { $schema: _schema, ...configParams } = parsed;
|
|
20366
|
+
assertTargetsFeaturesExclusive({
|
|
20367
|
+
targets: configParams.targets,
|
|
20368
|
+
features: configParams.features
|
|
20369
|
+
});
|
|
20242
20370
|
return configParams;
|
|
20243
20371
|
};
|
|
20244
20372
|
var mergeConfigs = (baseConfig, localConfig) => {
|
|
@@ -20282,14 +20410,35 @@ var ConfigResolver = class {
|
|
|
20282
20410
|
const localConfigPath = (0, import_node_path134.join)(configDir, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH);
|
|
20283
20411
|
const localConfig = await loadConfigFromFile(localConfigPath);
|
|
20284
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
|
+
}
|
|
20285
20425
|
const resolvedGlobal = global ?? configByFile.global ?? getDefaults().global;
|
|
20286
20426
|
const resolvedSimulateCommands = simulateCommands ?? configByFile.simulateCommands ?? getDefaults().simulateCommands;
|
|
20287
20427
|
const resolvedSimulateSubagents = simulateSubagents ?? configByFile.simulateSubagents ?? getDefaults().simulateSubagents;
|
|
20288
20428
|
const resolvedSimulateSkills = simulateSkills ?? configByFile.simulateSkills ?? getDefaults().simulateSkills;
|
|
20289
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);
|
|
20290
20439
|
const configParams = {
|
|
20291
|
-
targets:
|
|
20292
|
-
features:
|
|
20440
|
+
targets: resolvedTargets,
|
|
20441
|
+
features: resolvedFeatures,
|
|
20293
20442
|
verbose: verbose ?? configByFile.verbose ?? getDefaults().verbose,
|
|
20294
20443
|
delete: isDelete ?? configByFile.delete ?? getDefaults().delete,
|
|
20295
20444
|
baseDirs: getBaseDirsInLightOfGlobal({
|
|
@@ -20324,11 +20473,11 @@ function getBaseDirsInLightOfGlobal({
|
|
|
20324
20473
|
}
|
|
20325
20474
|
|
|
20326
20475
|
// src/lib/generate.ts
|
|
20327
|
-
var
|
|
20476
|
+
var import_node_path141 = require("path");
|
|
20328
20477
|
var import_es_toolkit5 = require("es-toolkit");
|
|
20329
20478
|
|
|
20330
20479
|
// src/features/permissions/permissions-processor.ts
|
|
20331
|
-
var
|
|
20480
|
+
var import_mini74 = require("zod/mini");
|
|
20332
20481
|
|
|
20333
20482
|
// src/features/permissions/claudecode-permissions.ts
|
|
20334
20483
|
var import_node_path136 = require("path");
|
|
@@ -20657,6 +20806,7 @@ function convertClaudeToRulesyncPermissions(params) {
|
|
|
20657
20806
|
var import_node_path137 = require("path");
|
|
20658
20807
|
var smolToml5 = __toESM(require("smol-toml"), 1);
|
|
20659
20808
|
var RULESYNC_PROFILE_NAME = "rulesync";
|
|
20809
|
+
var RULESYNC_BASH_RULES_FILE_NAME = "rulesync.rules";
|
|
20660
20810
|
var CodexcliPermissions = class _CodexcliPermissions extends ToolPermissions {
|
|
20661
20811
|
static getSettablePaths(_options = {}) {
|
|
20662
20812
|
return {
|
|
@@ -20746,6 +20896,22 @@ var CodexcliPermissions = class _CodexcliPermissions extends ToolPermissions {
|
|
|
20746
20896
|
});
|
|
20747
20897
|
}
|
|
20748
20898
|
};
|
|
20899
|
+
var CodexcliRulesFile = class extends ToolFile {
|
|
20900
|
+
validate() {
|
|
20901
|
+
return { success: true, error: null };
|
|
20902
|
+
}
|
|
20903
|
+
};
|
|
20904
|
+
function createCodexcliBashRulesFile({
|
|
20905
|
+
baseDir = process.cwd(),
|
|
20906
|
+
config
|
|
20907
|
+
}) {
|
|
20908
|
+
return new CodexcliRulesFile({
|
|
20909
|
+
baseDir,
|
|
20910
|
+
relativeDirPath: (0, import_node_path137.join)(".codex", "rules"),
|
|
20911
|
+
relativeFilePath: RULESYNC_BASH_RULES_FILE_NAME,
|
|
20912
|
+
fileContent: buildCodexBashRulesContent(config)
|
|
20913
|
+
});
|
|
20914
|
+
}
|
|
20749
20915
|
function convertRulesyncToCodexProfile({
|
|
20750
20916
|
config,
|
|
20751
20917
|
logger: logger5
|
|
@@ -20854,6 +21020,46 @@ function mapReadAction(action) {
|
|
|
20854
21020
|
function mapWriteAction(action) {
|
|
20855
21021
|
return action === "allow" ? "write" : "none";
|
|
20856
21022
|
}
|
|
21023
|
+
function buildCodexBashRulesContent(config) {
|
|
21024
|
+
const bashRules = config.permission.bash ?? {};
|
|
21025
|
+
const entries = Object.entries(bashRules);
|
|
21026
|
+
const header = [
|
|
21027
|
+
"# Generated by Rulesync from .rulesync/permissions.json (permission.bash)",
|
|
21028
|
+
"# https://developers.openai.com/codex/rules"
|
|
21029
|
+
];
|
|
21030
|
+
if (entries.length === 0) {
|
|
21031
|
+
return [...header, "# No bash permission rules were configured."].join("\n");
|
|
21032
|
+
}
|
|
21033
|
+
const ruleBlocks = entries.map(([pattern, action]) => {
|
|
21034
|
+
const tokens = toCommandPatternTokens(pattern);
|
|
21035
|
+
if (tokens.length === 0) {
|
|
21036
|
+
return null;
|
|
21037
|
+
}
|
|
21038
|
+
const serializedTokens = tokens.map((token) => JSON.stringify(token)).join(", ");
|
|
21039
|
+
const decision = mapBashActionToDecision(action);
|
|
21040
|
+
return [
|
|
21041
|
+
"",
|
|
21042
|
+
`# ${pattern}`,
|
|
21043
|
+
"prefix_rule(",
|
|
21044
|
+
` pattern = [${serializedTokens}],`,
|
|
21045
|
+
` decision = ${JSON.stringify(decision)},`,
|
|
21046
|
+
` justification = ${JSON.stringify(`Generated from Rulesync permission.bash: ${pattern}`)},`,
|
|
21047
|
+
")"
|
|
21048
|
+
].join("\n");
|
|
21049
|
+
}).filter((block) => block !== null);
|
|
21050
|
+
if (ruleBlocks.length === 0) {
|
|
21051
|
+
return [...header, "# No valid bash patterns were found."].join("\n");
|
|
21052
|
+
}
|
|
21053
|
+
return [...header, ...ruleBlocks].join("\n");
|
|
21054
|
+
}
|
|
21055
|
+
function toCommandPatternTokens(commandPattern) {
|
|
21056
|
+
return commandPattern.trim().split(/\s+/).map((token) => token.trim()).filter((token) => token.length > 0);
|
|
21057
|
+
}
|
|
21058
|
+
function mapBashActionToDecision(action) {
|
|
21059
|
+
if (action === "allow") return "allow";
|
|
21060
|
+
if (action === "ask") return "prompt";
|
|
21061
|
+
return "forbidden";
|
|
21062
|
+
}
|
|
20857
21063
|
|
|
20858
21064
|
// src/features/permissions/geminicli-permissions.ts
|
|
20859
21065
|
var import_node_path138 = require("path");
|
|
@@ -21019,16 +21225,200 @@ function parseGeminicliToolEntry({ entry }) {
|
|
|
21019
21225
|
};
|
|
21020
21226
|
}
|
|
21021
21227
|
|
|
21022
|
-
// src/features/permissions/
|
|
21228
|
+
// src/features/permissions/kiro-permissions.ts
|
|
21023
21229
|
var import_node_path139 = require("path");
|
|
21024
|
-
var import_jsonc_parser5 = require("jsonc-parser");
|
|
21025
21230
|
var import_mini72 = require("zod/mini");
|
|
21026
|
-
var
|
|
21027
|
-
import_mini72.z.
|
|
21028
|
-
import_mini72.z.record(import_mini72.z.string(), import_mini72.z.
|
|
21231
|
+
var KiroAgentSchema = import_mini72.z.looseObject({
|
|
21232
|
+
allowedTools: import_mini72.z.optional(import_mini72.z.array(import_mini72.z.string())),
|
|
21233
|
+
toolsSettings: import_mini72.z.optional(import_mini72.z.record(import_mini72.z.string(), import_mini72.z.unknown()))
|
|
21234
|
+
});
|
|
21235
|
+
var UnknownRecordSchema = import_mini72.z.record(import_mini72.z.string(), import_mini72.z.unknown());
|
|
21236
|
+
var KiroPermissions = class _KiroPermissions extends ToolPermissions {
|
|
21237
|
+
static getSettablePaths(_options = {}) {
|
|
21238
|
+
return {
|
|
21239
|
+
relativeDirPath: (0, import_node_path139.join)(".kiro", "agents"),
|
|
21240
|
+
relativeFilePath: "default.json"
|
|
21241
|
+
};
|
|
21242
|
+
}
|
|
21243
|
+
isDeletable() {
|
|
21244
|
+
return false;
|
|
21245
|
+
}
|
|
21246
|
+
static async fromFile({
|
|
21247
|
+
baseDir = process.cwd(),
|
|
21248
|
+
validate = true
|
|
21249
|
+
}) {
|
|
21250
|
+
const paths = this.getSettablePaths();
|
|
21251
|
+
const filePath = (0, import_node_path139.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath);
|
|
21252
|
+
const fileContent = await readFileContentOrNull(filePath) ?? JSON.stringify({}, null, 2);
|
|
21253
|
+
return new _KiroPermissions({
|
|
21254
|
+
baseDir,
|
|
21255
|
+
relativeDirPath: paths.relativeDirPath,
|
|
21256
|
+
relativeFilePath: paths.relativeFilePath,
|
|
21257
|
+
fileContent,
|
|
21258
|
+
validate
|
|
21259
|
+
});
|
|
21260
|
+
}
|
|
21261
|
+
static async fromRulesyncPermissions({
|
|
21262
|
+
baseDir = process.cwd(),
|
|
21263
|
+
rulesyncPermissions,
|
|
21264
|
+
validate = true,
|
|
21265
|
+
logger: logger5
|
|
21266
|
+
}) {
|
|
21267
|
+
const paths = this.getSettablePaths();
|
|
21268
|
+
const filePath = (0, import_node_path139.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath);
|
|
21269
|
+
const existingContent = await readFileContentOrNull(filePath) ?? JSON.stringify({}, null, 2);
|
|
21270
|
+
const parsedResult = KiroAgentSchema.safeParse(JSON.parse(existingContent));
|
|
21271
|
+
if (!parsedResult.success) {
|
|
21272
|
+
throw new Error(
|
|
21273
|
+
`Failed to parse existing Kiro agent config at ${filePath}: ${formatError(parsedResult.error)}`
|
|
21274
|
+
);
|
|
21275
|
+
}
|
|
21276
|
+
const config = rulesyncPermissions.getJson();
|
|
21277
|
+
const next = buildKiroPermissionsFromRulesync({ config, logger: logger5, existing: parsedResult.data });
|
|
21278
|
+
return new _KiroPermissions({
|
|
21279
|
+
baseDir,
|
|
21280
|
+
relativeDirPath: paths.relativeDirPath,
|
|
21281
|
+
relativeFilePath: paths.relativeFilePath,
|
|
21282
|
+
fileContent: JSON.stringify(next, null, 2),
|
|
21283
|
+
validate
|
|
21284
|
+
});
|
|
21285
|
+
}
|
|
21286
|
+
toRulesyncPermissions() {
|
|
21287
|
+
let parsed;
|
|
21288
|
+
try {
|
|
21289
|
+
parsed = KiroAgentSchema.parse(JSON.parse(this.getFileContent()));
|
|
21290
|
+
} catch (error) {
|
|
21291
|
+
throw new Error(
|
|
21292
|
+
`Failed to parse Kiro permissions content in ${(0, import_node_path139.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`,
|
|
21293
|
+
{ cause: error }
|
|
21294
|
+
);
|
|
21295
|
+
}
|
|
21296
|
+
const permission = {};
|
|
21297
|
+
const toolsSettings = parsed.toolsSettings ?? {};
|
|
21298
|
+
const shellSettings = asRecord(toolsSettings.shell);
|
|
21299
|
+
const shellAllow = asStringArray(shellSettings.allowedCommands);
|
|
21300
|
+
const shellDeny = asStringArray(shellSettings.deniedCommands);
|
|
21301
|
+
if (shellAllow.length > 0 || shellDeny.length > 0) {
|
|
21302
|
+
permission.bash = {};
|
|
21303
|
+
for (const pattern of shellAllow) permission.bash[pattern] = "allow";
|
|
21304
|
+
for (const pattern of shellDeny) permission.bash[pattern] = "deny";
|
|
21305
|
+
}
|
|
21306
|
+
const readSettings = asRecord(toolsSettings.read);
|
|
21307
|
+
const readAllow = asStringArray(readSettings.allowedPaths);
|
|
21308
|
+
const readDeny = asStringArray(readSettings.deniedPaths);
|
|
21309
|
+
if (readAllow.length > 0 || readDeny.length > 0) {
|
|
21310
|
+
permission.read = {};
|
|
21311
|
+
for (const pattern of readAllow) permission.read[pattern] = "allow";
|
|
21312
|
+
for (const pattern of readDeny) permission.read[pattern] = "deny";
|
|
21313
|
+
}
|
|
21314
|
+
const writeSettings = asRecord(toolsSettings.write);
|
|
21315
|
+
const writeAllow = asStringArray(writeSettings.allowedPaths);
|
|
21316
|
+
const writeDeny = asStringArray(writeSettings.deniedPaths);
|
|
21317
|
+
if (writeAllow.length > 0 || writeDeny.length > 0) {
|
|
21318
|
+
permission.write = {};
|
|
21319
|
+
for (const pattern of writeAllow) permission.write[pattern] = "allow";
|
|
21320
|
+
for (const pattern of writeDeny) permission.write[pattern] = "deny";
|
|
21321
|
+
}
|
|
21322
|
+
const allowedTools = new Set(parsed.allowedTools ?? []);
|
|
21323
|
+
if (allowedTools.has("web_fetch")) {
|
|
21324
|
+
permission.webfetch = { "*": "allow" };
|
|
21325
|
+
}
|
|
21326
|
+
if (allowedTools.has("web_search")) {
|
|
21327
|
+
permission.websearch = { "*": "allow" };
|
|
21328
|
+
}
|
|
21329
|
+
return this.toRulesyncPermissionsDefault({
|
|
21330
|
+
fileContent: JSON.stringify({ permission }, null, 2)
|
|
21331
|
+
});
|
|
21332
|
+
}
|
|
21333
|
+
validate() {
|
|
21334
|
+
return { success: true, error: null };
|
|
21335
|
+
}
|
|
21336
|
+
static forDeletion({
|
|
21337
|
+
baseDir = process.cwd(),
|
|
21338
|
+
relativeDirPath,
|
|
21339
|
+
relativeFilePath
|
|
21340
|
+
}) {
|
|
21341
|
+
return new _KiroPermissions({
|
|
21342
|
+
baseDir,
|
|
21343
|
+
relativeDirPath,
|
|
21344
|
+
relativeFilePath,
|
|
21345
|
+
fileContent: JSON.stringify({}, null, 2),
|
|
21346
|
+
validate: false
|
|
21347
|
+
});
|
|
21348
|
+
}
|
|
21349
|
+
};
|
|
21350
|
+
function buildKiroPermissionsFromRulesync({
|
|
21351
|
+
config,
|
|
21352
|
+
logger: logger5,
|
|
21353
|
+
existing
|
|
21354
|
+
}) {
|
|
21355
|
+
const nextAllowedTools = new Set(existing.allowedTools ?? []);
|
|
21356
|
+
const nextToolsSettings = { ...asRecord(existing.toolsSettings) };
|
|
21357
|
+
const shell = {
|
|
21358
|
+
allowedCommands: [],
|
|
21359
|
+
deniedCommands: []
|
|
21360
|
+
};
|
|
21361
|
+
const read = {
|
|
21362
|
+
allowedPaths: [],
|
|
21363
|
+
deniedPaths: []
|
|
21364
|
+
};
|
|
21365
|
+
const write = {
|
|
21366
|
+
allowedPaths: [],
|
|
21367
|
+
deniedPaths: []
|
|
21368
|
+
};
|
|
21369
|
+
for (const [category, rules] of Object.entries(config.permission)) {
|
|
21370
|
+
for (const [pattern, action] of Object.entries(rules)) {
|
|
21371
|
+
if (action === "ask") {
|
|
21372
|
+
logger5?.warn(`Kiro permissions do not support "ask". Skipping ${category}:${pattern}`);
|
|
21373
|
+
continue;
|
|
21374
|
+
}
|
|
21375
|
+
if (category === "bash") {
|
|
21376
|
+
(action === "allow" ? shell.allowedCommands : shell.deniedCommands).push(pattern);
|
|
21377
|
+
} else if (category === "read") {
|
|
21378
|
+
(action === "allow" ? read.allowedPaths : read.deniedPaths).push(pattern);
|
|
21379
|
+
} else if (category === "edit" || category === "write") {
|
|
21380
|
+
(action === "allow" ? write.allowedPaths : write.deniedPaths).push(pattern);
|
|
21381
|
+
} else if (category === "webfetch" || category === "websearch") {
|
|
21382
|
+
if (pattern !== "*") {
|
|
21383
|
+
logger5?.warn(
|
|
21384
|
+
`Kiro ${category} supports only wildcard (*) via allowedTools. Skipping rule: ${pattern}`
|
|
21385
|
+
);
|
|
21386
|
+
continue;
|
|
21387
|
+
}
|
|
21388
|
+
if (action === "allow")
|
|
21389
|
+
nextAllowedTools.add(category === "webfetch" ? "web_fetch" : "web_search");
|
|
21390
|
+
} else {
|
|
21391
|
+
logger5?.warn(`Kiro permissions do not support category: ${category}. Skipping.`);
|
|
21392
|
+
}
|
|
21393
|
+
}
|
|
21394
|
+
}
|
|
21395
|
+
nextToolsSettings.shell = shell;
|
|
21396
|
+
nextToolsSettings.read = read;
|
|
21397
|
+
nextToolsSettings.write = write;
|
|
21398
|
+
return {
|
|
21399
|
+
...existing,
|
|
21400
|
+
allowedTools: [...nextAllowedTools].toSorted(),
|
|
21401
|
+
toolsSettings: nextToolsSettings
|
|
21402
|
+
};
|
|
21403
|
+
}
|
|
21404
|
+
function asRecord(value) {
|
|
21405
|
+
const result = UnknownRecordSchema.safeParse(value);
|
|
21406
|
+
return result.success ? result.data : {};
|
|
21407
|
+
}
|
|
21408
|
+
function asStringArray(value) {
|
|
21409
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
21410
|
+
}
|
|
21411
|
+
|
|
21412
|
+
// src/features/permissions/opencode-permissions.ts
|
|
21413
|
+
var import_node_path140 = require("path");
|
|
21414
|
+
var import_jsonc_parser5 = require("jsonc-parser");
|
|
21415
|
+
var import_mini73 = require("zod/mini");
|
|
21416
|
+
var OpencodePermissionSchema = import_mini73.z.union([
|
|
21417
|
+
import_mini73.z.enum(["allow", "ask", "deny"]),
|
|
21418
|
+
import_mini73.z.record(import_mini73.z.string(), import_mini73.z.enum(["allow", "ask", "deny"]))
|
|
21029
21419
|
]);
|
|
21030
|
-
var OpencodePermissionsConfigSchema =
|
|
21031
|
-
permission:
|
|
21420
|
+
var OpencodePermissionsConfigSchema = import_mini73.z.looseObject({
|
|
21421
|
+
permission: import_mini73.z.optional(import_mini73.z.record(import_mini73.z.string(), OpencodePermissionSchema))
|
|
21032
21422
|
});
|
|
21033
21423
|
var OpencodePermissions = class _OpencodePermissions extends ToolPermissions {
|
|
21034
21424
|
json;
|
|
@@ -21045,7 +21435,7 @@ var OpencodePermissions = class _OpencodePermissions extends ToolPermissions {
|
|
|
21045
21435
|
static getSettablePaths({
|
|
21046
21436
|
global = false
|
|
21047
21437
|
} = {}) {
|
|
21048
|
-
return global ? { relativeDirPath: (0,
|
|
21438
|
+
return global ? { relativeDirPath: (0, import_node_path140.join)(".config", "opencode"), relativeFilePath: "opencode.json" } : { relativeDirPath: ".", relativeFilePath: "opencode.json" };
|
|
21049
21439
|
}
|
|
21050
21440
|
static async fromFile({
|
|
21051
21441
|
baseDir = process.cwd(),
|
|
@@ -21053,9 +21443,9 @@ var OpencodePermissions = class _OpencodePermissions extends ToolPermissions {
|
|
|
21053
21443
|
global = false
|
|
21054
21444
|
}) {
|
|
21055
21445
|
const basePaths = _OpencodePermissions.getSettablePaths({ global });
|
|
21056
|
-
const jsonDir = (0,
|
|
21057
|
-
const jsoncPath = (0,
|
|
21058
|
-
const jsonPath = (0,
|
|
21446
|
+
const jsonDir = (0, import_node_path140.join)(baseDir, basePaths.relativeDirPath);
|
|
21447
|
+
const jsoncPath = (0, import_node_path140.join)(jsonDir, "opencode.jsonc");
|
|
21448
|
+
const jsonPath = (0, import_node_path140.join)(jsonDir, "opencode.json");
|
|
21059
21449
|
let fileContent = await readFileContentOrNull(jsoncPath);
|
|
21060
21450
|
let relativeFilePath = "opencode.jsonc";
|
|
21061
21451
|
if (!fileContent) {
|
|
@@ -21080,9 +21470,9 @@ var OpencodePermissions = class _OpencodePermissions extends ToolPermissions {
|
|
|
21080
21470
|
global = false
|
|
21081
21471
|
}) {
|
|
21082
21472
|
const basePaths = _OpencodePermissions.getSettablePaths({ global });
|
|
21083
|
-
const jsonDir = (0,
|
|
21084
|
-
const jsoncPath = (0,
|
|
21085
|
-
const jsonPath = (0,
|
|
21473
|
+
const jsonDir = (0, import_node_path140.join)(baseDir, basePaths.relativeDirPath);
|
|
21474
|
+
const jsoncPath = (0, import_node_path140.join)(jsonDir, "opencode.jsonc");
|
|
21475
|
+
const jsonPath = (0, import_node_path140.join)(jsonDir, "opencode.json");
|
|
21086
21476
|
let fileContent = await readFileContentOrNull(jsoncPath);
|
|
21087
21477
|
let relativeFilePath = "opencode.jsonc";
|
|
21088
21478
|
if (!fileContent) {
|
|
@@ -21156,9 +21546,10 @@ var permissionsProcessorToolTargetTuple = [
|
|
|
21156
21546
|
"claudecode",
|
|
21157
21547
|
"codexcli",
|
|
21158
21548
|
"geminicli",
|
|
21549
|
+
"kiro",
|
|
21159
21550
|
"opencode"
|
|
21160
21551
|
];
|
|
21161
|
-
var PermissionsProcessorToolTargetSchema =
|
|
21552
|
+
var PermissionsProcessorToolTargetSchema = import_mini74.z.enum(permissionsProcessorToolTargetTuple);
|
|
21162
21553
|
var toolPermissionsFactories = /* @__PURE__ */ new Map([
|
|
21163
21554
|
[
|
|
21164
21555
|
"claudecode",
|
|
@@ -21166,7 +21557,7 @@ var toolPermissionsFactories = /* @__PURE__ */ new Map([
|
|
|
21166
21557
|
class: ClaudecodePermissions,
|
|
21167
21558
|
meta: {
|
|
21168
21559
|
supportsProject: true,
|
|
21169
|
-
supportsGlobal:
|
|
21560
|
+
supportsGlobal: true,
|
|
21170
21561
|
supportsImport: true
|
|
21171
21562
|
}
|
|
21172
21563
|
}
|
|
@@ -21193,6 +21584,17 @@ var toolPermissionsFactories = /* @__PURE__ */ new Map([
|
|
|
21193
21584
|
}
|
|
21194
21585
|
}
|
|
21195
21586
|
],
|
|
21587
|
+
[
|
|
21588
|
+
"kiro",
|
|
21589
|
+
{
|
|
21590
|
+
class: KiroPermissions,
|
|
21591
|
+
meta: {
|
|
21592
|
+
supportsProject: true,
|
|
21593
|
+
supportsGlobal: false,
|
|
21594
|
+
supportsImport: true
|
|
21595
|
+
}
|
|
21596
|
+
}
|
|
21597
|
+
],
|
|
21196
21598
|
[
|
|
21197
21599
|
"opencode",
|
|
21198
21600
|
{
|
|
@@ -21288,7 +21690,14 @@ var PermissionsProcessor = class extends FeatureProcessor {
|
|
|
21288
21690
|
logger: this.logger,
|
|
21289
21691
|
global: this.global
|
|
21290
21692
|
});
|
|
21291
|
-
|
|
21693
|
+
if (this.toolTarget !== "codexcli") {
|
|
21694
|
+
return [toolPermissions];
|
|
21695
|
+
}
|
|
21696
|
+
const bashRulesFile = createCodexcliBashRulesFile({
|
|
21697
|
+
baseDir: this.baseDir,
|
|
21698
|
+
config: rulesyncPermissions.getJson()
|
|
21699
|
+
});
|
|
21700
|
+
return [toolPermissions, bashRulesFile];
|
|
21292
21701
|
}
|
|
21293
21702
|
async convertToolFilesToRulesyncFiles(toolFiles) {
|
|
21294
21703
|
const permissions = toolFiles.filter((f) => f instanceof ToolPermissions);
|
|
@@ -21375,7 +21784,7 @@ function warnUnsupportedTargets(params) {
|
|
|
21375
21784
|
}
|
|
21376
21785
|
}
|
|
21377
21786
|
async function checkRulesyncDirExists(params) {
|
|
21378
|
-
return fileExists((0,
|
|
21787
|
+
return fileExists((0, import_node_path141.join)(params.baseDir, RULESYNC_RELATIVE_DIR_PATH));
|
|
21379
21788
|
}
|
|
21380
21789
|
async function generate(params) {
|
|
21381
21790
|
const { config, logger: logger5 } = params;
|
|
@@ -21845,7 +22254,7 @@ async function generateCommand(logger5, options) {
|
|
|
21845
22254
|
}
|
|
21846
22255
|
|
|
21847
22256
|
// src/cli/commands/gitignore.ts
|
|
21848
|
-
var
|
|
22257
|
+
var import_node_path142 = require("path");
|
|
21849
22258
|
|
|
21850
22259
|
// src/cli/commands/gitignore-entries.ts
|
|
21851
22260
|
var normalizeGitignoreEntryTargets = (target) => {
|
|
@@ -22189,7 +22598,7 @@ var removeExistingRulesyncEntries = (content) => {
|
|
|
22189
22598
|
return result;
|
|
22190
22599
|
};
|
|
22191
22600
|
var gitignoreCommand = async (logger5, options) => {
|
|
22192
|
-
const gitignorePath = (0,
|
|
22601
|
+
const gitignorePath = (0, import_node_path142.join)(process.cwd(), ".gitignore");
|
|
22193
22602
|
let gitignoreContent = "";
|
|
22194
22603
|
if (await fileExists(gitignorePath)) {
|
|
22195
22604
|
gitignoreContent = await readFileContent(gitignorePath);
|
|
@@ -22510,6 +22919,12 @@ async function importCommand(logger5, options) {
|
|
|
22510
22919
|
if (!options.targets) {
|
|
22511
22920
|
throw new CLIError("No tools found in --targets", ErrorCodes.IMPORT_FAILED);
|
|
22512
22921
|
}
|
|
22922
|
+
if (!Array.isArray(options.targets)) {
|
|
22923
|
+
throw new CLIError(
|
|
22924
|
+
"--targets object form is not supported on the command line",
|
|
22925
|
+
ErrorCodes.IMPORT_FAILED
|
|
22926
|
+
);
|
|
22927
|
+
}
|
|
22513
22928
|
if (options.targets.length > 1) {
|
|
22514
22929
|
throw new CLIError("Only one tool can be imported at a time", ErrorCodes.IMPORT_FAILED);
|
|
22515
22930
|
}
|
|
@@ -22550,7 +22965,7 @@ async function importCommand(logger5, options) {
|
|
|
22550
22965
|
}
|
|
22551
22966
|
|
|
22552
22967
|
// src/lib/init.ts
|
|
22553
|
-
var
|
|
22968
|
+
var import_node_path143 = require("path");
|
|
22554
22969
|
async function init() {
|
|
22555
22970
|
const sampleFiles = await createSampleFiles();
|
|
22556
22971
|
const configFile = await createConfigFile();
|
|
@@ -22743,27 +23158,27 @@ Keep the summary concise and ready to reuse in future tasks.`
|
|
|
22743
23158
|
await ensureDir(subagentPaths.relativeDirPath);
|
|
22744
23159
|
await ensureDir(skillPaths.relativeDirPath);
|
|
22745
23160
|
await ensureDir(ignorePaths.recommended.relativeDirPath);
|
|
22746
|
-
const ruleFilepath = (0,
|
|
23161
|
+
const ruleFilepath = (0, import_node_path143.join)(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
|
|
22747
23162
|
results.push(await writeIfNotExists(ruleFilepath, sampleRuleFile.content));
|
|
22748
|
-
const mcpFilepath = (0,
|
|
23163
|
+
const mcpFilepath = (0, import_node_path143.join)(
|
|
22749
23164
|
mcpPaths.recommended.relativeDirPath,
|
|
22750
23165
|
mcpPaths.recommended.relativeFilePath
|
|
22751
23166
|
);
|
|
22752
23167
|
results.push(await writeIfNotExists(mcpFilepath, sampleMcpFile.content));
|
|
22753
|
-
const commandFilepath = (0,
|
|
23168
|
+
const commandFilepath = (0, import_node_path143.join)(commandPaths.relativeDirPath, sampleCommandFile.filename);
|
|
22754
23169
|
results.push(await writeIfNotExists(commandFilepath, sampleCommandFile.content));
|
|
22755
|
-
const subagentFilepath = (0,
|
|
23170
|
+
const subagentFilepath = (0, import_node_path143.join)(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
|
|
22756
23171
|
results.push(await writeIfNotExists(subagentFilepath, sampleSubagentFile.content));
|
|
22757
|
-
const skillDirPath = (0,
|
|
23172
|
+
const skillDirPath = (0, import_node_path143.join)(skillPaths.relativeDirPath, sampleSkillFile.dirName);
|
|
22758
23173
|
await ensureDir(skillDirPath);
|
|
22759
|
-
const skillFilepath = (0,
|
|
23174
|
+
const skillFilepath = (0, import_node_path143.join)(skillDirPath, SKILL_FILE_NAME);
|
|
22760
23175
|
results.push(await writeIfNotExists(skillFilepath, sampleSkillFile.content));
|
|
22761
|
-
const ignoreFilepath = (0,
|
|
23176
|
+
const ignoreFilepath = (0, import_node_path143.join)(
|
|
22762
23177
|
ignorePaths.recommended.relativeDirPath,
|
|
22763
23178
|
ignorePaths.recommended.relativeFilePath
|
|
22764
23179
|
);
|
|
22765
23180
|
results.push(await writeIfNotExists(ignoreFilepath, sampleIgnoreFile.content));
|
|
22766
|
-
const hooksFilepath = (0,
|
|
23181
|
+
const hooksFilepath = (0, import_node_path143.join)(hooksPaths.relativeDirPath, hooksPaths.relativeFilePath);
|
|
22767
23182
|
results.push(await writeIfNotExists(hooksFilepath, sampleHooksFile.content));
|
|
22768
23183
|
return results;
|
|
22769
23184
|
}
|
|
@@ -22811,12 +23226,12 @@ async function initCommand(logger5) {
|
|
|
22811
23226
|
}
|
|
22812
23227
|
|
|
22813
23228
|
// src/lib/sources.ts
|
|
22814
|
-
var
|
|
23229
|
+
var import_node_path146 = require("path");
|
|
22815
23230
|
var import_promise2 = require("es-toolkit/promise");
|
|
22816
23231
|
|
|
22817
23232
|
// src/lib/git-client.ts
|
|
22818
23233
|
var import_node_child_process = require("child_process");
|
|
22819
|
-
var
|
|
23234
|
+
var import_node_path144 = require("path");
|
|
22820
23235
|
var import_node_util2 = require("util");
|
|
22821
23236
|
var execFileAsync = (0, import_node_util2.promisify)(import_node_child_process.execFile);
|
|
22822
23237
|
var GIT_TIMEOUT_MS = 6e4;
|
|
@@ -22904,7 +23319,7 @@ async function fetchSkillFiles(params) {
|
|
|
22904
23319
|
const { url, ref, skillsPath, logger: logger5 } = params;
|
|
22905
23320
|
validateGitUrl(url, { logger: logger5 });
|
|
22906
23321
|
validateRef(ref);
|
|
22907
|
-
if (skillsPath.split(/[/\\]/).includes("..") || (0,
|
|
23322
|
+
if (skillsPath.split(/[/\\]/).includes("..") || (0, import_node_path144.isAbsolute)(skillsPath)) {
|
|
22908
23323
|
throw new GitClientError(
|
|
22909
23324
|
`Invalid skillsPath "${skillsPath}": must be a relative path without ".."`
|
|
22910
23325
|
);
|
|
@@ -22938,7 +23353,7 @@ async function fetchSkillFiles(params) {
|
|
|
22938
23353
|
timeout: GIT_TIMEOUT_MS
|
|
22939
23354
|
});
|
|
22940
23355
|
await execFileAsync("git", ["-C", tmpDir, "checkout"], { timeout: GIT_TIMEOUT_MS });
|
|
22941
|
-
const skillsDir = (0,
|
|
23356
|
+
const skillsDir = (0, import_node_path144.join)(tmpDir, skillsPath);
|
|
22942
23357
|
if (!await directoryExists(skillsDir)) return [];
|
|
22943
23358
|
return await walkDirectory(skillsDir, skillsDir, 0, { totalFiles: 0, totalSize: 0 }, logger5);
|
|
22944
23359
|
} catch (error) {
|
|
@@ -22960,7 +23375,7 @@ async function walkDirectory(dir, baseDir, depth = 0, ctx = { totalFiles: 0, tot
|
|
|
22960
23375
|
const results = [];
|
|
22961
23376
|
for (const name of await listDirectoryFiles(dir)) {
|
|
22962
23377
|
if (name === ".git") continue;
|
|
22963
|
-
const fullPath = (0,
|
|
23378
|
+
const fullPath = (0, import_node_path144.join)(dir, name);
|
|
22964
23379
|
if (await isSymlink(fullPath)) {
|
|
22965
23380
|
logger5?.warn(`Skipping symlink "${fullPath}".`);
|
|
22966
23381
|
continue;
|
|
@@ -22988,7 +23403,7 @@ async function walkDirectory(dir, baseDir, depth = 0, ctx = { totalFiles: 0, tot
|
|
|
22988
23403
|
);
|
|
22989
23404
|
}
|
|
22990
23405
|
const content = await readFileContent(fullPath);
|
|
22991
|
-
results.push({ relativePath: (0,
|
|
23406
|
+
results.push({ relativePath: (0, import_node_path144.relative)(baseDir, fullPath), content, size });
|
|
22992
23407
|
}
|
|
22993
23408
|
}
|
|
22994
23409
|
return results;
|
|
@@ -22996,28 +23411,28 @@ async function walkDirectory(dir, baseDir, depth = 0, ctx = { totalFiles: 0, tot
|
|
|
22996
23411
|
|
|
22997
23412
|
// src/lib/sources-lock.ts
|
|
22998
23413
|
var import_node_crypto = require("crypto");
|
|
22999
|
-
var
|
|
23000
|
-
var
|
|
23414
|
+
var import_node_path145 = require("path");
|
|
23415
|
+
var import_mini75 = require("zod/mini");
|
|
23001
23416
|
var LOCKFILE_VERSION = 1;
|
|
23002
|
-
var LockedSkillSchema =
|
|
23003
|
-
integrity:
|
|
23417
|
+
var LockedSkillSchema = import_mini75.z.object({
|
|
23418
|
+
integrity: import_mini75.z.string()
|
|
23004
23419
|
});
|
|
23005
|
-
var LockedSourceSchema =
|
|
23006
|
-
requestedRef: (0,
|
|
23007
|
-
resolvedRef:
|
|
23008
|
-
resolvedAt: (0,
|
|
23009
|
-
skills:
|
|
23420
|
+
var LockedSourceSchema = import_mini75.z.object({
|
|
23421
|
+
requestedRef: (0, import_mini75.optional)(import_mini75.z.string()),
|
|
23422
|
+
resolvedRef: import_mini75.z.string().check((0, import_mini75.refine)((v) => /^[0-9a-f]{40}$/.test(v), "resolvedRef must be a 40-character hex SHA")),
|
|
23423
|
+
resolvedAt: (0, import_mini75.optional)(import_mini75.z.string()),
|
|
23424
|
+
skills: import_mini75.z.record(import_mini75.z.string(), LockedSkillSchema)
|
|
23010
23425
|
});
|
|
23011
|
-
var SourcesLockSchema =
|
|
23012
|
-
lockfileVersion:
|
|
23013
|
-
sources:
|
|
23426
|
+
var SourcesLockSchema = import_mini75.z.object({
|
|
23427
|
+
lockfileVersion: import_mini75.z.number(),
|
|
23428
|
+
sources: import_mini75.z.record(import_mini75.z.string(), LockedSourceSchema)
|
|
23014
23429
|
});
|
|
23015
|
-
var LegacyLockedSourceSchema =
|
|
23016
|
-
resolvedRef:
|
|
23017
|
-
skills:
|
|
23430
|
+
var LegacyLockedSourceSchema = import_mini75.z.object({
|
|
23431
|
+
resolvedRef: import_mini75.z.string(),
|
|
23432
|
+
skills: import_mini75.z.array(import_mini75.z.string())
|
|
23018
23433
|
});
|
|
23019
|
-
var LegacySourcesLockSchema =
|
|
23020
|
-
sources:
|
|
23434
|
+
var LegacySourcesLockSchema = import_mini75.z.object({
|
|
23435
|
+
sources: import_mini75.z.record(import_mini75.z.string(), LegacyLockedSourceSchema)
|
|
23021
23436
|
});
|
|
23022
23437
|
function migrateLegacyLock(params) {
|
|
23023
23438
|
const { legacy, logger: logger5 } = params;
|
|
@@ -23042,7 +23457,7 @@ function createEmptyLock() {
|
|
|
23042
23457
|
}
|
|
23043
23458
|
async function readLockFile(params) {
|
|
23044
23459
|
const { logger: logger5 } = params;
|
|
23045
|
-
const lockPath = (0,
|
|
23460
|
+
const lockPath = (0, import_node_path145.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
|
|
23046
23461
|
if (!await fileExists(lockPath)) {
|
|
23047
23462
|
logger5.debug("No sources lockfile found, starting fresh.");
|
|
23048
23463
|
return createEmptyLock();
|
|
@@ -23071,7 +23486,7 @@ async function readLockFile(params) {
|
|
|
23071
23486
|
}
|
|
23072
23487
|
async function writeLockFile(params) {
|
|
23073
23488
|
const { logger: logger5 } = params;
|
|
23074
|
-
const lockPath = (0,
|
|
23489
|
+
const lockPath = (0, import_node_path145.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
|
|
23075
23490
|
const content = JSON.stringify(params.lock, null, 2) + "\n";
|
|
23076
23491
|
await writeFileContent(lockPath, content);
|
|
23077
23492
|
logger5.debug(`Wrote sources lockfile to ${lockPath}`);
|
|
@@ -23245,7 +23660,7 @@ function logGitClientHints(params) {
|
|
|
23245
23660
|
async function checkLockedSkillsExist(curatedDir, skillNames) {
|
|
23246
23661
|
if (skillNames.length === 0) return true;
|
|
23247
23662
|
for (const name of skillNames) {
|
|
23248
|
-
if (!await directoryExists((0,
|
|
23663
|
+
if (!await directoryExists((0, import_node_path146.join)(curatedDir, name))) {
|
|
23249
23664
|
return false;
|
|
23250
23665
|
}
|
|
23251
23666
|
}
|
|
@@ -23253,10 +23668,10 @@ async function checkLockedSkillsExist(curatedDir, skillNames) {
|
|
|
23253
23668
|
}
|
|
23254
23669
|
async function cleanPreviousCuratedSkills(params) {
|
|
23255
23670
|
const { curatedDir, lockedSkillNames, logger: logger5 } = params;
|
|
23256
|
-
const resolvedCuratedDir = (0,
|
|
23671
|
+
const resolvedCuratedDir = (0, import_node_path146.resolve)(curatedDir);
|
|
23257
23672
|
for (const prevSkill of lockedSkillNames) {
|
|
23258
|
-
const prevDir = (0,
|
|
23259
|
-
if (!(0,
|
|
23673
|
+
const prevDir = (0, import_node_path146.join)(curatedDir, prevSkill);
|
|
23674
|
+
if (!(0, import_node_path146.resolve)(prevDir).startsWith(resolvedCuratedDir + import_node_path146.sep)) {
|
|
23260
23675
|
logger5.warn(
|
|
23261
23676
|
`Skipping removal of "${prevSkill}": resolved path is outside the curated directory.`
|
|
23262
23677
|
);
|
|
@@ -23295,9 +23710,9 @@ async function writeSkillAndComputeIntegrity(params) {
|
|
|
23295
23710
|
for (const file of files) {
|
|
23296
23711
|
checkPathTraversal({
|
|
23297
23712
|
relativePath: file.relativePath,
|
|
23298
|
-
intendedRootDir: (0,
|
|
23713
|
+
intendedRootDir: (0, import_node_path146.join)(curatedDir, skillName)
|
|
23299
23714
|
});
|
|
23300
|
-
await writeFileContent((0,
|
|
23715
|
+
await writeFileContent((0, import_node_path146.join)(curatedDir, skillName, file.relativePath), file.content);
|
|
23301
23716
|
written.push({ path: file.relativePath, content: file.content });
|
|
23302
23717
|
}
|
|
23303
23718
|
const integrity = computeSkillIntegrity(written);
|
|
@@ -23374,7 +23789,7 @@ async function fetchSource(params) {
|
|
|
23374
23789
|
ref = resolvedSha;
|
|
23375
23790
|
logger5.debug(`Resolved ${sourceKey} ref "${requestedRef}" to SHA: ${resolvedSha}`);
|
|
23376
23791
|
}
|
|
23377
|
-
const curatedDir = (0,
|
|
23792
|
+
const curatedDir = (0, import_node_path146.join)(baseDir, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
|
|
23378
23793
|
if (locked && resolvedSha === locked.resolvedRef && !updateSources) {
|
|
23379
23794
|
const allExist = await checkLockedSkillsExist(curatedDir, lockedSkillNames);
|
|
23380
23795
|
if (allExist) {
|
|
@@ -23499,7 +23914,7 @@ async function fetchSourceViaGit(params) {
|
|
|
23499
23914
|
requestedRef = def.ref;
|
|
23500
23915
|
resolvedSha = def.sha;
|
|
23501
23916
|
}
|
|
23502
|
-
const curatedDir = (0,
|
|
23917
|
+
const curatedDir = (0, import_node_path146.join)(baseDir, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
|
|
23503
23918
|
if (locked && resolvedSha === locked.resolvedRef && !updateSources) {
|
|
23504
23919
|
if (await checkLockedSkillsExist(curatedDir, lockedSkillNames)) {
|
|
23505
23920
|
return { skillCount: 0, fetchedSkillNames: lockedSkillNames, updatedLock: lock };
|
|
@@ -23615,11 +24030,11 @@ async function installCommand(logger5, options) {
|
|
|
23615
24030
|
var import_fastmcp = require("fastmcp");
|
|
23616
24031
|
|
|
23617
24032
|
// src/mcp/tools.ts
|
|
23618
|
-
var
|
|
24033
|
+
var import_mini84 = require("zod/mini");
|
|
23619
24034
|
|
|
23620
24035
|
// src/mcp/commands.ts
|
|
23621
|
-
var
|
|
23622
|
-
var
|
|
24036
|
+
var import_node_path147 = require("path");
|
|
24037
|
+
var import_mini76 = require("zod/mini");
|
|
23623
24038
|
|
|
23624
24039
|
// src/utils/logger.ts
|
|
23625
24040
|
var BaseLogger = class {
|
|
@@ -23770,7 +24185,7 @@ var logger = new ConsoleLogger({ verbose: false, silent: true });
|
|
|
23770
24185
|
var maxCommandSizeBytes = 1024 * 1024;
|
|
23771
24186
|
var maxCommandsCount = 1e3;
|
|
23772
24187
|
async function listCommands() {
|
|
23773
|
-
const commandsDir = (0,
|
|
24188
|
+
const commandsDir = (0, import_node_path147.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
|
|
23774
24189
|
try {
|
|
23775
24190
|
const files = await listDirectoryFiles(commandsDir);
|
|
23776
24191
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -23786,7 +24201,7 @@ async function listCommands() {
|
|
|
23786
24201
|
});
|
|
23787
24202
|
const frontmatter = command.getFrontmatter();
|
|
23788
24203
|
return {
|
|
23789
|
-
relativePathFromCwd: (0,
|
|
24204
|
+
relativePathFromCwd: (0, import_node_path147.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
|
|
23790
24205
|
frontmatter
|
|
23791
24206
|
};
|
|
23792
24207
|
} catch (error) {
|
|
@@ -23808,13 +24223,13 @@ async function getCommand({ relativePathFromCwd }) {
|
|
|
23808
24223
|
relativePath: relativePathFromCwd,
|
|
23809
24224
|
intendedRootDir: process.cwd()
|
|
23810
24225
|
});
|
|
23811
|
-
const filename = (0,
|
|
24226
|
+
const filename = (0, import_node_path147.basename)(relativePathFromCwd);
|
|
23812
24227
|
try {
|
|
23813
24228
|
const command = await RulesyncCommand.fromFile({
|
|
23814
24229
|
relativeFilePath: filename
|
|
23815
24230
|
});
|
|
23816
24231
|
return {
|
|
23817
|
-
relativePathFromCwd: (0,
|
|
24232
|
+
relativePathFromCwd: (0, import_node_path147.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
|
|
23818
24233
|
frontmatter: command.getFrontmatter(),
|
|
23819
24234
|
body: command.getBody()
|
|
23820
24235
|
};
|
|
@@ -23833,7 +24248,7 @@ async function putCommand({
|
|
|
23833
24248
|
relativePath: relativePathFromCwd,
|
|
23834
24249
|
intendedRootDir: process.cwd()
|
|
23835
24250
|
});
|
|
23836
|
-
const filename = (0,
|
|
24251
|
+
const filename = (0, import_node_path147.basename)(relativePathFromCwd);
|
|
23837
24252
|
const estimatedSize = JSON.stringify(frontmatter).length + body.length;
|
|
23838
24253
|
if (estimatedSize > maxCommandSizeBytes) {
|
|
23839
24254
|
throw new Error(
|
|
@@ -23843,7 +24258,7 @@ async function putCommand({
|
|
|
23843
24258
|
try {
|
|
23844
24259
|
const existingCommands = await listCommands();
|
|
23845
24260
|
const isUpdate = existingCommands.some(
|
|
23846
|
-
(command2) => command2.relativePathFromCwd === (0,
|
|
24261
|
+
(command2) => command2.relativePathFromCwd === (0, import_node_path147.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
|
|
23847
24262
|
);
|
|
23848
24263
|
if (!isUpdate && existingCommands.length >= maxCommandsCount) {
|
|
23849
24264
|
throw new Error(
|
|
@@ -23860,11 +24275,11 @@ async function putCommand({
|
|
|
23860
24275
|
fileContent,
|
|
23861
24276
|
validate: true
|
|
23862
24277
|
});
|
|
23863
|
-
const commandsDir = (0,
|
|
24278
|
+
const commandsDir = (0, import_node_path147.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
|
|
23864
24279
|
await ensureDir(commandsDir);
|
|
23865
24280
|
await writeFileContent(command.getFilePath(), command.getFileContent());
|
|
23866
24281
|
return {
|
|
23867
|
-
relativePathFromCwd: (0,
|
|
24282
|
+
relativePathFromCwd: (0, import_node_path147.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
|
|
23868
24283
|
frontmatter: command.getFrontmatter(),
|
|
23869
24284
|
body: command.getBody()
|
|
23870
24285
|
};
|
|
@@ -23879,12 +24294,12 @@ async function deleteCommand({ relativePathFromCwd }) {
|
|
|
23879
24294
|
relativePath: relativePathFromCwd,
|
|
23880
24295
|
intendedRootDir: process.cwd()
|
|
23881
24296
|
});
|
|
23882
|
-
const filename = (0,
|
|
23883
|
-
const fullPath = (0,
|
|
24297
|
+
const filename = (0, import_node_path147.basename)(relativePathFromCwd);
|
|
24298
|
+
const fullPath = (0, import_node_path147.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
|
|
23884
24299
|
try {
|
|
23885
24300
|
await removeFile(fullPath);
|
|
23886
24301
|
return {
|
|
23887
|
-
relativePathFromCwd: (0,
|
|
24302
|
+
relativePathFromCwd: (0, import_node_path147.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
|
|
23888
24303
|
};
|
|
23889
24304
|
} catch (error) {
|
|
23890
24305
|
throw new Error(`Failed to delete command file ${relativePathFromCwd}: ${formatError(error)}`, {
|
|
@@ -23893,23 +24308,23 @@ async function deleteCommand({ relativePathFromCwd }) {
|
|
|
23893
24308
|
}
|
|
23894
24309
|
}
|
|
23895
24310
|
var commandToolSchemas = {
|
|
23896
|
-
listCommands:
|
|
23897
|
-
getCommand:
|
|
23898
|
-
relativePathFromCwd:
|
|
24311
|
+
listCommands: import_mini76.z.object({}),
|
|
24312
|
+
getCommand: import_mini76.z.object({
|
|
24313
|
+
relativePathFromCwd: import_mini76.z.string()
|
|
23899
24314
|
}),
|
|
23900
|
-
putCommand:
|
|
23901
|
-
relativePathFromCwd:
|
|
24315
|
+
putCommand: import_mini76.z.object({
|
|
24316
|
+
relativePathFromCwd: import_mini76.z.string(),
|
|
23902
24317
|
frontmatter: RulesyncCommandFrontmatterSchema,
|
|
23903
|
-
body:
|
|
24318
|
+
body: import_mini76.z.string()
|
|
23904
24319
|
}),
|
|
23905
|
-
deleteCommand:
|
|
23906
|
-
relativePathFromCwd:
|
|
24320
|
+
deleteCommand: import_mini76.z.object({
|
|
24321
|
+
relativePathFromCwd: import_mini76.z.string()
|
|
23907
24322
|
})
|
|
23908
24323
|
};
|
|
23909
24324
|
var commandTools = {
|
|
23910
24325
|
listCommands: {
|
|
23911
24326
|
name: "listCommands",
|
|
23912
|
-
description: `List all commands from ${(0,
|
|
24327
|
+
description: `List all commands from ${(0, import_node_path147.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
23913
24328
|
parameters: commandToolSchemas.listCommands,
|
|
23914
24329
|
execute: async () => {
|
|
23915
24330
|
const commands = await listCommands();
|
|
@@ -23951,15 +24366,15 @@ var commandTools = {
|
|
|
23951
24366
|
};
|
|
23952
24367
|
|
|
23953
24368
|
// src/mcp/generate.ts
|
|
23954
|
-
var
|
|
23955
|
-
var generateOptionsSchema =
|
|
23956
|
-
targets:
|
|
23957
|
-
features:
|
|
23958
|
-
delete:
|
|
23959
|
-
global:
|
|
23960
|
-
simulateCommands:
|
|
23961
|
-
simulateSubagents:
|
|
23962
|
-
simulateSkills:
|
|
24369
|
+
var import_mini77 = require("zod/mini");
|
|
24370
|
+
var generateOptionsSchema = import_mini77.z.object({
|
|
24371
|
+
targets: import_mini77.z.optional(import_mini77.z.array(import_mini77.z.string())),
|
|
24372
|
+
features: import_mini77.z.optional(import_mini77.z.array(import_mini77.z.string())),
|
|
24373
|
+
delete: import_mini77.z.optional(import_mini77.z.boolean()),
|
|
24374
|
+
global: import_mini77.z.optional(import_mini77.z.boolean()),
|
|
24375
|
+
simulateCommands: import_mini77.z.optional(import_mini77.z.boolean()),
|
|
24376
|
+
simulateSubagents: import_mini77.z.optional(import_mini77.z.boolean()),
|
|
24377
|
+
simulateSkills: import_mini77.z.optional(import_mini77.z.boolean())
|
|
23963
24378
|
});
|
|
23964
24379
|
async function executeGenerate(options = {}) {
|
|
23965
24380
|
try {
|
|
@@ -24038,11 +24453,11 @@ var generateTools = {
|
|
|
24038
24453
|
};
|
|
24039
24454
|
|
|
24040
24455
|
// src/mcp/ignore.ts
|
|
24041
|
-
var
|
|
24042
|
-
var
|
|
24456
|
+
var import_node_path148 = require("path");
|
|
24457
|
+
var import_mini78 = require("zod/mini");
|
|
24043
24458
|
var maxIgnoreFileSizeBytes = 100 * 1024;
|
|
24044
24459
|
async function getIgnoreFile() {
|
|
24045
|
-
const ignoreFilePath = (0,
|
|
24460
|
+
const ignoreFilePath = (0, import_node_path148.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
24046
24461
|
try {
|
|
24047
24462
|
const content = await readFileContent(ignoreFilePath);
|
|
24048
24463
|
return {
|
|
@@ -24059,7 +24474,7 @@ async function getIgnoreFile() {
|
|
|
24059
24474
|
}
|
|
24060
24475
|
}
|
|
24061
24476
|
async function putIgnoreFile({ content }) {
|
|
24062
|
-
const ignoreFilePath = (0,
|
|
24477
|
+
const ignoreFilePath = (0, import_node_path148.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
24063
24478
|
const contentSizeBytes = Buffer.byteLength(content, "utf8");
|
|
24064
24479
|
if (contentSizeBytes > maxIgnoreFileSizeBytes) {
|
|
24065
24480
|
throw new Error(
|
|
@@ -24083,8 +24498,8 @@ async function putIgnoreFile({ content }) {
|
|
|
24083
24498
|
}
|
|
24084
24499
|
}
|
|
24085
24500
|
async function deleteIgnoreFile() {
|
|
24086
|
-
const aiignorePath = (0,
|
|
24087
|
-
const legacyIgnorePath = (0,
|
|
24501
|
+
const aiignorePath = (0, import_node_path148.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
24502
|
+
const legacyIgnorePath = (0, import_node_path148.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
|
|
24088
24503
|
try {
|
|
24089
24504
|
await Promise.all([removeFile(aiignorePath), removeFile(legacyIgnorePath)]);
|
|
24090
24505
|
return {
|
|
@@ -24102,11 +24517,11 @@ async function deleteIgnoreFile() {
|
|
|
24102
24517
|
}
|
|
24103
24518
|
}
|
|
24104
24519
|
var ignoreToolSchemas = {
|
|
24105
|
-
getIgnoreFile:
|
|
24106
|
-
putIgnoreFile:
|
|
24107
|
-
content:
|
|
24520
|
+
getIgnoreFile: import_mini78.z.object({}),
|
|
24521
|
+
putIgnoreFile: import_mini78.z.object({
|
|
24522
|
+
content: import_mini78.z.string()
|
|
24108
24523
|
}),
|
|
24109
|
-
deleteIgnoreFile:
|
|
24524
|
+
deleteIgnoreFile: import_mini78.z.object({})
|
|
24110
24525
|
};
|
|
24111
24526
|
var ignoreTools = {
|
|
24112
24527
|
getIgnoreFile: {
|
|
@@ -24139,11 +24554,11 @@ var ignoreTools = {
|
|
|
24139
24554
|
};
|
|
24140
24555
|
|
|
24141
24556
|
// src/mcp/import.ts
|
|
24142
|
-
var
|
|
24143
|
-
var importOptionsSchema =
|
|
24144
|
-
target:
|
|
24145
|
-
features:
|
|
24146
|
-
global:
|
|
24557
|
+
var import_mini79 = require("zod/mini");
|
|
24558
|
+
var importOptionsSchema = import_mini79.z.object({
|
|
24559
|
+
target: import_mini79.z.string(),
|
|
24560
|
+
features: import_mini79.z.optional(import_mini79.z.array(import_mini79.z.string())),
|
|
24561
|
+
global: import_mini79.z.optional(import_mini79.z.boolean())
|
|
24147
24562
|
});
|
|
24148
24563
|
async function executeImport(options) {
|
|
24149
24564
|
try {
|
|
@@ -24214,15 +24629,15 @@ var importTools = {
|
|
|
24214
24629
|
};
|
|
24215
24630
|
|
|
24216
24631
|
// src/mcp/mcp.ts
|
|
24217
|
-
var
|
|
24218
|
-
var
|
|
24632
|
+
var import_node_path149 = require("path");
|
|
24633
|
+
var import_mini80 = require("zod/mini");
|
|
24219
24634
|
var maxMcpSizeBytes = 1024 * 1024;
|
|
24220
24635
|
async function getMcpFile() {
|
|
24221
24636
|
try {
|
|
24222
24637
|
const rulesyncMcp = await RulesyncMcp.fromFile({
|
|
24223
24638
|
validate: true
|
|
24224
24639
|
});
|
|
24225
|
-
const relativePathFromCwd = (0,
|
|
24640
|
+
const relativePathFromCwd = (0, import_node_path149.join)(
|
|
24226
24641
|
rulesyncMcp.getRelativeDirPath(),
|
|
24227
24642
|
rulesyncMcp.getRelativeFilePath()
|
|
24228
24643
|
);
|
|
@@ -24260,7 +24675,7 @@ async function putMcpFile({ content }) {
|
|
|
24260
24675
|
const paths = RulesyncMcp.getSettablePaths();
|
|
24261
24676
|
const relativeDirPath = paths.recommended.relativeDirPath;
|
|
24262
24677
|
const relativeFilePath = paths.recommended.relativeFilePath;
|
|
24263
|
-
const fullPath = (0,
|
|
24678
|
+
const fullPath = (0, import_node_path149.join)(baseDir, relativeDirPath, relativeFilePath);
|
|
24264
24679
|
const rulesyncMcp = new RulesyncMcp({
|
|
24265
24680
|
baseDir,
|
|
24266
24681
|
relativeDirPath,
|
|
@@ -24268,9 +24683,9 @@ async function putMcpFile({ content }) {
|
|
|
24268
24683
|
fileContent: content,
|
|
24269
24684
|
validate: true
|
|
24270
24685
|
});
|
|
24271
|
-
await ensureDir((0,
|
|
24686
|
+
await ensureDir((0, import_node_path149.join)(baseDir, relativeDirPath));
|
|
24272
24687
|
await writeFileContent(fullPath, content);
|
|
24273
|
-
const relativePathFromCwd = (0,
|
|
24688
|
+
const relativePathFromCwd = (0, import_node_path149.join)(relativeDirPath, relativeFilePath);
|
|
24274
24689
|
return {
|
|
24275
24690
|
relativePathFromCwd,
|
|
24276
24691
|
content: rulesyncMcp.getFileContent()
|
|
@@ -24288,15 +24703,15 @@ async function deleteMcpFile() {
|
|
|
24288
24703
|
try {
|
|
24289
24704
|
const baseDir = process.cwd();
|
|
24290
24705
|
const paths = RulesyncMcp.getSettablePaths();
|
|
24291
|
-
const recommendedPath = (0,
|
|
24706
|
+
const recommendedPath = (0, import_node_path149.join)(
|
|
24292
24707
|
baseDir,
|
|
24293
24708
|
paths.recommended.relativeDirPath,
|
|
24294
24709
|
paths.recommended.relativeFilePath
|
|
24295
24710
|
);
|
|
24296
|
-
const legacyPath = (0,
|
|
24711
|
+
const legacyPath = (0, import_node_path149.join)(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
|
|
24297
24712
|
await removeFile(recommendedPath);
|
|
24298
24713
|
await removeFile(legacyPath);
|
|
24299
|
-
const relativePathFromCwd = (0,
|
|
24714
|
+
const relativePathFromCwd = (0, import_node_path149.join)(
|
|
24300
24715
|
paths.recommended.relativeDirPath,
|
|
24301
24716
|
paths.recommended.relativeFilePath
|
|
24302
24717
|
);
|
|
@@ -24313,11 +24728,11 @@ async function deleteMcpFile() {
|
|
|
24313
24728
|
}
|
|
24314
24729
|
}
|
|
24315
24730
|
var mcpToolSchemas = {
|
|
24316
|
-
getMcpFile:
|
|
24317
|
-
putMcpFile:
|
|
24318
|
-
content:
|
|
24731
|
+
getMcpFile: import_mini80.z.object({}),
|
|
24732
|
+
putMcpFile: import_mini80.z.object({
|
|
24733
|
+
content: import_mini80.z.string()
|
|
24319
24734
|
}),
|
|
24320
|
-
deleteMcpFile:
|
|
24735
|
+
deleteMcpFile: import_mini80.z.object({})
|
|
24321
24736
|
};
|
|
24322
24737
|
var mcpTools = {
|
|
24323
24738
|
getMcpFile: {
|
|
@@ -24350,13 +24765,13 @@ var mcpTools = {
|
|
|
24350
24765
|
};
|
|
24351
24766
|
|
|
24352
24767
|
// src/mcp/rules.ts
|
|
24353
|
-
var
|
|
24354
|
-
var
|
|
24768
|
+
var import_node_path150 = require("path");
|
|
24769
|
+
var import_mini81 = require("zod/mini");
|
|
24355
24770
|
var logger2 = new ConsoleLogger({ verbose: false, silent: true });
|
|
24356
24771
|
var maxRuleSizeBytes = 1024 * 1024;
|
|
24357
24772
|
var maxRulesCount = 1e3;
|
|
24358
24773
|
async function listRules() {
|
|
24359
|
-
const rulesDir = (0,
|
|
24774
|
+
const rulesDir = (0, import_node_path150.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
|
|
24360
24775
|
try {
|
|
24361
24776
|
const files = await listDirectoryFiles(rulesDir);
|
|
24362
24777
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -24369,7 +24784,7 @@ async function listRules() {
|
|
|
24369
24784
|
});
|
|
24370
24785
|
const frontmatter = rule.getFrontmatter();
|
|
24371
24786
|
return {
|
|
24372
|
-
relativePathFromCwd: (0,
|
|
24787
|
+
relativePathFromCwd: (0, import_node_path150.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
|
|
24373
24788
|
frontmatter
|
|
24374
24789
|
};
|
|
24375
24790
|
} catch (error) {
|
|
@@ -24391,14 +24806,14 @@ async function getRule({ relativePathFromCwd }) {
|
|
|
24391
24806
|
relativePath: relativePathFromCwd,
|
|
24392
24807
|
intendedRootDir: process.cwd()
|
|
24393
24808
|
});
|
|
24394
|
-
const filename = (0,
|
|
24809
|
+
const filename = (0, import_node_path150.basename)(relativePathFromCwd);
|
|
24395
24810
|
try {
|
|
24396
24811
|
const rule = await RulesyncRule.fromFile({
|
|
24397
24812
|
relativeFilePath: filename,
|
|
24398
24813
|
validate: true
|
|
24399
24814
|
});
|
|
24400
24815
|
return {
|
|
24401
|
-
relativePathFromCwd: (0,
|
|
24816
|
+
relativePathFromCwd: (0, import_node_path150.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
|
|
24402
24817
|
frontmatter: rule.getFrontmatter(),
|
|
24403
24818
|
body: rule.getBody()
|
|
24404
24819
|
};
|
|
@@ -24417,7 +24832,7 @@ async function putRule({
|
|
|
24417
24832
|
relativePath: relativePathFromCwd,
|
|
24418
24833
|
intendedRootDir: process.cwd()
|
|
24419
24834
|
});
|
|
24420
|
-
const filename = (0,
|
|
24835
|
+
const filename = (0, import_node_path150.basename)(relativePathFromCwd);
|
|
24421
24836
|
const estimatedSize = JSON.stringify(frontmatter).length + body.length;
|
|
24422
24837
|
if (estimatedSize > maxRuleSizeBytes) {
|
|
24423
24838
|
throw new Error(
|
|
@@ -24427,7 +24842,7 @@ async function putRule({
|
|
|
24427
24842
|
try {
|
|
24428
24843
|
const existingRules = await listRules();
|
|
24429
24844
|
const isUpdate = existingRules.some(
|
|
24430
|
-
(rule2) => rule2.relativePathFromCwd === (0,
|
|
24845
|
+
(rule2) => rule2.relativePathFromCwd === (0, import_node_path150.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
|
|
24431
24846
|
);
|
|
24432
24847
|
if (!isUpdate && existingRules.length >= maxRulesCount) {
|
|
24433
24848
|
throw new Error(
|
|
@@ -24442,11 +24857,11 @@ async function putRule({
|
|
|
24442
24857
|
body,
|
|
24443
24858
|
validate: true
|
|
24444
24859
|
});
|
|
24445
|
-
const rulesDir = (0,
|
|
24860
|
+
const rulesDir = (0, import_node_path150.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
|
|
24446
24861
|
await ensureDir(rulesDir);
|
|
24447
24862
|
await writeFileContent(rule.getFilePath(), rule.getFileContent());
|
|
24448
24863
|
return {
|
|
24449
|
-
relativePathFromCwd: (0,
|
|
24864
|
+
relativePathFromCwd: (0, import_node_path150.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
|
|
24450
24865
|
frontmatter: rule.getFrontmatter(),
|
|
24451
24866
|
body: rule.getBody()
|
|
24452
24867
|
};
|
|
@@ -24461,12 +24876,12 @@ async function deleteRule({ relativePathFromCwd }) {
|
|
|
24461
24876
|
relativePath: relativePathFromCwd,
|
|
24462
24877
|
intendedRootDir: process.cwd()
|
|
24463
24878
|
});
|
|
24464
|
-
const filename = (0,
|
|
24465
|
-
const fullPath = (0,
|
|
24879
|
+
const filename = (0, import_node_path150.basename)(relativePathFromCwd);
|
|
24880
|
+
const fullPath = (0, import_node_path150.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
|
|
24466
24881
|
try {
|
|
24467
24882
|
await removeFile(fullPath);
|
|
24468
24883
|
return {
|
|
24469
|
-
relativePathFromCwd: (0,
|
|
24884
|
+
relativePathFromCwd: (0, import_node_path150.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
|
|
24470
24885
|
};
|
|
24471
24886
|
} catch (error) {
|
|
24472
24887
|
throw new Error(`Failed to delete rule file ${relativePathFromCwd}: ${formatError(error)}`, {
|
|
@@ -24475,23 +24890,23 @@ async function deleteRule({ relativePathFromCwd }) {
|
|
|
24475
24890
|
}
|
|
24476
24891
|
}
|
|
24477
24892
|
var ruleToolSchemas = {
|
|
24478
|
-
listRules:
|
|
24479
|
-
getRule:
|
|
24480
|
-
relativePathFromCwd:
|
|
24893
|
+
listRules: import_mini81.z.object({}),
|
|
24894
|
+
getRule: import_mini81.z.object({
|
|
24895
|
+
relativePathFromCwd: import_mini81.z.string()
|
|
24481
24896
|
}),
|
|
24482
|
-
putRule:
|
|
24483
|
-
relativePathFromCwd:
|
|
24897
|
+
putRule: import_mini81.z.object({
|
|
24898
|
+
relativePathFromCwd: import_mini81.z.string(),
|
|
24484
24899
|
frontmatter: RulesyncRuleFrontmatterSchema,
|
|
24485
|
-
body:
|
|
24900
|
+
body: import_mini81.z.string()
|
|
24486
24901
|
}),
|
|
24487
|
-
deleteRule:
|
|
24488
|
-
relativePathFromCwd:
|
|
24902
|
+
deleteRule: import_mini81.z.object({
|
|
24903
|
+
relativePathFromCwd: import_mini81.z.string()
|
|
24489
24904
|
})
|
|
24490
24905
|
};
|
|
24491
24906
|
var ruleTools = {
|
|
24492
24907
|
listRules: {
|
|
24493
24908
|
name: "listRules",
|
|
24494
|
-
description: `List all rules from ${(0,
|
|
24909
|
+
description: `List all rules from ${(0, import_node_path150.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
24495
24910
|
parameters: ruleToolSchemas.listRules,
|
|
24496
24911
|
execute: async () => {
|
|
24497
24912
|
const rules = await listRules();
|
|
@@ -24533,8 +24948,8 @@ var ruleTools = {
|
|
|
24533
24948
|
};
|
|
24534
24949
|
|
|
24535
24950
|
// src/mcp/skills.ts
|
|
24536
|
-
var
|
|
24537
|
-
var
|
|
24951
|
+
var import_node_path151 = require("path");
|
|
24952
|
+
var import_mini82 = require("zod/mini");
|
|
24538
24953
|
var logger3 = new ConsoleLogger({ verbose: false, silent: true });
|
|
24539
24954
|
var maxSkillSizeBytes = 1024 * 1024;
|
|
24540
24955
|
var maxSkillsCount = 1e3;
|
|
@@ -24551,19 +24966,19 @@ function mcpSkillFileToAiDirFile(file) {
|
|
|
24551
24966
|
};
|
|
24552
24967
|
}
|
|
24553
24968
|
function extractDirName(relativeDirPathFromCwd) {
|
|
24554
|
-
const dirName = (0,
|
|
24969
|
+
const dirName = (0, import_node_path151.basename)(relativeDirPathFromCwd);
|
|
24555
24970
|
if (!dirName) {
|
|
24556
24971
|
throw new Error(`Invalid path: ${relativeDirPathFromCwd}`);
|
|
24557
24972
|
}
|
|
24558
24973
|
return dirName;
|
|
24559
24974
|
}
|
|
24560
24975
|
async function listSkills() {
|
|
24561
|
-
const skillsDir = (0,
|
|
24976
|
+
const skillsDir = (0, import_node_path151.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH);
|
|
24562
24977
|
try {
|
|
24563
|
-
const skillDirPaths = await findFilesByGlobs((0,
|
|
24978
|
+
const skillDirPaths = await findFilesByGlobs((0, import_node_path151.join)(skillsDir, "*"), { type: "dir" });
|
|
24564
24979
|
const skills = await Promise.all(
|
|
24565
24980
|
skillDirPaths.map(async (dirPath) => {
|
|
24566
|
-
const dirName = (0,
|
|
24981
|
+
const dirName = (0, import_node_path151.basename)(dirPath);
|
|
24567
24982
|
if (!dirName) return null;
|
|
24568
24983
|
try {
|
|
24569
24984
|
const skill = await RulesyncSkill.fromDir({
|
|
@@ -24571,7 +24986,7 @@ async function listSkills() {
|
|
|
24571
24986
|
});
|
|
24572
24987
|
const frontmatter = skill.getFrontmatter();
|
|
24573
24988
|
return {
|
|
24574
|
-
relativeDirPathFromCwd: (0,
|
|
24989
|
+
relativeDirPathFromCwd: (0, import_node_path151.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
24575
24990
|
frontmatter
|
|
24576
24991
|
};
|
|
24577
24992
|
} catch (error) {
|
|
@@ -24599,7 +25014,7 @@ async function getSkill({ relativeDirPathFromCwd }) {
|
|
|
24599
25014
|
dirName
|
|
24600
25015
|
});
|
|
24601
25016
|
return {
|
|
24602
|
-
relativeDirPathFromCwd: (0,
|
|
25017
|
+
relativeDirPathFromCwd: (0, import_node_path151.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
24603
25018
|
frontmatter: skill.getFrontmatter(),
|
|
24604
25019
|
body: skill.getBody(),
|
|
24605
25020
|
otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
|
|
@@ -24633,7 +25048,7 @@ async function putSkill({
|
|
|
24633
25048
|
try {
|
|
24634
25049
|
const existingSkills = await listSkills();
|
|
24635
25050
|
const isUpdate = existingSkills.some(
|
|
24636
|
-
(skill2) => skill2.relativeDirPathFromCwd === (0,
|
|
25051
|
+
(skill2) => skill2.relativeDirPathFromCwd === (0, import_node_path151.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
|
|
24637
25052
|
);
|
|
24638
25053
|
if (!isUpdate && existingSkills.length >= maxSkillsCount) {
|
|
24639
25054
|
throw new Error(
|
|
@@ -24650,9 +25065,9 @@ async function putSkill({
|
|
|
24650
25065
|
otherFiles: aiDirFiles,
|
|
24651
25066
|
validate: true
|
|
24652
25067
|
});
|
|
24653
|
-
const skillDirPath = (0,
|
|
25068
|
+
const skillDirPath = (0, import_node_path151.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
|
|
24654
25069
|
await ensureDir(skillDirPath);
|
|
24655
|
-
const skillFilePath = (0,
|
|
25070
|
+
const skillFilePath = (0, import_node_path151.join)(skillDirPath, SKILL_FILE_NAME);
|
|
24656
25071
|
const skillFileContent = stringifyFrontmatter(body, frontmatter);
|
|
24657
25072
|
await writeFileContent(skillFilePath, skillFileContent);
|
|
24658
25073
|
for (const file of otherFiles) {
|
|
@@ -24660,15 +25075,15 @@ async function putSkill({
|
|
|
24660
25075
|
relativePath: file.name,
|
|
24661
25076
|
intendedRootDir: skillDirPath
|
|
24662
25077
|
});
|
|
24663
|
-
const filePath = (0,
|
|
24664
|
-
const fileDir = (0,
|
|
25078
|
+
const filePath = (0, import_node_path151.join)(skillDirPath, file.name);
|
|
25079
|
+
const fileDir = (0, import_node_path151.join)(skillDirPath, (0, import_node_path151.dirname)(file.name));
|
|
24665
25080
|
if (fileDir !== skillDirPath) {
|
|
24666
25081
|
await ensureDir(fileDir);
|
|
24667
25082
|
}
|
|
24668
25083
|
await writeFileContent(filePath, file.body);
|
|
24669
25084
|
}
|
|
24670
25085
|
return {
|
|
24671
|
-
relativeDirPathFromCwd: (0,
|
|
25086
|
+
relativeDirPathFromCwd: (0, import_node_path151.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
24672
25087
|
frontmatter: skill.getFrontmatter(),
|
|
24673
25088
|
body: skill.getBody(),
|
|
24674
25089
|
otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
|
|
@@ -24690,13 +25105,13 @@ async function deleteSkill({
|
|
|
24690
25105
|
intendedRootDir: process.cwd()
|
|
24691
25106
|
});
|
|
24692
25107
|
const dirName = extractDirName(relativeDirPathFromCwd);
|
|
24693
|
-
const skillDirPath = (0,
|
|
25108
|
+
const skillDirPath = (0, import_node_path151.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
|
|
24694
25109
|
try {
|
|
24695
25110
|
if (await directoryExists(skillDirPath)) {
|
|
24696
25111
|
await removeDirectory(skillDirPath);
|
|
24697
25112
|
}
|
|
24698
25113
|
return {
|
|
24699
|
-
relativeDirPathFromCwd: (0,
|
|
25114
|
+
relativeDirPathFromCwd: (0, import_node_path151.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
|
|
24700
25115
|
};
|
|
24701
25116
|
} catch (error) {
|
|
24702
25117
|
throw new Error(
|
|
@@ -24707,29 +25122,29 @@ async function deleteSkill({
|
|
|
24707
25122
|
);
|
|
24708
25123
|
}
|
|
24709
25124
|
}
|
|
24710
|
-
var McpSkillFileSchema =
|
|
24711
|
-
name:
|
|
24712
|
-
body:
|
|
25125
|
+
var McpSkillFileSchema = import_mini82.z.object({
|
|
25126
|
+
name: import_mini82.z.string(),
|
|
25127
|
+
body: import_mini82.z.string()
|
|
24713
25128
|
});
|
|
24714
25129
|
var skillToolSchemas = {
|
|
24715
|
-
listSkills:
|
|
24716
|
-
getSkill:
|
|
24717
|
-
relativeDirPathFromCwd:
|
|
25130
|
+
listSkills: import_mini82.z.object({}),
|
|
25131
|
+
getSkill: import_mini82.z.object({
|
|
25132
|
+
relativeDirPathFromCwd: import_mini82.z.string()
|
|
24718
25133
|
}),
|
|
24719
|
-
putSkill:
|
|
24720
|
-
relativeDirPathFromCwd:
|
|
25134
|
+
putSkill: import_mini82.z.object({
|
|
25135
|
+
relativeDirPathFromCwd: import_mini82.z.string(),
|
|
24721
25136
|
frontmatter: RulesyncSkillFrontmatterSchema,
|
|
24722
|
-
body:
|
|
24723
|
-
otherFiles:
|
|
25137
|
+
body: import_mini82.z.string(),
|
|
25138
|
+
otherFiles: import_mini82.z.optional(import_mini82.z.array(McpSkillFileSchema))
|
|
24724
25139
|
}),
|
|
24725
|
-
deleteSkill:
|
|
24726
|
-
relativeDirPathFromCwd:
|
|
25140
|
+
deleteSkill: import_mini82.z.object({
|
|
25141
|
+
relativeDirPathFromCwd: import_mini82.z.string()
|
|
24727
25142
|
})
|
|
24728
25143
|
};
|
|
24729
25144
|
var skillTools = {
|
|
24730
25145
|
listSkills: {
|
|
24731
25146
|
name: "listSkills",
|
|
24732
|
-
description: `List all skills from ${(0,
|
|
25147
|
+
description: `List all skills from ${(0, import_node_path151.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "*", SKILL_FILE_NAME)} with their frontmatter.`,
|
|
24733
25148
|
parameters: skillToolSchemas.listSkills,
|
|
24734
25149
|
execute: async () => {
|
|
24735
25150
|
const skills = await listSkills();
|
|
@@ -24772,13 +25187,13 @@ var skillTools = {
|
|
|
24772
25187
|
};
|
|
24773
25188
|
|
|
24774
25189
|
// src/mcp/subagents.ts
|
|
24775
|
-
var
|
|
24776
|
-
var
|
|
25190
|
+
var import_node_path152 = require("path");
|
|
25191
|
+
var import_mini83 = require("zod/mini");
|
|
24777
25192
|
var logger4 = new ConsoleLogger({ verbose: false, silent: true });
|
|
24778
25193
|
var maxSubagentSizeBytes = 1024 * 1024;
|
|
24779
25194
|
var maxSubagentsCount = 1e3;
|
|
24780
25195
|
async function listSubagents() {
|
|
24781
|
-
const subagentsDir = (0,
|
|
25196
|
+
const subagentsDir = (0, import_node_path152.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
|
|
24782
25197
|
try {
|
|
24783
25198
|
const files = await listDirectoryFiles(subagentsDir);
|
|
24784
25199
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -24791,7 +25206,7 @@ async function listSubagents() {
|
|
|
24791
25206
|
});
|
|
24792
25207
|
const frontmatter = subagent.getFrontmatter();
|
|
24793
25208
|
return {
|
|
24794
|
-
relativePathFromCwd: (0,
|
|
25209
|
+
relativePathFromCwd: (0, import_node_path152.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
|
|
24795
25210
|
frontmatter
|
|
24796
25211
|
};
|
|
24797
25212
|
} catch (error) {
|
|
@@ -24815,14 +25230,14 @@ async function getSubagent({ relativePathFromCwd }) {
|
|
|
24815
25230
|
relativePath: relativePathFromCwd,
|
|
24816
25231
|
intendedRootDir: process.cwd()
|
|
24817
25232
|
});
|
|
24818
|
-
const filename = (0,
|
|
25233
|
+
const filename = (0, import_node_path152.basename)(relativePathFromCwd);
|
|
24819
25234
|
try {
|
|
24820
25235
|
const subagent = await RulesyncSubagent.fromFile({
|
|
24821
25236
|
relativeFilePath: filename,
|
|
24822
25237
|
validate: true
|
|
24823
25238
|
});
|
|
24824
25239
|
return {
|
|
24825
|
-
relativePathFromCwd: (0,
|
|
25240
|
+
relativePathFromCwd: (0, import_node_path152.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
|
|
24826
25241
|
frontmatter: subagent.getFrontmatter(),
|
|
24827
25242
|
body: subagent.getBody()
|
|
24828
25243
|
};
|
|
@@ -24841,7 +25256,7 @@ async function putSubagent({
|
|
|
24841
25256
|
relativePath: relativePathFromCwd,
|
|
24842
25257
|
intendedRootDir: process.cwd()
|
|
24843
25258
|
});
|
|
24844
|
-
const filename = (0,
|
|
25259
|
+
const filename = (0, import_node_path152.basename)(relativePathFromCwd);
|
|
24845
25260
|
const estimatedSize = JSON.stringify(frontmatter).length + body.length;
|
|
24846
25261
|
if (estimatedSize > maxSubagentSizeBytes) {
|
|
24847
25262
|
throw new Error(
|
|
@@ -24851,7 +25266,7 @@ async function putSubagent({
|
|
|
24851
25266
|
try {
|
|
24852
25267
|
const existingSubagents = await listSubagents();
|
|
24853
25268
|
const isUpdate = existingSubagents.some(
|
|
24854
|
-
(subagent2) => subagent2.relativePathFromCwd === (0,
|
|
25269
|
+
(subagent2) => subagent2.relativePathFromCwd === (0, import_node_path152.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
|
|
24855
25270
|
);
|
|
24856
25271
|
if (!isUpdate && existingSubagents.length >= maxSubagentsCount) {
|
|
24857
25272
|
throw new Error(
|
|
@@ -24866,11 +25281,11 @@ async function putSubagent({
|
|
|
24866
25281
|
body,
|
|
24867
25282
|
validate: true
|
|
24868
25283
|
});
|
|
24869
|
-
const subagentsDir = (0,
|
|
25284
|
+
const subagentsDir = (0, import_node_path152.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
|
|
24870
25285
|
await ensureDir(subagentsDir);
|
|
24871
25286
|
await writeFileContent(subagent.getFilePath(), subagent.getFileContent());
|
|
24872
25287
|
return {
|
|
24873
|
-
relativePathFromCwd: (0,
|
|
25288
|
+
relativePathFromCwd: (0, import_node_path152.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
|
|
24874
25289
|
frontmatter: subagent.getFrontmatter(),
|
|
24875
25290
|
body: subagent.getBody()
|
|
24876
25291
|
};
|
|
@@ -24885,12 +25300,12 @@ async function deleteSubagent({ relativePathFromCwd }) {
|
|
|
24885
25300
|
relativePath: relativePathFromCwd,
|
|
24886
25301
|
intendedRootDir: process.cwd()
|
|
24887
25302
|
});
|
|
24888
|
-
const filename = (0,
|
|
24889
|
-
const fullPath = (0,
|
|
25303
|
+
const filename = (0, import_node_path152.basename)(relativePathFromCwd);
|
|
25304
|
+
const fullPath = (0, import_node_path152.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
|
|
24890
25305
|
try {
|
|
24891
25306
|
await removeFile(fullPath);
|
|
24892
25307
|
return {
|
|
24893
|
-
relativePathFromCwd: (0,
|
|
25308
|
+
relativePathFromCwd: (0, import_node_path152.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
|
|
24894
25309
|
};
|
|
24895
25310
|
} catch (error) {
|
|
24896
25311
|
throw new Error(
|
|
@@ -24902,23 +25317,23 @@ async function deleteSubagent({ relativePathFromCwd }) {
|
|
|
24902
25317
|
}
|
|
24903
25318
|
}
|
|
24904
25319
|
var subagentToolSchemas = {
|
|
24905
|
-
listSubagents:
|
|
24906
|
-
getSubagent:
|
|
24907
|
-
relativePathFromCwd:
|
|
25320
|
+
listSubagents: import_mini83.z.object({}),
|
|
25321
|
+
getSubagent: import_mini83.z.object({
|
|
25322
|
+
relativePathFromCwd: import_mini83.z.string()
|
|
24908
25323
|
}),
|
|
24909
|
-
putSubagent:
|
|
24910
|
-
relativePathFromCwd:
|
|
25324
|
+
putSubagent: import_mini83.z.object({
|
|
25325
|
+
relativePathFromCwd: import_mini83.z.string(),
|
|
24911
25326
|
frontmatter: RulesyncSubagentFrontmatterSchema,
|
|
24912
|
-
body:
|
|
25327
|
+
body: import_mini83.z.string()
|
|
24913
25328
|
}),
|
|
24914
|
-
deleteSubagent:
|
|
24915
|
-
relativePathFromCwd:
|
|
25329
|
+
deleteSubagent: import_mini83.z.object({
|
|
25330
|
+
relativePathFromCwd: import_mini83.z.string()
|
|
24916
25331
|
})
|
|
24917
25332
|
};
|
|
24918
25333
|
var subagentTools = {
|
|
24919
25334
|
listSubagents: {
|
|
24920
25335
|
name: "listSubagents",
|
|
24921
|
-
description: `List all subagents from ${(0,
|
|
25336
|
+
description: `List all subagents from ${(0, import_node_path152.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
24922
25337
|
parameters: subagentToolSchemas.listSubagents,
|
|
24923
25338
|
execute: async () => {
|
|
24924
25339
|
const subagents = await listSubagents();
|
|
@@ -24960,7 +25375,7 @@ var subagentTools = {
|
|
|
24960
25375
|
};
|
|
24961
25376
|
|
|
24962
25377
|
// src/mcp/tools.ts
|
|
24963
|
-
var rulesyncFeatureSchema =
|
|
25378
|
+
var rulesyncFeatureSchema = import_mini84.z.enum([
|
|
24964
25379
|
"rule",
|
|
24965
25380
|
"command",
|
|
24966
25381
|
"subagent",
|
|
@@ -24970,21 +25385,21 @@ var rulesyncFeatureSchema = import_mini83.z.enum([
|
|
|
24970
25385
|
"generate",
|
|
24971
25386
|
"import"
|
|
24972
25387
|
]);
|
|
24973
|
-
var rulesyncOperationSchema =
|
|
24974
|
-
var skillFileSchema =
|
|
24975
|
-
name:
|
|
24976
|
-
body:
|
|
25388
|
+
var rulesyncOperationSchema = import_mini84.z.enum(["list", "get", "put", "delete", "run"]);
|
|
25389
|
+
var skillFileSchema = import_mini84.z.object({
|
|
25390
|
+
name: import_mini84.z.string(),
|
|
25391
|
+
body: import_mini84.z.string()
|
|
24977
25392
|
});
|
|
24978
|
-
var rulesyncToolSchema =
|
|
25393
|
+
var rulesyncToolSchema = import_mini84.z.object({
|
|
24979
25394
|
feature: rulesyncFeatureSchema,
|
|
24980
25395
|
operation: rulesyncOperationSchema,
|
|
24981
|
-
targetPathFromCwd:
|
|
24982
|
-
frontmatter:
|
|
24983
|
-
body:
|
|
24984
|
-
otherFiles:
|
|
24985
|
-
content:
|
|
24986
|
-
generateOptions:
|
|
24987
|
-
importOptions:
|
|
25396
|
+
targetPathFromCwd: import_mini84.z.optional(import_mini84.z.string()),
|
|
25397
|
+
frontmatter: import_mini84.z.optional(import_mini84.z.unknown()),
|
|
25398
|
+
body: import_mini84.z.optional(import_mini84.z.string()),
|
|
25399
|
+
otherFiles: import_mini84.z.optional(import_mini84.z.array(skillFileSchema)),
|
|
25400
|
+
content: import_mini84.z.optional(import_mini84.z.string()),
|
|
25401
|
+
generateOptions: import_mini84.z.optional(generateOptionsSchema),
|
|
25402
|
+
importOptions: import_mini84.z.optional(importOptionsSchema)
|
|
24988
25403
|
});
|
|
24989
25404
|
var supportedOperationsByFeature = {
|
|
24990
25405
|
rule: ["list", "get", "put", "delete"],
|
|
@@ -25191,7 +25606,7 @@ async function mcpCommand(logger5, { version }) {
|
|
|
25191
25606
|
}
|
|
25192
25607
|
|
|
25193
25608
|
// src/cli/commands/resolve-gitignore-targets.ts
|
|
25194
|
-
var
|
|
25609
|
+
var import_node_path153 = require("path");
|
|
25195
25610
|
var resolveGitignoreTargets = async ({
|
|
25196
25611
|
cliTargets,
|
|
25197
25612
|
cwd = process.cwd()
|
|
@@ -25199,8 +25614,8 @@ var resolveGitignoreTargets = async ({
|
|
|
25199
25614
|
if (cliTargets !== void 0) {
|
|
25200
25615
|
return cliTargets;
|
|
25201
25616
|
}
|
|
25202
|
-
const baseConfigPath = (0,
|
|
25203
|
-
const localConfigPath = (0,
|
|
25617
|
+
const baseConfigPath = (0, import_node_path153.join)(cwd, RULESYNC_CONFIG_RELATIVE_FILE_PATH);
|
|
25618
|
+
const localConfigPath = (0, import_node_path153.join)(cwd, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH);
|
|
25204
25619
|
const [hasBase, hasLocal] = await Promise.all([
|
|
25205
25620
|
fileExists(baseConfigPath),
|
|
25206
25621
|
fileExists(localConfigPath)
|
|
@@ -25210,7 +25625,11 @@ var resolveGitignoreTargets = async ({
|
|
|
25210
25625
|
}
|
|
25211
25626
|
const config = await ConfigResolver.resolve({});
|
|
25212
25627
|
if (config.getGitignoreTargetsOnly()) {
|
|
25213
|
-
|
|
25628
|
+
const targets = config.getTargets();
|
|
25629
|
+
if (targets.includes("agentsmd")) {
|
|
25630
|
+
return targets;
|
|
25631
|
+
}
|
|
25632
|
+
return [...targets, "agentsmd"];
|
|
25214
25633
|
}
|
|
25215
25634
|
return void 0;
|
|
25216
25635
|
};
|
|
@@ -25617,7 +26036,7 @@ function wrapCommand({
|
|
|
25617
26036
|
}
|
|
25618
26037
|
|
|
25619
26038
|
// src/cli/index.ts
|
|
25620
|
-
var getVersion = () => "8.
|
|
26039
|
+
var getVersion = () => "8.3.0";
|
|
25621
26040
|
function wrapCommand2(name, errorCode, handler) {
|
|
25622
26041
|
return wrapCommand({ name, errorCode, handler, getVersion });
|
|
25623
26042
|
}
|