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.
@@ -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: RulesyncTargetsSchema,
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
- this.validateConflictingTargets(targets);
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 = targets;
20061
- this.features = 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
- const hasTarget1 = targets.includes(target1);
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.targets.includes("*")) {
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 this.targets.filter((target) => target !== "*");
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
- const allFeatures = [];
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
- if (Array.isArray(this.features)) {
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 targetFeatures = this.features[target];
20158
- if (!targetFeatures || Array.isArray(targetFeatures)) {
20159
- return void 0;
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: targets ?? configByFile.targets ?? getDefaults().targets,
20292
- features: features ?? configByFile.features ?? getDefaults().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 import_node_path140 = require("path");
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 import_mini73 = require("zod/mini");
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/opencode-permissions.ts
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 OpencodePermissionSchema = import_mini72.z.union([
21027
- import_mini72.z.enum(["allow", "ask", "deny"]),
21028
- import_mini72.z.record(import_mini72.z.string(), import_mini72.z.enum(["allow", "ask", "deny"]))
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 = import_mini72.z.looseObject({
21031
- permission: import_mini72.z.optional(import_mini72.z.record(import_mini72.z.string(), OpencodePermissionSchema))
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, import_node_path139.join)(".config", "opencode"), relativeFilePath: "opencode.json" } : { relativeDirPath: ".", relativeFilePath: "opencode.json" };
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, import_node_path139.join)(baseDir, basePaths.relativeDirPath);
21057
- const jsoncPath = (0, import_node_path139.join)(jsonDir, "opencode.jsonc");
21058
- const jsonPath = (0, import_node_path139.join)(jsonDir, "opencode.json");
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, import_node_path139.join)(baseDir, basePaths.relativeDirPath);
21084
- const jsoncPath = (0, import_node_path139.join)(jsonDir, "opencode.jsonc");
21085
- const jsonPath = (0, import_node_path139.join)(jsonDir, "opencode.json");
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 = import_mini73.z.enum(permissionsProcessorToolTargetTuple);
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: false,
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
- return [toolPermissions];
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, import_node_path140.join)(params.baseDir, RULESYNC_RELATIVE_DIR_PATH));
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 import_node_path141 = require("path");
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, import_node_path141.join)(process.cwd(), ".gitignore");
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 import_node_path142 = require("path");
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, import_node_path142.join)(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
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, import_node_path142.join)(
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, import_node_path142.join)(commandPaths.relativeDirPath, sampleCommandFile.filename);
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, import_node_path142.join)(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
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, import_node_path142.join)(skillPaths.relativeDirPath, sampleSkillFile.dirName);
23172
+ const skillDirPath = (0, import_node_path143.join)(skillPaths.relativeDirPath, sampleSkillFile.dirName);
22758
23173
  await ensureDir(skillDirPath);
22759
- const skillFilepath = (0, import_node_path142.join)(skillDirPath, SKILL_FILE_NAME);
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, import_node_path142.join)(
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, import_node_path142.join)(hooksPaths.relativeDirPath, hooksPaths.relativeFilePath);
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 import_node_path145 = require("path");
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 import_node_path143 = require("path");
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, import_node_path143.isAbsolute)(skillsPath)) {
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, import_node_path143.join)(tmpDir, skillsPath);
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, import_node_path143.join)(dir, name);
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, import_node_path143.relative)(baseDir, fullPath), content, size });
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 import_node_path144 = require("path");
23000
- var import_mini74 = require("zod/mini");
23414
+ var import_node_path145 = require("path");
23415
+ var import_mini75 = require("zod/mini");
23001
23416
  var LOCKFILE_VERSION = 1;
23002
- var LockedSkillSchema = import_mini74.z.object({
23003
- integrity: import_mini74.z.string()
23417
+ var LockedSkillSchema = import_mini75.z.object({
23418
+ integrity: import_mini75.z.string()
23004
23419
  });
23005
- var LockedSourceSchema = import_mini74.z.object({
23006
- requestedRef: (0, import_mini74.optional)(import_mini74.z.string()),
23007
- resolvedRef: import_mini74.z.string().check((0, import_mini74.refine)((v) => /^[0-9a-f]{40}$/.test(v), "resolvedRef must be a 40-character hex SHA")),
23008
- resolvedAt: (0, import_mini74.optional)(import_mini74.z.string()),
23009
- skills: import_mini74.z.record(import_mini74.z.string(), LockedSkillSchema)
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 = import_mini74.z.object({
23012
- lockfileVersion: import_mini74.z.number(),
23013
- sources: import_mini74.z.record(import_mini74.z.string(), LockedSourceSchema)
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 = import_mini74.z.object({
23016
- resolvedRef: import_mini74.z.string(),
23017
- skills: import_mini74.z.array(import_mini74.z.string())
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 = import_mini74.z.object({
23020
- sources: import_mini74.z.record(import_mini74.z.string(), LegacyLockedSourceSchema)
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, import_node_path144.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
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, import_node_path144.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
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, import_node_path145.join)(curatedDir, name))) {
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, import_node_path145.resolve)(curatedDir);
23671
+ const resolvedCuratedDir = (0, import_node_path146.resolve)(curatedDir);
23257
23672
  for (const prevSkill of lockedSkillNames) {
23258
- const prevDir = (0, import_node_path145.join)(curatedDir, prevSkill);
23259
- if (!(0, import_node_path145.resolve)(prevDir).startsWith(resolvedCuratedDir + import_node_path145.sep)) {
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, import_node_path145.join)(curatedDir, skillName)
23713
+ intendedRootDir: (0, import_node_path146.join)(curatedDir, skillName)
23299
23714
  });
23300
- await writeFileContent((0, import_node_path145.join)(curatedDir, skillName, file.relativePath), file.content);
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, import_node_path145.join)(baseDir, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
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, import_node_path145.join)(baseDir, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
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 import_mini83 = require("zod/mini");
24033
+ var import_mini84 = require("zod/mini");
23619
24034
 
23620
24035
  // src/mcp/commands.ts
23621
- var import_node_path146 = require("path");
23622
- var import_mini75 = require("zod/mini");
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, import_node_path146.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
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, import_node_path146.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
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, import_node_path146.basename)(relativePathFromCwd);
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, import_node_path146.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
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, import_node_path146.basename)(relativePathFromCwd);
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, import_node_path146.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
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, import_node_path146.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
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, import_node_path146.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
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, import_node_path146.basename)(relativePathFromCwd);
23883
- const fullPath = (0, import_node_path146.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
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, import_node_path146.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
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: import_mini75.z.object({}),
23897
- getCommand: import_mini75.z.object({
23898
- relativePathFromCwd: import_mini75.z.string()
24311
+ listCommands: import_mini76.z.object({}),
24312
+ getCommand: import_mini76.z.object({
24313
+ relativePathFromCwd: import_mini76.z.string()
23899
24314
  }),
23900
- putCommand: import_mini75.z.object({
23901
- relativePathFromCwd: import_mini75.z.string(),
24315
+ putCommand: import_mini76.z.object({
24316
+ relativePathFromCwd: import_mini76.z.string(),
23902
24317
  frontmatter: RulesyncCommandFrontmatterSchema,
23903
- body: import_mini75.z.string()
24318
+ body: import_mini76.z.string()
23904
24319
  }),
23905
- deleteCommand: import_mini75.z.object({
23906
- relativePathFromCwd: import_mini75.z.string()
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, import_node_path146.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
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 import_mini76 = require("zod/mini");
23955
- var generateOptionsSchema = import_mini76.z.object({
23956
- targets: import_mini76.z.optional(import_mini76.z.array(import_mini76.z.string())),
23957
- features: import_mini76.z.optional(import_mini76.z.array(import_mini76.z.string())),
23958
- delete: import_mini76.z.optional(import_mini76.z.boolean()),
23959
- global: import_mini76.z.optional(import_mini76.z.boolean()),
23960
- simulateCommands: import_mini76.z.optional(import_mini76.z.boolean()),
23961
- simulateSubagents: import_mini76.z.optional(import_mini76.z.boolean()),
23962
- simulateSkills: import_mini76.z.optional(import_mini76.z.boolean())
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 import_node_path147 = require("path");
24042
- var import_mini77 = require("zod/mini");
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, import_node_path147.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
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, import_node_path147.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
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, import_node_path147.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
24087
- const legacyIgnorePath = (0, import_node_path147.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
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: import_mini77.z.object({}),
24106
- putIgnoreFile: import_mini77.z.object({
24107
- content: import_mini77.z.string()
24520
+ getIgnoreFile: import_mini78.z.object({}),
24521
+ putIgnoreFile: import_mini78.z.object({
24522
+ content: import_mini78.z.string()
24108
24523
  }),
24109
- deleteIgnoreFile: import_mini77.z.object({})
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 import_mini78 = require("zod/mini");
24143
- var importOptionsSchema = import_mini78.z.object({
24144
- target: import_mini78.z.string(),
24145
- features: import_mini78.z.optional(import_mini78.z.array(import_mini78.z.string())),
24146
- global: import_mini78.z.optional(import_mini78.z.boolean())
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 import_node_path148 = require("path");
24218
- var import_mini79 = require("zod/mini");
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, import_node_path148.join)(
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, import_node_path148.join)(baseDir, relativeDirPath, relativeFilePath);
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, import_node_path148.join)(baseDir, relativeDirPath));
24686
+ await ensureDir((0, import_node_path149.join)(baseDir, relativeDirPath));
24272
24687
  await writeFileContent(fullPath, content);
24273
- const relativePathFromCwd = (0, import_node_path148.join)(relativeDirPath, relativeFilePath);
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, import_node_path148.join)(
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, import_node_path148.join)(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
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, import_node_path148.join)(
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: import_mini79.z.object({}),
24317
- putMcpFile: import_mini79.z.object({
24318
- content: import_mini79.z.string()
24731
+ getMcpFile: import_mini80.z.object({}),
24732
+ putMcpFile: import_mini80.z.object({
24733
+ content: import_mini80.z.string()
24319
24734
  }),
24320
- deleteMcpFile: import_mini79.z.object({})
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 import_node_path149 = require("path");
24354
- var import_mini80 = require("zod/mini");
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, import_node_path149.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
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, import_node_path149.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
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, import_node_path149.basename)(relativePathFromCwd);
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, import_node_path149.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
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, import_node_path149.basename)(relativePathFromCwd);
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, import_node_path149.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
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, import_node_path149.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
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, import_node_path149.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
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, import_node_path149.basename)(relativePathFromCwd);
24465
- const fullPath = (0, import_node_path149.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
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, import_node_path149.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
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: import_mini80.z.object({}),
24479
- getRule: import_mini80.z.object({
24480
- relativePathFromCwd: import_mini80.z.string()
24893
+ listRules: import_mini81.z.object({}),
24894
+ getRule: import_mini81.z.object({
24895
+ relativePathFromCwd: import_mini81.z.string()
24481
24896
  }),
24482
- putRule: import_mini80.z.object({
24483
- relativePathFromCwd: import_mini80.z.string(),
24897
+ putRule: import_mini81.z.object({
24898
+ relativePathFromCwd: import_mini81.z.string(),
24484
24899
  frontmatter: RulesyncRuleFrontmatterSchema,
24485
- body: import_mini80.z.string()
24900
+ body: import_mini81.z.string()
24486
24901
  }),
24487
- deleteRule: import_mini80.z.object({
24488
- relativePathFromCwd: import_mini80.z.string()
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, import_node_path149.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
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 import_node_path150 = require("path");
24537
- var import_mini81 = require("zod/mini");
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, import_node_path150.basename)(relativeDirPathFromCwd);
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, import_node_path150.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH);
24976
+ const skillsDir = (0, import_node_path151.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH);
24562
24977
  try {
24563
- const skillDirPaths = await findFilesByGlobs((0, import_node_path150.join)(skillsDir, "*"), { type: "dir" });
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, import_node_path150.basename)(dirPath);
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, import_node_path150.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
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, import_node_path150.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
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, import_node_path150.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
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, import_node_path150.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
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, import_node_path150.join)(skillDirPath, SKILL_FILE_NAME);
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, import_node_path150.join)(skillDirPath, file.name);
24664
- const fileDir = (0, import_node_path150.join)(skillDirPath, (0, import_node_path150.dirname)(file.name));
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, import_node_path150.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
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, import_node_path150.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
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, import_node_path150.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
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 = import_mini81.z.object({
24711
- name: import_mini81.z.string(),
24712
- body: import_mini81.z.string()
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: import_mini81.z.object({}),
24716
- getSkill: import_mini81.z.object({
24717
- relativeDirPathFromCwd: import_mini81.z.string()
25130
+ listSkills: import_mini82.z.object({}),
25131
+ getSkill: import_mini82.z.object({
25132
+ relativeDirPathFromCwd: import_mini82.z.string()
24718
25133
  }),
24719
- putSkill: import_mini81.z.object({
24720
- relativeDirPathFromCwd: import_mini81.z.string(),
25134
+ putSkill: import_mini82.z.object({
25135
+ relativeDirPathFromCwd: import_mini82.z.string(),
24721
25136
  frontmatter: RulesyncSkillFrontmatterSchema,
24722
- body: import_mini81.z.string(),
24723
- otherFiles: import_mini81.z.optional(import_mini81.z.array(McpSkillFileSchema))
25137
+ body: import_mini82.z.string(),
25138
+ otherFiles: import_mini82.z.optional(import_mini82.z.array(McpSkillFileSchema))
24724
25139
  }),
24725
- deleteSkill: import_mini81.z.object({
24726
- relativeDirPathFromCwd: import_mini81.z.string()
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, import_node_path150.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "*", SKILL_FILE_NAME)} with their frontmatter.`,
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 import_node_path151 = require("path");
24776
- var import_mini82 = require("zod/mini");
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, import_node_path151.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
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, import_node_path151.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
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, import_node_path151.basename)(relativePathFromCwd);
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, import_node_path151.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
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, import_node_path151.basename)(relativePathFromCwd);
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, import_node_path151.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
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, import_node_path151.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
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, import_node_path151.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
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, import_node_path151.basename)(relativePathFromCwd);
24889
- const fullPath = (0, import_node_path151.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
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, import_node_path151.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
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: import_mini82.z.object({}),
24906
- getSubagent: import_mini82.z.object({
24907
- relativePathFromCwd: import_mini82.z.string()
25320
+ listSubagents: import_mini83.z.object({}),
25321
+ getSubagent: import_mini83.z.object({
25322
+ relativePathFromCwd: import_mini83.z.string()
24908
25323
  }),
24909
- putSubagent: import_mini82.z.object({
24910
- relativePathFromCwd: import_mini82.z.string(),
25324
+ putSubagent: import_mini83.z.object({
25325
+ relativePathFromCwd: import_mini83.z.string(),
24911
25326
  frontmatter: RulesyncSubagentFrontmatterSchema,
24912
- body: import_mini82.z.string()
25327
+ body: import_mini83.z.string()
24913
25328
  }),
24914
- deleteSubagent: import_mini82.z.object({
24915
- relativePathFromCwd: import_mini82.z.string()
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, import_node_path151.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
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 = import_mini83.z.enum([
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 = import_mini83.z.enum(["list", "get", "put", "delete", "run"]);
24974
- var skillFileSchema = import_mini83.z.object({
24975
- name: import_mini83.z.string(),
24976
- body: import_mini83.z.string()
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 = import_mini83.z.object({
25393
+ var rulesyncToolSchema = import_mini84.z.object({
24979
25394
  feature: rulesyncFeatureSchema,
24980
25395
  operation: rulesyncOperationSchema,
24981
- targetPathFromCwd: import_mini83.z.optional(import_mini83.z.string()),
24982
- frontmatter: import_mini83.z.optional(import_mini83.z.unknown()),
24983
- body: import_mini83.z.optional(import_mini83.z.string()),
24984
- otherFiles: import_mini83.z.optional(import_mini83.z.array(skillFileSchema)),
24985
- content: import_mini83.z.optional(import_mini83.z.string()),
24986
- generateOptions: import_mini83.z.optional(generateOptionsSchema),
24987
- importOptions: import_mini83.z.optional(importOptionsSchema)
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 import_node_path152 = require("path");
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, import_node_path152.join)(cwd, RULESYNC_CONFIG_RELATIVE_FILE_PATH);
25203
- const localConfigPath = (0, import_node_path152.join)(cwd, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH);
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
- return config.getTargets();
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.1.0";
26039
+ var getVersion = () => "8.3.0";
25621
26040
  function wrapCommand2(name, errorCode, handler) {
25622
26041
  return wrapCommand({ name, errorCode, handler, getVersion });
25623
26042
  }