rulesync 5.7.0 → 5.9.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.
Files changed (4) hide show
  1. package/README.md +5 -1
  2. package/dist/index.cjs +880 -524
  3. package/dist/index.js +852 -496
  4. package/package.json +11 -11
package/dist/index.js CHANGED
@@ -40,37 +40,52 @@ var isEnvTest = process.env.NODE_ENV === "test";
40
40
  // src/utils/logger.ts
41
41
  var Logger = class {
42
42
  _verbose = false;
43
+ _silent = false;
43
44
  console = consola.withDefaults({
44
45
  tag: "rulesync"
45
46
  });
46
- setVerbose(verbose) {
47
- this._verbose = verbose;
47
+ /**
48
+ * Configure logger with verbose and silent mode settings.
49
+ * Handles conflicting flags where silent takes precedence.
50
+ * @param verbose - Enable verbose logging
51
+ * @param silent - Enable silent mode (suppresses all output except errors)
52
+ */
53
+ configure({ verbose, silent }) {
54
+ if (verbose && silent) {
55
+ this._silent = false;
56
+ this.warn("Both --verbose and --silent specified; --silent takes precedence");
57
+ }
58
+ this._silent = silent;
59
+ this._verbose = verbose && !silent;
48
60
  }
49
61
  get verbose() {
50
62
  return this._verbose;
51
63
  }
64
+ get silent() {
65
+ return this._silent;
66
+ }
52
67
  info(message, ...args) {
53
- if (isEnvTest) return;
68
+ if (isEnvTest || this._silent) return;
54
69
  this.console.info(message, ...args);
55
70
  }
56
- // Success (always shown)
71
+ // Success (always shown unless silent)
57
72
  success(message, ...args) {
58
- if (isEnvTest) return;
73
+ if (isEnvTest || this._silent) return;
59
74
  this.console.success(message, ...args);
60
75
  }
61
- // Warning (always shown)
76
+ // Warning (always shown unless silent)
62
77
  warn(message, ...args) {
63
- if (isEnvTest) return;
78
+ if (isEnvTest || this._silent) return;
64
79
  this.console.warn(message, ...args);
65
80
  }
66
- // Error (always shown)
81
+ // Error (always shown, even in silent mode)
67
82
  error(message, ...args) {
68
83
  if (isEnvTest) return;
69
84
  this.console.error(message, ...args);
70
85
  }
71
86
  // Debug level (shown only in verbose mode)
72
87
  debug(message, ...args) {
73
- if (isEnvTest) return;
88
+ if (isEnvTest || this._silent) return;
74
89
  if (this._verbose) {
75
90
  this.console.info(message, ...args);
76
91
  }
@@ -78,9 +93,6 @@ var Logger = class {
78
93
  };
79
94
  var logger = new Logger();
80
95
 
81
- // src/cli/commands/generate.ts
82
- import { intersection } from "es-toolkit";
83
-
84
96
  // src/config/config-resolver.ts
85
97
  import { parse as parseJsonc } from "jsonc-parser";
86
98
  import { resolve as resolve2 } from "path";
@@ -261,6 +273,7 @@ var ConfigParamsSchema = z3.object({
261
273
  delete: z3.boolean(),
262
274
  // New non-experimental options
263
275
  global: optional(z3.boolean()),
276
+ silent: optional(z3.boolean()),
264
277
  simulateCommands: optional(z3.boolean()),
265
278
  simulateSubagents: optional(z3.boolean()),
266
279
  simulateSkills: optional(z3.boolean()),
@@ -284,6 +297,7 @@ var Config = class {
284
297
  verbose;
285
298
  delete;
286
299
  global;
300
+ silent;
287
301
  simulateCommands;
288
302
  simulateSubagents;
289
303
  simulateSkills;
@@ -295,6 +309,7 @@ var Config = class {
295
309
  verbose,
296
310
  delete: isDelete,
297
311
  global,
312
+ silent,
298
313
  simulateCommands,
299
314
  simulateSubagents,
300
315
  simulateSkills,
@@ -307,6 +322,7 @@ var Config = class {
307
322
  this.verbose = verbose;
308
323
  this.delete = isDelete;
309
324
  this.global = global ?? false;
325
+ this.silent = silent ?? false;
310
326
  this.simulateCommands = simulateCommands ?? false;
311
327
  this.simulateSubagents = simulateSubagents ?? false;
312
328
  this.simulateSkills = simulateSkills ?? false;
@@ -350,6 +366,9 @@ var Config = class {
350
366
  getGlobal() {
351
367
  return this.global;
352
368
  }
369
+ getSilent() {
370
+ return this.silent;
371
+ }
353
372
  getSimulateCommands() {
354
373
  return this.simulateCommands;
355
374
  }
@@ -373,6 +392,7 @@ var getDefaults = () => ({
373
392
  baseDirs: [process.cwd()],
374
393
  configPath: "rulesync.jsonc",
375
394
  global: false,
395
+ silent: false,
376
396
  simulateCommands: false,
377
397
  simulateSubagents: false,
378
398
  simulateSkills: false,
@@ -387,6 +407,7 @@ var ConfigResolver = class {
387
407
  baseDirs,
388
408
  configPath = getDefaults().configPath,
389
409
  global,
410
+ silent,
390
411
  simulateCommands,
391
412
  simulateSubagents,
392
413
  simulateSkills,
@@ -420,6 +441,7 @@ var ConfigResolver = class {
420
441
  global: resolvedGlobal
421
442
  }),
422
443
  global: resolvedGlobal,
444
+ silent: silent ?? configByFile.silent ?? getDefaults().silent,
423
445
  simulateCommands: resolvedSimulateCommands,
424
446
  simulateSubagents: resolvedSimulateSubagents,
425
447
  simulateSkills: resolvedSimulateSkills,
@@ -442,6 +464,10 @@ function getBaseDirsInLightOfGlobal({
442
464
  return resolvedBaseDirs;
443
465
  }
444
466
 
467
+ // src/lib/generate.ts
468
+ import { intersection } from "es-toolkit";
469
+ import { join as join96 } from "path";
470
+
445
471
  // src/constants/rulesync-paths.ts
446
472
  import { join as join2 } from "path";
447
473
  var RULESYNC_CONFIG_RELATIVE_FILE_PATH = "rulesync.jsonc";
@@ -5217,8 +5243,8 @@ var McpProcessor = class extends FeatureProcessor {
5217
5243
 
5218
5244
  // src/features/rules/rules-processor.ts
5219
5245
  import { encode } from "@toon-format/toon";
5220
- import { basename as basename24, join as join94 } from "path";
5221
- import { z as z43 } from "zod/mini";
5246
+ import { basename as basename24, join as join95 } from "path";
5247
+ import { z as z44 } from "zod/mini";
5222
5248
 
5223
5249
  // src/constants/general.ts
5224
5250
  var SKILL_FILE_NAME = "SKILL.md";
@@ -5683,8 +5709,8 @@ var GeminiCliSkill = class _GeminiCliSkill extends SimulatedSkill {
5683
5709
  };
5684
5710
 
5685
5711
  // src/features/skills/skills-processor.ts
5686
- import { basename as basename17, join as join59 } from "path";
5687
- import { z as z29 } from "zod/mini";
5712
+ import { basename as basename17, join as join60 } from "path";
5713
+ import { z as z30 } from "zod/mini";
5688
5714
 
5689
5715
  // src/types/dir-feature-processor.ts
5690
5716
  import { join as join49 } from "path";
@@ -6860,18 +6886,197 @@ var KiloSkill = class _KiloSkill extends ToolSkill {
6860
6886
  }
6861
6887
  };
6862
6888
 
6863
- // src/features/skills/opencode-skill.ts
6889
+ // src/features/skills/kiro-skill.ts
6864
6890
  import { join as join57 } from "path";
6865
6891
  import { z as z27 } from "zod/mini";
6866
- var OpenCodeSkillFrontmatterSchema = z27.looseObject({
6892
+ var KiroSkillFrontmatterSchema = z27.looseObject({
6867
6893
  name: z27.string(),
6868
- description: z27.string(),
6869
- "allowed-tools": z27.optional(z27.array(z27.string()))
6894
+ description: z27.string()
6895
+ });
6896
+ var KiroSkill = class _KiroSkill extends ToolSkill {
6897
+ constructor({
6898
+ baseDir = process.cwd(),
6899
+ relativeDirPath = join57(".kiro", "skills"),
6900
+ dirName,
6901
+ frontmatter,
6902
+ body,
6903
+ otherFiles = [],
6904
+ validate = true,
6905
+ global = false
6906
+ }) {
6907
+ super({
6908
+ baseDir,
6909
+ relativeDirPath,
6910
+ dirName,
6911
+ mainFile: {
6912
+ name: SKILL_FILE_NAME,
6913
+ body,
6914
+ frontmatter: { ...frontmatter }
6915
+ },
6916
+ otherFiles,
6917
+ global
6918
+ });
6919
+ if (validate) {
6920
+ const result = this.validate();
6921
+ if (!result.success) {
6922
+ throw result.error;
6923
+ }
6924
+ }
6925
+ }
6926
+ static getSettablePaths(options) {
6927
+ if (options?.global) {
6928
+ throw new Error("KiroSkill does not support global mode.");
6929
+ }
6930
+ return {
6931
+ relativeDirPath: join57(".kiro", "skills")
6932
+ };
6933
+ }
6934
+ getFrontmatter() {
6935
+ if (!this.mainFile?.frontmatter) {
6936
+ throw new Error("Frontmatter is not defined");
6937
+ }
6938
+ const result = KiroSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
6939
+ return result;
6940
+ }
6941
+ getBody() {
6942
+ return this.mainFile?.body ?? "";
6943
+ }
6944
+ validate() {
6945
+ if (!this.mainFile) {
6946
+ return {
6947
+ success: false,
6948
+ error: new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
6949
+ };
6950
+ }
6951
+ const result = KiroSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
6952
+ if (!result.success) {
6953
+ return {
6954
+ success: false,
6955
+ error: new Error(
6956
+ `Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
6957
+ )
6958
+ };
6959
+ }
6960
+ if (result.data.name !== this.getDirName()) {
6961
+ return {
6962
+ success: false,
6963
+ error: new Error(
6964
+ `${this.getDirPath()}: frontmatter name (${result.data.name}) must match directory name (${this.getDirName()})`
6965
+ )
6966
+ };
6967
+ }
6968
+ return { success: true, error: null };
6969
+ }
6970
+ toRulesyncSkill() {
6971
+ const frontmatter = this.getFrontmatter();
6972
+ const rulesyncFrontmatter = {
6973
+ name: frontmatter.name,
6974
+ description: frontmatter.description,
6975
+ targets: ["*"]
6976
+ };
6977
+ return new RulesyncSkill({
6978
+ baseDir: this.baseDir,
6979
+ relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH,
6980
+ dirName: this.getDirName(),
6981
+ frontmatter: rulesyncFrontmatter,
6982
+ body: this.getBody(),
6983
+ otherFiles: this.getOtherFiles(),
6984
+ validate: true,
6985
+ global: this.global
6986
+ });
6987
+ }
6988
+ static fromRulesyncSkill({
6989
+ rulesyncSkill,
6990
+ validate = true,
6991
+ global = false
6992
+ }) {
6993
+ const settablePaths = _KiroSkill.getSettablePaths({ global });
6994
+ const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
6995
+ const kiroFrontmatter = {
6996
+ name: rulesyncFrontmatter.name,
6997
+ description: rulesyncFrontmatter.description
6998
+ };
6999
+ return new _KiroSkill({
7000
+ baseDir: rulesyncSkill.getBaseDir(),
7001
+ relativeDirPath: settablePaths.relativeDirPath,
7002
+ dirName: rulesyncSkill.getDirName(),
7003
+ frontmatter: kiroFrontmatter,
7004
+ body: rulesyncSkill.getBody(),
7005
+ otherFiles: rulesyncSkill.getOtherFiles(),
7006
+ validate,
7007
+ global
7008
+ });
7009
+ }
7010
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
7011
+ const targets = rulesyncSkill.getFrontmatter().targets;
7012
+ return targets.includes("*") || targets.includes("kiro");
7013
+ }
7014
+ static async fromDir(params) {
7015
+ const loaded = await this.loadSkillDirContent({
7016
+ ...params,
7017
+ getSettablePaths: _KiroSkill.getSettablePaths
7018
+ });
7019
+ const result = KiroSkillFrontmatterSchema.safeParse(loaded.frontmatter);
7020
+ if (!result.success) {
7021
+ const skillDirPath = join57(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
7022
+ throw new Error(
7023
+ `Invalid frontmatter in ${join57(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
7024
+ );
7025
+ }
7026
+ if (result.data.name !== loaded.dirName) {
7027
+ const skillFilePath = join57(
7028
+ loaded.baseDir,
7029
+ loaded.relativeDirPath,
7030
+ loaded.dirName,
7031
+ SKILL_FILE_NAME
7032
+ );
7033
+ throw new Error(
7034
+ `Frontmatter name (${result.data.name}) must match directory name (${loaded.dirName}) in ${skillFilePath}`
7035
+ );
7036
+ }
7037
+ return new _KiroSkill({
7038
+ baseDir: loaded.baseDir,
7039
+ relativeDirPath: loaded.relativeDirPath,
7040
+ dirName: loaded.dirName,
7041
+ frontmatter: result.data,
7042
+ body: loaded.body,
7043
+ otherFiles: loaded.otherFiles,
7044
+ validate: true,
7045
+ global: loaded.global
7046
+ });
7047
+ }
7048
+ static forDeletion({
7049
+ baseDir = process.cwd(),
7050
+ relativeDirPath,
7051
+ dirName,
7052
+ global = false
7053
+ }) {
7054
+ const settablePaths = _KiroSkill.getSettablePaths({ global });
7055
+ return new _KiroSkill({
7056
+ baseDir,
7057
+ relativeDirPath: relativeDirPath ?? settablePaths.relativeDirPath,
7058
+ dirName,
7059
+ frontmatter: { name: "", description: "" },
7060
+ body: "",
7061
+ otherFiles: [],
7062
+ validate: false,
7063
+ global
7064
+ });
7065
+ }
7066
+ };
7067
+
7068
+ // src/features/skills/opencode-skill.ts
7069
+ import { join as join58 } from "path";
7070
+ import { z as z28 } from "zod/mini";
7071
+ var OpenCodeSkillFrontmatterSchema = z28.looseObject({
7072
+ name: z28.string(),
7073
+ description: z28.string(),
7074
+ "allowed-tools": z28.optional(z28.array(z28.string()))
6870
7075
  });
6871
7076
  var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
6872
7077
  constructor({
6873
7078
  baseDir = process.cwd(),
6874
- relativeDirPath = join57(".opencode", "skill"),
7079
+ relativeDirPath = join58(".opencode", "skill"),
6875
7080
  dirName,
6876
7081
  frontmatter,
6877
7082
  body,
@@ -6900,7 +7105,7 @@ var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
6900
7105
  }
6901
7106
  static getSettablePaths({ global = false } = {}) {
6902
7107
  return {
6903
- relativeDirPath: global ? join57(".config", "opencode", "skill") : join57(".opencode", "skill")
7108
+ relativeDirPath: global ? join58(".config", "opencode", "skill") : join58(".opencode", "skill")
6904
7109
  };
6905
7110
  }
6906
7111
  getFrontmatter() {
@@ -6988,9 +7193,9 @@ var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
6988
7193
  });
6989
7194
  const result = OpenCodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
6990
7195
  if (!result.success) {
6991
- const skillDirPath = join57(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
7196
+ const skillDirPath = join58(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
6992
7197
  throw new Error(
6993
- `Invalid frontmatter in ${join57(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
7198
+ `Invalid frontmatter in ${join58(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
6994
7199
  );
6995
7200
  }
6996
7201
  return new _OpenCodeSkill({
@@ -7024,16 +7229,16 @@ var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
7024
7229
  };
7025
7230
 
7026
7231
  // src/features/skills/roo-skill.ts
7027
- import { join as join58 } from "path";
7028
- import { z as z28 } from "zod/mini";
7029
- var RooSkillFrontmatterSchema = z28.looseObject({
7030
- name: z28.string(),
7031
- description: z28.string()
7232
+ import { join as join59 } from "path";
7233
+ import { z as z29 } from "zod/mini";
7234
+ var RooSkillFrontmatterSchema = z29.looseObject({
7235
+ name: z29.string(),
7236
+ description: z29.string()
7032
7237
  });
7033
7238
  var RooSkill = class _RooSkill extends ToolSkill {
7034
7239
  constructor({
7035
7240
  baseDir = process.cwd(),
7036
- relativeDirPath = join58(".roo", "skills"),
7241
+ relativeDirPath = join59(".roo", "skills"),
7037
7242
  dirName,
7038
7243
  frontmatter,
7039
7244
  body,
@@ -7064,7 +7269,7 @@ var RooSkill = class _RooSkill extends ToolSkill {
7064
7269
  global: _global = false
7065
7270
  } = {}) {
7066
7271
  return {
7067
- relativeDirPath: join58(".roo", "skills")
7272
+ relativeDirPath: join59(".roo", "skills")
7068
7273
  };
7069
7274
  }
7070
7275
  getFrontmatter() {
@@ -7154,13 +7359,13 @@ var RooSkill = class _RooSkill extends ToolSkill {
7154
7359
  });
7155
7360
  const result = RooSkillFrontmatterSchema.safeParse(loaded.frontmatter);
7156
7361
  if (!result.success) {
7157
- const skillDirPath = join58(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
7362
+ const skillDirPath = join59(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
7158
7363
  throw new Error(
7159
- `Invalid frontmatter in ${join58(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
7364
+ `Invalid frontmatter in ${join59(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
7160
7365
  );
7161
7366
  }
7162
7367
  if (result.data.name !== loaded.dirName) {
7163
- const skillFilePath = join58(
7368
+ const skillFilePath = join59(
7164
7369
  loaded.baseDir,
7165
7370
  loaded.relativeDirPath,
7166
7371
  loaded.dirName,
@@ -7211,10 +7416,11 @@ var skillsProcessorToolTargetTuple = [
7211
7416
  "cursor",
7212
7417
  "geminicli",
7213
7418
  "kilo",
7419
+ "kiro",
7214
7420
  "opencode",
7215
7421
  "roo"
7216
7422
  ];
7217
- var SkillsProcessorToolTargetSchema = z29.enum(skillsProcessorToolTargetTuple);
7423
+ var SkillsProcessorToolTargetSchema = z30.enum(skillsProcessorToolTargetTuple);
7218
7424
  var toolSkillFactories = /* @__PURE__ */ new Map([
7219
7425
  [
7220
7426
  "agentsmd",
@@ -7279,6 +7485,13 @@ var toolSkillFactories = /* @__PURE__ */ new Map([
7279
7485
  meta: { supportsProject: true, supportsSimulated: false, supportsGlobal: true }
7280
7486
  }
7281
7487
  ],
7488
+ [
7489
+ "kiro",
7490
+ {
7491
+ class: KiroSkill,
7492
+ meta: { supportsProject: true, supportsSimulated: false, supportsGlobal: false }
7493
+ }
7494
+ ],
7282
7495
  [
7283
7496
  "opencode",
7284
7497
  {
@@ -7371,8 +7584,8 @@ var SkillsProcessor = class extends DirFeatureProcessor {
7371
7584
  */
7372
7585
  async loadRulesyncDirs() {
7373
7586
  const paths = RulesyncSkill.getSettablePaths();
7374
- const rulesyncSkillsDirPath = join59(this.baseDir, paths.relativeDirPath);
7375
- const dirPaths = await findFilesByGlobs(join59(rulesyncSkillsDirPath, "*"), { type: "dir" });
7587
+ const rulesyncSkillsDirPath = join60(this.baseDir, paths.relativeDirPath);
7588
+ const dirPaths = await findFilesByGlobs(join60(rulesyncSkillsDirPath, "*"), { type: "dir" });
7376
7589
  const dirNames = dirPaths.map((path3) => basename17(path3));
7377
7590
  const rulesyncSkills = await Promise.all(
7378
7591
  dirNames.map(
@@ -7389,8 +7602,8 @@ var SkillsProcessor = class extends DirFeatureProcessor {
7389
7602
  async loadToolDirs() {
7390
7603
  const factory = this.getFactory(this.toolTarget);
7391
7604
  const paths = factory.class.getSettablePaths({ global: this.global });
7392
- const skillsDirPath = join59(this.baseDir, paths.relativeDirPath);
7393
- const dirPaths = await findFilesByGlobs(join59(skillsDirPath, "*"), { type: "dir" });
7605
+ const skillsDirPath = join60(this.baseDir, paths.relativeDirPath);
7606
+ const dirPaths = await findFilesByGlobs(join60(skillsDirPath, "*"), { type: "dir" });
7394
7607
  const dirNames = dirPaths.map((path3) => basename17(path3));
7395
7608
  const toolSkills = await Promise.all(
7396
7609
  dirNames.map(
@@ -7407,8 +7620,8 @@ var SkillsProcessor = class extends DirFeatureProcessor {
7407
7620
  async loadToolDirsToDelete() {
7408
7621
  const factory = this.getFactory(this.toolTarget);
7409
7622
  const paths = factory.class.getSettablePaths({ global: this.global });
7410
- const skillsDirPath = join59(this.baseDir, paths.relativeDirPath);
7411
- const dirPaths = await findFilesByGlobs(join59(skillsDirPath, "*"), { type: "dir" });
7623
+ const skillsDirPath = join60(this.baseDir, paths.relativeDirPath);
7624
+ const dirPaths = await findFilesByGlobs(join60(skillsDirPath, "*"), { type: "dir" });
7412
7625
  const dirNames = dirPaths.map((path3) => basename17(path3));
7413
7626
  const toolSkills = dirNames.map(
7414
7627
  (dirName) => factory.class.forDeletion({
@@ -7457,11 +7670,11 @@ var SkillsProcessor = class extends DirFeatureProcessor {
7457
7670
  };
7458
7671
 
7459
7672
  // src/features/subagents/agentsmd-subagent.ts
7460
- import { join as join61 } from "path";
7673
+ import { join as join62 } from "path";
7461
7674
 
7462
7675
  // src/features/subagents/simulated-subagent.ts
7463
- import { basename as basename18, join as join60 } from "path";
7464
- import { z as z30 } from "zod/mini";
7676
+ import { basename as basename18, join as join61 } from "path";
7677
+ import { z as z31 } from "zod/mini";
7465
7678
 
7466
7679
  // src/features/subagents/tool-subagent.ts
7467
7680
  var ToolSubagent = class extends ToolFile {
@@ -7504,9 +7717,9 @@ var ToolSubagent = class extends ToolFile {
7504
7717
  };
7505
7718
 
7506
7719
  // src/features/subagents/simulated-subagent.ts
7507
- var SimulatedSubagentFrontmatterSchema = z30.object({
7508
- name: z30.string(),
7509
- description: z30.string()
7720
+ var SimulatedSubagentFrontmatterSchema = z31.object({
7721
+ name: z31.string(),
7722
+ description: z31.string()
7510
7723
  });
7511
7724
  var SimulatedSubagent = class extends ToolSubagent {
7512
7725
  frontmatter;
@@ -7516,7 +7729,7 @@ var SimulatedSubagent = class extends ToolSubagent {
7516
7729
  const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
7517
7730
  if (!result.success) {
7518
7731
  throw new Error(
7519
- `Invalid frontmatter in ${join60(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
7732
+ `Invalid frontmatter in ${join61(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
7520
7733
  );
7521
7734
  }
7522
7735
  }
@@ -7567,7 +7780,7 @@ var SimulatedSubagent = class extends ToolSubagent {
7567
7780
  return {
7568
7781
  success: false,
7569
7782
  error: new Error(
7570
- `Invalid frontmatter in ${join60(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
7783
+ `Invalid frontmatter in ${join61(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
7571
7784
  )
7572
7785
  };
7573
7786
  }
@@ -7577,7 +7790,7 @@ var SimulatedSubagent = class extends ToolSubagent {
7577
7790
  relativeFilePath,
7578
7791
  validate = true
7579
7792
  }) {
7580
- const filePath = join60(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
7793
+ const filePath = join61(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
7581
7794
  const fileContent = await readFileContent(filePath);
7582
7795
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
7583
7796
  const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -7613,7 +7826,7 @@ var SimulatedSubagent = class extends ToolSubagent {
7613
7826
  var AgentsmdSubagent = class _AgentsmdSubagent extends SimulatedSubagent {
7614
7827
  static getSettablePaths() {
7615
7828
  return {
7616
- relativeDirPath: join61(".agents", "subagents")
7829
+ relativeDirPath: join62(".agents", "subagents")
7617
7830
  };
7618
7831
  }
7619
7832
  static async fromFile(params) {
@@ -7636,11 +7849,11 @@ var AgentsmdSubagent = class _AgentsmdSubagent extends SimulatedSubagent {
7636
7849
  };
7637
7850
 
7638
7851
  // src/features/subagents/codexcli-subagent.ts
7639
- import { join as join62 } from "path";
7852
+ import { join as join63 } from "path";
7640
7853
  var CodexCliSubagent = class _CodexCliSubagent extends SimulatedSubagent {
7641
7854
  static getSettablePaths() {
7642
7855
  return {
7643
- relativeDirPath: join62(".codex", "subagents")
7856
+ relativeDirPath: join63(".codex", "subagents")
7644
7857
  };
7645
7858
  }
7646
7859
  static async fromFile(params) {
@@ -7663,11 +7876,11 @@ var CodexCliSubagent = class _CodexCliSubagent extends SimulatedSubagent {
7663
7876
  };
7664
7877
 
7665
7878
  // src/features/subagents/cursor-subagent.ts
7666
- import { join as join63 } from "path";
7879
+ import { join as join64 } from "path";
7667
7880
  var CursorSubagent = class _CursorSubagent extends SimulatedSubagent {
7668
7881
  static getSettablePaths() {
7669
7882
  return {
7670
- relativeDirPath: join63(".cursor", "subagents")
7883
+ relativeDirPath: join64(".cursor", "subagents")
7671
7884
  };
7672
7885
  }
7673
7886
  static async fromFile(params) {
@@ -7690,11 +7903,11 @@ var CursorSubagent = class _CursorSubagent extends SimulatedSubagent {
7690
7903
  };
7691
7904
 
7692
7905
  // src/features/subagents/geminicli-subagent.ts
7693
- import { join as join64 } from "path";
7906
+ import { join as join65 } from "path";
7694
7907
  var GeminiCliSubagent = class _GeminiCliSubagent extends SimulatedSubagent {
7695
7908
  static getSettablePaths() {
7696
7909
  return {
7697
- relativeDirPath: join64(".gemini", "subagents")
7910
+ relativeDirPath: join65(".gemini", "subagents")
7698
7911
  };
7699
7912
  }
7700
7913
  static async fromFile(params) {
@@ -7717,11 +7930,11 @@ var GeminiCliSubagent = class _GeminiCliSubagent extends SimulatedSubagent {
7717
7930
  };
7718
7931
 
7719
7932
  // src/features/subagents/roo-subagent.ts
7720
- import { join as join65 } from "path";
7933
+ import { join as join66 } from "path";
7721
7934
  var RooSubagent = class _RooSubagent extends SimulatedSubagent {
7722
7935
  static getSettablePaths() {
7723
7936
  return {
7724
- relativeDirPath: join65(".roo", "subagents")
7937
+ relativeDirPath: join66(".roo", "subagents")
7725
7938
  };
7726
7939
  }
7727
7940
  static async fromFile(params) {
@@ -7744,20 +7957,20 @@ var RooSubagent = class _RooSubagent extends SimulatedSubagent {
7744
7957
  };
7745
7958
 
7746
7959
  // src/features/subagents/subagents-processor.ts
7747
- import { basename as basename21, join as join71 } from "path";
7748
- import { z as z36 } from "zod/mini";
7960
+ import { basename as basename21, join as join72 } from "path";
7961
+ import { z as z37 } from "zod/mini";
7749
7962
 
7750
7963
  // src/features/subagents/claudecode-subagent.ts
7751
- import { join as join67 } from "path";
7752
- import { z as z32 } from "zod/mini";
7964
+ import { join as join68 } from "path";
7965
+ import { z as z33 } from "zod/mini";
7753
7966
 
7754
7967
  // src/features/subagents/rulesync-subagent.ts
7755
- import { basename as basename19, join as join66 } from "path";
7756
- import { z as z31 } from "zod/mini";
7757
- var RulesyncSubagentFrontmatterSchema = z31.looseObject({
7968
+ import { basename as basename19, join as join67 } from "path";
7969
+ import { z as z32 } from "zod/mini";
7970
+ var RulesyncSubagentFrontmatterSchema = z32.looseObject({
7758
7971
  targets: RulesyncTargetsSchema,
7759
- name: z31.string(),
7760
- description: z31.string()
7972
+ name: z32.string(),
7973
+ description: z32.string()
7761
7974
  });
7762
7975
  var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
7763
7976
  frontmatter;
@@ -7767,7 +7980,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
7767
7980
  const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
7768
7981
  if (!result.success) {
7769
7982
  throw new Error(
7770
- `Invalid frontmatter in ${join66(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
7983
+ `Invalid frontmatter in ${join67(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
7771
7984
  );
7772
7985
  }
7773
7986
  }
@@ -7800,7 +8013,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
7800
8013
  return {
7801
8014
  success: false,
7802
8015
  error: new Error(
7803
- `Invalid frontmatter in ${join66(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
8016
+ `Invalid frontmatter in ${join67(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
7804
8017
  )
7805
8018
  };
7806
8019
  }
@@ -7809,7 +8022,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
7809
8022
  relativeFilePath
7810
8023
  }) {
7811
8024
  const fileContent = await readFileContent(
7812
- join66(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, relativeFilePath)
8025
+ join67(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, relativeFilePath)
7813
8026
  );
7814
8027
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
7815
8028
  const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -7828,13 +8041,13 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
7828
8041
  };
7829
8042
 
7830
8043
  // src/features/subagents/claudecode-subagent.ts
7831
- var ClaudecodeSubagentFrontmatterSchema = z32.looseObject({
7832
- name: z32.string(),
7833
- description: z32.string(),
7834
- model: z32.optional(z32.string()),
7835
- tools: z32.optional(z32.union([z32.string(), z32.array(z32.string())])),
7836
- permissionMode: z32.optional(z32.string()),
7837
- skills: z32.optional(z32.union([z32.string(), z32.array(z32.string())]))
8044
+ var ClaudecodeSubagentFrontmatterSchema = z33.looseObject({
8045
+ name: z33.string(),
8046
+ description: z33.string(),
8047
+ model: z33.optional(z33.string()),
8048
+ tools: z33.optional(z33.union([z33.string(), z33.array(z33.string())])),
8049
+ permissionMode: z33.optional(z33.string()),
8050
+ skills: z33.optional(z33.union([z33.string(), z33.array(z33.string())]))
7838
8051
  });
7839
8052
  var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
7840
8053
  frontmatter;
@@ -7844,7 +8057,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
7844
8057
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
7845
8058
  if (!result.success) {
7846
8059
  throw new Error(
7847
- `Invalid frontmatter in ${join67(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
8060
+ `Invalid frontmatter in ${join68(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
7848
8061
  );
7849
8062
  }
7850
8063
  }
@@ -7856,7 +8069,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
7856
8069
  }
7857
8070
  static getSettablePaths(_options = {}) {
7858
8071
  return {
7859
- relativeDirPath: join67(".claude", "agents")
8072
+ relativeDirPath: join68(".claude", "agents")
7860
8073
  };
7861
8074
  }
7862
8075
  getFrontmatter() {
@@ -7930,7 +8143,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
7930
8143
  return {
7931
8144
  success: false,
7932
8145
  error: new Error(
7933
- `Invalid frontmatter in ${join67(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
8146
+ `Invalid frontmatter in ${join68(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
7934
8147
  )
7935
8148
  };
7936
8149
  }
@@ -7948,7 +8161,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
7948
8161
  global = false
7949
8162
  }) {
7950
8163
  const paths = this.getSettablePaths({ global });
7951
- const filePath = join67(baseDir, paths.relativeDirPath, relativeFilePath);
8164
+ const filePath = join68(baseDir, paths.relativeDirPath, relativeFilePath);
7952
8165
  const fileContent = await readFileContent(filePath);
7953
8166
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
7954
8167
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -7983,13 +8196,13 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
7983
8196
  };
7984
8197
 
7985
8198
  // src/features/subagents/copilot-subagent.ts
7986
- import { join as join68 } from "path";
7987
- import { z as z33 } from "zod/mini";
8199
+ import { join as join69 } from "path";
8200
+ import { z as z34 } from "zod/mini";
7988
8201
  var REQUIRED_TOOL = "agent/runSubagent";
7989
- var CopilotSubagentFrontmatterSchema = z33.looseObject({
7990
- name: z33.string(),
7991
- description: z33.string(),
7992
- tools: z33.optional(z33.union([z33.string(), z33.array(z33.string())]))
8202
+ var CopilotSubagentFrontmatterSchema = z34.looseObject({
8203
+ name: z34.string(),
8204
+ description: z34.string(),
8205
+ tools: z34.optional(z34.union([z34.string(), z34.array(z34.string())]))
7993
8206
  });
7994
8207
  var normalizeTools = (tools) => {
7995
8208
  if (!tools) {
@@ -8009,7 +8222,7 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
8009
8222
  const result = CopilotSubagentFrontmatterSchema.safeParse(frontmatter);
8010
8223
  if (!result.success) {
8011
8224
  throw new Error(
8012
- `Invalid frontmatter in ${join68(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
8225
+ `Invalid frontmatter in ${join69(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
8013
8226
  );
8014
8227
  }
8015
8228
  }
@@ -8021,7 +8234,7 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
8021
8234
  }
8022
8235
  static getSettablePaths(_options = {}) {
8023
8236
  return {
8024
- relativeDirPath: join68(".github", "agents")
8237
+ relativeDirPath: join69(".github", "agents")
8025
8238
  };
8026
8239
  }
8027
8240
  getFrontmatter() {
@@ -8095,7 +8308,7 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
8095
8308
  return {
8096
8309
  success: false,
8097
8310
  error: new Error(
8098
- `Invalid frontmatter in ${join68(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
8311
+ `Invalid frontmatter in ${join69(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
8099
8312
  )
8100
8313
  };
8101
8314
  }
@@ -8113,7 +8326,7 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
8113
8326
  global = false
8114
8327
  }) {
8115
8328
  const paths = this.getSettablePaths({ global });
8116
- const filePath = join68(baseDir, paths.relativeDirPath, relativeFilePath);
8329
+ const filePath = join69(baseDir, paths.relativeDirPath, relativeFilePath);
8117
8330
  const fileContent = await readFileContent(filePath);
8118
8331
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
8119
8332
  const result = CopilotSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -8149,23 +8362,23 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
8149
8362
  };
8150
8363
 
8151
8364
  // src/features/subagents/kiro-subagent.ts
8152
- import { join as join69 } from "path";
8153
- import { z as z34 } from "zod/mini";
8154
- var KiroCliSubagentJsonSchema = z34.looseObject({
8155
- name: z34.string(),
8156
- description: z34.optional(z34.nullable(z34.string())),
8157
- prompt: z34.optional(z34.nullable(z34.string())),
8158
- tools: z34.optional(z34.nullable(z34.array(z34.string()))),
8159
- toolAliases: z34.optional(z34.nullable(z34.record(z34.string(), z34.string()))),
8160
- toolSettings: z34.optional(z34.nullable(z34.unknown())),
8161
- toolSchema: z34.optional(z34.nullable(z34.unknown())),
8162
- hooks: z34.optional(z34.nullable(z34.record(z34.string(), z34.array(z34.unknown())))),
8163
- model: z34.optional(z34.nullable(z34.string())),
8164
- mcpServers: z34.optional(z34.nullable(z34.record(z34.string(), z34.unknown()))),
8165
- useLegacyMcpJson: z34.optional(z34.nullable(z34.boolean())),
8166
- resources: z34.optional(z34.nullable(z34.array(z34.string()))),
8167
- allowedTools: z34.optional(z34.nullable(z34.array(z34.string()))),
8168
- includeMcpJson: z34.optional(z34.nullable(z34.boolean()))
8365
+ import { join as join70 } from "path";
8366
+ import { z as z35 } from "zod/mini";
8367
+ var KiroCliSubagentJsonSchema = z35.looseObject({
8368
+ name: z35.string(),
8369
+ description: z35.optional(z35.nullable(z35.string())),
8370
+ prompt: z35.optional(z35.nullable(z35.string())),
8371
+ tools: z35.optional(z35.nullable(z35.array(z35.string()))),
8372
+ toolAliases: z35.optional(z35.nullable(z35.record(z35.string(), z35.string()))),
8373
+ toolSettings: z35.optional(z35.nullable(z35.unknown())),
8374
+ toolSchema: z35.optional(z35.nullable(z35.unknown())),
8375
+ hooks: z35.optional(z35.nullable(z35.record(z35.string(), z35.array(z35.unknown())))),
8376
+ model: z35.optional(z35.nullable(z35.string())),
8377
+ mcpServers: z35.optional(z35.nullable(z35.record(z35.string(), z35.unknown()))),
8378
+ useLegacyMcpJson: z35.optional(z35.nullable(z35.boolean())),
8379
+ resources: z35.optional(z35.nullable(z35.array(z35.string()))),
8380
+ allowedTools: z35.optional(z35.nullable(z35.array(z35.string()))),
8381
+ includeMcpJson: z35.optional(z35.nullable(z35.boolean()))
8169
8382
  });
8170
8383
  var KiroSubagent = class _KiroSubagent extends ToolSubagent {
8171
8384
  body;
@@ -8177,7 +8390,7 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
8177
8390
  }
8178
8391
  static getSettablePaths(_options = {}) {
8179
8392
  return {
8180
- relativeDirPath: join69(".kiro", "agents")
8393
+ relativeDirPath: join70(".kiro", "agents")
8181
8394
  };
8182
8395
  }
8183
8396
  getBody() {
@@ -8257,7 +8470,7 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
8257
8470
  global = false
8258
8471
  }) {
8259
8472
  const paths = this.getSettablePaths({ global });
8260
- const filePath = join69(baseDir, paths.relativeDirPath, relativeFilePath);
8473
+ const filePath = join70(baseDir, paths.relativeDirPath, relativeFilePath);
8261
8474
  const fileContent = await readFileContent(filePath);
8262
8475
  return new _KiroSubagent({
8263
8476
  baseDir,
@@ -8286,12 +8499,12 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
8286
8499
  };
8287
8500
 
8288
8501
  // src/features/subagents/opencode-subagent.ts
8289
- import { basename as basename20, join as join70 } from "path";
8290
- import { z as z35 } from "zod/mini";
8291
- var OpenCodeSubagentFrontmatterSchema = z35.looseObject({
8292
- description: z35.string(),
8293
- mode: z35.literal("subagent"),
8294
- name: z35.optional(z35.string())
8502
+ import { basename as basename20, join as join71 } from "path";
8503
+ import { z as z36 } from "zod/mini";
8504
+ var OpenCodeSubagentFrontmatterSchema = z36.looseObject({
8505
+ description: z36.string(),
8506
+ mode: z36.literal("subagent"),
8507
+ name: z36.optional(z36.string())
8295
8508
  });
8296
8509
  var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
8297
8510
  frontmatter;
@@ -8301,7 +8514,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
8301
8514
  const result = OpenCodeSubagentFrontmatterSchema.safeParse(frontmatter);
8302
8515
  if (!result.success) {
8303
8516
  throw new Error(
8304
- `Invalid frontmatter in ${join70(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
8517
+ `Invalid frontmatter in ${join71(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
8305
8518
  );
8306
8519
  }
8307
8520
  }
@@ -8315,7 +8528,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
8315
8528
  global = false
8316
8529
  } = {}) {
8317
8530
  return {
8318
- relativeDirPath: global ? join70(".config", "opencode", "agent") : join70(".opencode", "agent")
8531
+ relativeDirPath: global ? join71(".config", "opencode", "agent") : join71(".opencode", "agent")
8319
8532
  };
8320
8533
  }
8321
8534
  getFrontmatter() {
@@ -8381,7 +8594,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
8381
8594
  return {
8382
8595
  success: false,
8383
8596
  error: new Error(
8384
- `Invalid frontmatter in ${join70(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
8597
+ `Invalid frontmatter in ${join71(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
8385
8598
  )
8386
8599
  };
8387
8600
  }
@@ -8398,7 +8611,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
8398
8611
  global = false
8399
8612
  }) {
8400
8613
  const paths = this.getSettablePaths({ global });
8401
- const filePath = join70(baseDir, paths.relativeDirPath, relativeFilePath);
8614
+ const filePath = join71(baseDir, paths.relativeDirPath, relativeFilePath);
8402
8615
  const fileContent = await readFileContent(filePath);
8403
8616
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
8404
8617
  const result = OpenCodeSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -8446,7 +8659,7 @@ var subagentsProcessorToolTargetTuple = [
8446
8659
  "opencode",
8447
8660
  "roo"
8448
8661
  ];
8449
- var SubagentsProcessorToolTargetSchema = z36.enum(subagentsProcessorToolTargetTuple);
8662
+ var SubagentsProcessorToolTargetSchema = z37.enum(subagentsProcessorToolTargetTuple);
8450
8663
  var toolSubagentFactories = /* @__PURE__ */ new Map([
8451
8664
  [
8452
8665
  "agentsmd",
@@ -8600,7 +8813,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
8600
8813
  * Load and parse rulesync subagent files from .rulesync/subagents/ directory
8601
8814
  */
8602
8815
  async loadRulesyncFiles() {
8603
- const subagentsDir = join71(this.baseDir, RulesyncSubagent.getSettablePaths().relativeDirPath);
8816
+ const subagentsDir = join72(this.baseDir, RulesyncSubagent.getSettablePaths().relativeDirPath);
8604
8817
  const dirExists = await directoryExists(subagentsDir);
8605
8818
  if (!dirExists) {
8606
8819
  logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
@@ -8615,7 +8828,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
8615
8828
  logger.info(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
8616
8829
  const rulesyncSubagents = [];
8617
8830
  for (const mdFile of mdFiles) {
8618
- const filepath = join71(subagentsDir, mdFile);
8831
+ const filepath = join72(subagentsDir, mdFile);
8619
8832
  try {
8620
8833
  const rulesyncSubagent = await RulesyncSubagent.fromFile({
8621
8834
  relativeFilePath: mdFile,
@@ -8645,7 +8858,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
8645
8858
  const factory = this.getFactory(this.toolTarget);
8646
8859
  const paths = factory.class.getSettablePaths({ global: this.global });
8647
8860
  const subagentFilePaths = await findFilesByGlobs(
8648
- join71(this.baseDir, paths.relativeDirPath, factory.meta.filePattern)
8861
+ join72(this.baseDir, paths.relativeDirPath, factory.meta.filePattern)
8649
8862
  );
8650
8863
  if (forDeletion) {
8651
8864
  const toolSubagents2 = subagentFilePaths.map(
@@ -8695,48 +8908,49 @@ var SubagentsProcessor = class extends FeatureProcessor {
8695
8908
  };
8696
8909
 
8697
8910
  // src/features/rules/agentsmd-rule.ts
8698
- import { join as join74 } from "path";
8911
+ import { join as join75 } from "path";
8699
8912
 
8700
8913
  // src/features/rules/tool-rule.ts
8701
- import { join as join73 } from "path";
8914
+ import { join as join74 } from "path";
8702
8915
 
8703
8916
  // src/features/rules/rulesync-rule.ts
8704
- import { basename as basename22, join as join72 } from "path";
8705
- import { z as z37 } from "zod/mini";
8706
- var RulesyncRuleFrontmatterSchema = z37.object({
8707
- root: z37.optional(z37.optional(z37.boolean())),
8708
- targets: z37.optional(RulesyncTargetsSchema),
8709
- description: z37.optional(z37.string()),
8710
- globs: z37.optional(z37.array(z37.string())),
8711
- agentsmd: z37.optional(
8712
- z37.object({
8917
+ import { basename as basename22, join as join73 } from "path";
8918
+ import { z as z38 } from "zod/mini";
8919
+ var RulesyncRuleFrontmatterSchema = z38.object({
8920
+ root: z38.optional(z38.boolean()),
8921
+ localRoot: z38.optional(z38.boolean()),
8922
+ targets: z38.optional(RulesyncTargetsSchema),
8923
+ description: z38.optional(z38.string()),
8924
+ globs: z38.optional(z38.array(z38.string())),
8925
+ agentsmd: z38.optional(
8926
+ z38.object({
8713
8927
  // @example "path/to/subproject"
8714
- subprojectPath: z37.optional(z37.string())
8928
+ subprojectPath: z38.optional(z38.string())
8715
8929
  })
8716
8930
  ),
8717
- claudecode: z37.optional(
8718
- z37.object({
8931
+ claudecode: z38.optional(
8932
+ z38.object({
8719
8933
  // Glob patterns for conditional rules (takes precedence over globs)
8720
8934
  // @example "src/**/*.ts, tests/**/*.test.ts"
8721
- paths: z37.optional(z37.string())
8935
+ paths: z38.optional(z38.string())
8722
8936
  })
8723
8937
  ),
8724
- cursor: z37.optional(
8725
- z37.object({
8726
- alwaysApply: z37.optional(z37.boolean()),
8727
- description: z37.optional(z37.string()),
8728
- globs: z37.optional(z37.array(z37.string()))
8938
+ cursor: z38.optional(
8939
+ z38.object({
8940
+ alwaysApply: z38.optional(z38.boolean()),
8941
+ description: z38.optional(z38.string()),
8942
+ globs: z38.optional(z38.array(z38.string()))
8729
8943
  })
8730
8944
  ),
8731
- copilot: z37.optional(
8732
- z37.object({
8733
- excludeAgent: z37.optional(z37.union([z37.literal("code-review"), z37.literal("coding-agent")]))
8945
+ copilot: z38.optional(
8946
+ z38.object({
8947
+ excludeAgent: z38.optional(z38.union([z38.literal("code-review"), z38.literal("coding-agent")]))
8734
8948
  })
8735
8949
  ),
8736
- antigravity: z37.optional(
8737
- z37.looseObject({
8738
- trigger: z37.optional(z37.string()),
8739
- globs: z37.optional(z37.array(z37.string()))
8950
+ antigravity: z38.optional(
8951
+ z38.looseObject({
8952
+ trigger: z38.optional(z38.string()),
8953
+ globs: z38.optional(z38.array(z38.string()))
8740
8954
  })
8741
8955
  )
8742
8956
  });
@@ -8748,7 +8962,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
8748
8962
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
8749
8963
  if (!result.success) {
8750
8964
  throw new Error(
8751
- `Invalid frontmatter in ${join72(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
8965
+ `Invalid frontmatter in ${join73(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
8752
8966
  );
8753
8967
  }
8754
8968
  }
@@ -8783,7 +8997,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
8783
8997
  return {
8784
8998
  success: false,
8785
8999
  error: new Error(
8786
- `Invalid frontmatter in ${join72(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
9000
+ `Invalid frontmatter in ${join73(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
8787
9001
  )
8788
9002
  };
8789
9003
  }
@@ -8792,12 +9006,12 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
8792
9006
  relativeFilePath,
8793
9007
  validate = true
8794
9008
  }) {
8795
- const legacyPath = join72(
9009
+ const legacyPath = join73(
8796
9010
  process.cwd(),
8797
9011
  this.getSettablePaths().legacy.relativeDirPath,
8798
9012
  relativeFilePath
8799
9013
  );
8800
- const recommendedPath = join72(
9014
+ const recommendedPath = join73(
8801
9015
  this.getSettablePaths().recommended.relativeDirPath,
8802
9016
  relativeFilePath
8803
9017
  );
@@ -8812,6 +9026,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
8812
9026
  }
8813
9027
  const validatedFrontmatter = {
8814
9028
  root: result.data.root ?? false,
9029
+ localRoot: result.data.localRoot ?? false,
8815
9030
  targets: result.data.targets ?? ["*"],
8816
9031
  description: result.data.description ?? "",
8817
9032
  globs: result.data.globs ?? [],
@@ -8832,7 +9047,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
8832
9047
  relativeFilePath,
8833
9048
  validate = true
8834
9049
  }) {
8835
- const filePath = join72(
9050
+ const filePath = join73(
8836
9051
  process.cwd(),
8837
9052
  this.getSettablePaths().recommended.relativeDirPath,
8838
9053
  relativeFilePath
@@ -8845,6 +9060,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
8845
9060
  }
8846
9061
  const validatedFrontmatter = {
8847
9062
  root: result.data.root ?? false,
9063
+ localRoot: result.data.localRoot ?? false,
8848
9064
  targets: result.data.targets ?? ["*"],
8849
9065
  description: result.data.description ?? "",
8850
9066
  globs: result.data.globs ?? [],
@@ -8934,7 +9150,7 @@ var ToolRule = class extends ToolFile {
8934
9150
  rulesyncRule,
8935
9151
  validate = true,
8936
9152
  rootPath = { relativeDirPath: ".", relativeFilePath: "AGENTS.md" },
8937
- nonRootPath = { relativeDirPath: join73(".agents", "memories") }
9153
+ nonRootPath = { relativeDirPath: join74(".agents", "memories") }
8938
9154
  }) {
8939
9155
  const params = this.buildToolRuleParamsDefault({
8940
9156
  baseDir,
@@ -8945,7 +9161,7 @@ var ToolRule = class extends ToolFile {
8945
9161
  });
8946
9162
  const rulesyncFrontmatter = rulesyncRule.getFrontmatter();
8947
9163
  if (!rulesyncFrontmatter.root && rulesyncFrontmatter.agentsmd?.subprojectPath) {
8948
- params.relativeDirPath = join73(rulesyncFrontmatter.agentsmd.subprojectPath);
9164
+ params.relativeDirPath = join74(rulesyncFrontmatter.agentsmd.subprojectPath);
8949
9165
  params.relativeFilePath = "AGENTS.md";
8950
9166
  }
8951
9167
  return params;
@@ -9010,7 +9226,7 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
9010
9226
  relativeFilePath: "AGENTS.md"
9011
9227
  },
9012
9228
  nonRoot: {
9013
- relativeDirPath: join74(".agents", "memories")
9229
+ relativeDirPath: join75(".agents", "memories")
9014
9230
  }
9015
9231
  };
9016
9232
  }
@@ -9020,8 +9236,8 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
9020
9236
  validate = true
9021
9237
  }) {
9022
9238
  const isRoot = relativeFilePath === "AGENTS.md";
9023
- const relativePath = isRoot ? "AGENTS.md" : join74(".agents", "memories", relativeFilePath);
9024
- const fileContent = await readFileContent(join74(baseDir, relativePath));
9239
+ const relativePath = isRoot ? "AGENTS.md" : join75(".agents", "memories", relativeFilePath);
9240
+ const fileContent = await readFileContent(join75(baseDir, relativePath));
9025
9241
  return new _AgentsMdRule({
9026
9242
  baseDir,
9027
9243
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -9076,21 +9292,21 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
9076
9292
  };
9077
9293
 
9078
9294
  // src/features/rules/antigravity-rule.ts
9079
- import { join as join75 } from "path";
9080
- import { z as z38 } from "zod/mini";
9081
- var AntigravityRuleFrontmatterSchema = z38.looseObject({
9082
- trigger: z38.optional(
9083
- z38.union([
9084
- z38.literal("always_on"),
9085
- z38.literal("glob"),
9086
- z38.literal("manual"),
9087
- z38.literal("model_decision"),
9088
- z38.string()
9295
+ import { join as join76 } from "path";
9296
+ import { z as z39 } from "zod/mini";
9297
+ var AntigravityRuleFrontmatterSchema = z39.looseObject({
9298
+ trigger: z39.optional(
9299
+ z39.union([
9300
+ z39.literal("always_on"),
9301
+ z39.literal("glob"),
9302
+ z39.literal("manual"),
9303
+ z39.literal("model_decision"),
9304
+ z39.string()
9089
9305
  // accepts any string for forward compatibility
9090
9306
  ])
9091
9307
  ),
9092
- globs: z38.optional(z38.string()),
9093
- description: z38.optional(z38.string())
9308
+ globs: z39.optional(z39.string()),
9309
+ description: z39.optional(z39.string())
9094
9310
  });
9095
9311
  function parseGlobsString(globs) {
9096
9312
  if (!globs) {
@@ -9235,7 +9451,7 @@ var AntigravityRule = class _AntigravityRule extends ToolRule {
9235
9451
  const result = AntigravityRuleFrontmatterSchema.safeParse(frontmatter);
9236
9452
  if (!result.success) {
9237
9453
  throw new Error(
9238
- `Invalid frontmatter in ${join75(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
9454
+ `Invalid frontmatter in ${join76(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
9239
9455
  );
9240
9456
  }
9241
9457
  }
@@ -9250,7 +9466,7 @@ var AntigravityRule = class _AntigravityRule extends ToolRule {
9250
9466
  static getSettablePaths() {
9251
9467
  return {
9252
9468
  nonRoot: {
9253
- relativeDirPath: join75(".agent", "rules")
9469
+ relativeDirPath: join76(".agent", "rules")
9254
9470
  }
9255
9471
  };
9256
9472
  }
@@ -9259,7 +9475,7 @@ var AntigravityRule = class _AntigravityRule extends ToolRule {
9259
9475
  relativeFilePath,
9260
9476
  validate = true
9261
9477
  }) {
9262
- const filePath = join75(
9478
+ const filePath = join76(
9263
9479
  baseDir,
9264
9480
  this.getSettablePaths().nonRoot.relativeDirPath,
9265
9481
  relativeFilePath
@@ -9400,7 +9616,7 @@ var AntigravityRule = class _AntigravityRule extends ToolRule {
9400
9616
  };
9401
9617
 
9402
9618
  // src/features/rules/augmentcode-legacy-rule.ts
9403
- import { join as join76 } from "path";
9619
+ import { join as join77 } from "path";
9404
9620
  var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
9405
9621
  toRulesyncRule() {
9406
9622
  const rulesyncFrontmatter = {
@@ -9426,7 +9642,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
9426
9642
  relativeFilePath: ".augment-guidelines"
9427
9643
  },
9428
9644
  nonRoot: {
9429
- relativeDirPath: join76(".augment", "rules")
9645
+ relativeDirPath: join77(".augment", "rules")
9430
9646
  }
9431
9647
  };
9432
9648
  }
@@ -9461,8 +9677,8 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
9461
9677
  }) {
9462
9678
  const settablePaths = this.getSettablePaths();
9463
9679
  const isRoot = relativeFilePath === settablePaths.root.relativeFilePath;
9464
- const relativePath = isRoot ? settablePaths.root.relativeFilePath : join76(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
9465
- const fileContent = await readFileContent(join76(baseDir, relativePath));
9680
+ const relativePath = isRoot ? settablePaths.root.relativeFilePath : join77(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
9681
+ const fileContent = await readFileContent(join77(baseDir, relativePath));
9466
9682
  return new _AugmentcodeLegacyRule({
9467
9683
  baseDir,
9468
9684
  relativeDirPath: isRoot ? settablePaths.root.relativeDirPath : settablePaths.nonRoot.relativeDirPath,
@@ -9491,7 +9707,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
9491
9707
  };
9492
9708
 
9493
9709
  // src/features/rules/augmentcode-rule.ts
9494
- import { join as join77 } from "path";
9710
+ import { join as join78 } from "path";
9495
9711
  var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
9496
9712
  toRulesyncRule() {
9497
9713
  return this.toRulesyncRuleDefault();
@@ -9499,7 +9715,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
9499
9715
  static getSettablePaths() {
9500
9716
  return {
9501
9717
  nonRoot: {
9502
- relativeDirPath: join77(".augment", "rules")
9718
+ relativeDirPath: join78(".augment", "rules")
9503
9719
  }
9504
9720
  };
9505
9721
  }
@@ -9523,7 +9739,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
9523
9739
  validate = true
9524
9740
  }) {
9525
9741
  const fileContent = await readFileContent(
9526
- join77(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
9742
+ join78(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
9527
9743
  );
9528
9744
  const { body: content } = parseFrontmatter(fileContent);
9529
9745
  return new _AugmentcodeRule({
@@ -9559,7 +9775,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
9559
9775
  };
9560
9776
 
9561
9777
  // src/features/rules/claudecode-legacy-rule.ts
9562
- import { join as join78 } from "path";
9778
+ import { join as join79 } from "path";
9563
9779
  var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
9564
9780
  static getSettablePaths({
9565
9781
  global
@@ -9578,7 +9794,7 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
9578
9794
  relativeFilePath: "CLAUDE.md"
9579
9795
  },
9580
9796
  nonRoot: {
9581
- relativeDirPath: join78(".claude", "memories")
9797
+ relativeDirPath: join79(".claude", "memories")
9582
9798
  }
9583
9799
  };
9584
9800
  }
@@ -9593,7 +9809,7 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
9593
9809
  if (isRoot) {
9594
9810
  const relativePath2 = paths.root.relativeFilePath;
9595
9811
  const fileContent2 = await readFileContent(
9596
- join78(baseDir, paths.root.relativeDirPath, relativePath2)
9812
+ join79(baseDir, paths.root.relativeDirPath, relativePath2)
9597
9813
  );
9598
9814
  return new _ClaudecodeLegacyRule({
9599
9815
  baseDir,
@@ -9607,8 +9823,8 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
9607
9823
  if (!paths.nonRoot) {
9608
9824
  throw new Error("nonRoot path is not set");
9609
9825
  }
9610
- const relativePath = join78(paths.nonRoot.relativeDirPath, relativeFilePath);
9611
- const fileContent = await readFileContent(join78(baseDir, relativePath));
9826
+ const relativePath = join79(paths.nonRoot.relativeDirPath, relativeFilePath);
9827
+ const fileContent = await readFileContent(join79(baseDir, relativePath));
9612
9828
  return new _ClaudecodeLegacyRule({
9613
9829
  baseDir,
9614
9830
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -9667,10 +9883,10 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
9667
9883
  };
9668
9884
 
9669
9885
  // src/features/rules/claudecode-rule.ts
9670
- import { join as join79 } from "path";
9671
- import { z as z39 } from "zod/mini";
9672
- var ClaudecodeRuleFrontmatterSchema = z39.object({
9673
- paths: z39.optional(z39.string())
9886
+ import { join as join80 } from "path";
9887
+ import { z as z40 } from "zod/mini";
9888
+ var ClaudecodeRuleFrontmatterSchema = z40.object({
9889
+ paths: z40.optional(z40.string())
9674
9890
  });
9675
9891
  var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
9676
9892
  frontmatter;
@@ -9692,7 +9908,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
9692
9908
  relativeFilePath: "CLAUDE.md"
9693
9909
  },
9694
9910
  nonRoot: {
9695
- relativeDirPath: join79(".claude", "rules")
9911
+ relativeDirPath: join80(".claude", "rules")
9696
9912
  }
9697
9913
  };
9698
9914
  }
@@ -9701,7 +9917,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
9701
9917
  const result = ClaudecodeRuleFrontmatterSchema.safeParse(frontmatter);
9702
9918
  if (!result.success) {
9703
9919
  throw new Error(
9704
- `Invalid frontmatter in ${join79(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
9920
+ `Invalid frontmatter in ${join80(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
9705
9921
  );
9706
9922
  }
9707
9923
  }
@@ -9729,7 +9945,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
9729
9945
  const isRoot = relativeFilePath === paths.root.relativeFilePath;
9730
9946
  if (isRoot) {
9731
9947
  const fileContent2 = await readFileContent(
9732
- join79(baseDir, paths.root.relativeDirPath, paths.root.relativeFilePath)
9948
+ join80(baseDir, paths.root.relativeDirPath, paths.root.relativeFilePath)
9733
9949
  );
9734
9950
  return new _ClaudecodeRule({
9735
9951
  baseDir,
@@ -9744,13 +9960,13 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
9744
9960
  if (!paths.nonRoot) {
9745
9961
  throw new Error("nonRoot path is not set");
9746
9962
  }
9747
- const relativePath = join79(paths.nonRoot.relativeDirPath, relativeFilePath);
9748
- const fileContent = await readFileContent(join79(baseDir, relativePath));
9963
+ const relativePath = join80(paths.nonRoot.relativeDirPath, relativeFilePath);
9964
+ const fileContent = await readFileContent(join80(baseDir, relativePath));
9749
9965
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
9750
9966
  const result = ClaudecodeRuleFrontmatterSchema.safeParse(frontmatter);
9751
9967
  if (!result.success) {
9752
9968
  throw new Error(
9753
- `Invalid frontmatter in ${join79(baseDir, relativePath)}: ${formatError(result.error)}`
9969
+ `Invalid frontmatter in ${join80(baseDir, relativePath)}: ${formatError(result.error)}`
9754
9970
  );
9755
9971
  }
9756
9972
  return new _ClaudecodeRule({
@@ -9857,7 +10073,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
9857
10073
  return {
9858
10074
  success: false,
9859
10075
  error: new Error(
9860
- `Invalid frontmatter in ${join79(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10076
+ `Invalid frontmatter in ${join80(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
9861
10077
  )
9862
10078
  };
9863
10079
  }
@@ -9877,10 +10093,10 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
9877
10093
  };
9878
10094
 
9879
10095
  // src/features/rules/cline-rule.ts
9880
- import { join as join80 } from "path";
9881
- import { z as z40 } from "zod/mini";
9882
- var ClineRuleFrontmatterSchema = z40.object({
9883
- description: z40.string()
10096
+ import { join as join81 } from "path";
10097
+ import { z as z41 } from "zod/mini";
10098
+ var ClineRuleFrontmatterSchema = z41.object({
10099
+ description: z41.string()
9884
10100
  });
9885
10101
  var ClineRule = class _ClineRule extends ToolRule {
9886
10102
  static getSettablePaths() {
@@ -9922,7 +10138,7 @@ var ClineRule = class _ClineRule extends ToolRule {
9922
10138
  validate = true
9923
10139
  }) {
9924
10140
  const fileContent = await readFileContent(
9925
- join80(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
10141
+ join81(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
9926
10142
  );
9927
10143
  return new _ClineRule({
9928
10144
  baseDir,
@@ -9948,7 +10164,7 @@ var ClineRule = class _ClineRule extends ToolRule {
9948
10164
  };
9949
10165
 
9950
10166
  // src/features/rules/codexcli-rule.ts
9951
- import { join as join81 } from "path";
10167
+ import { join as join82 } from "path";
9952
10168
  var CodexcliRule = class _CodexcliRule extends ToolRule {
9953
10169
  static getSettablePaths({
9954
10170
  global
@@ -9967,7 +10183,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
9967
10183
  relativeFilePath: "AGENTS.md"
9968
10184
  },
9969
10185
  nonRoot: {
9970
- relativeDirPath: join81(".codex", "memories")
10186
+ relativeDirPath: join82(".codex", "memories")
9971
10187
  }
9972
10188
  };
9973
10189
  }
@@ -9982,7 +10198,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
9982
10198
  if (isRoot) {
9983
10199
  const relativePath2 = paths.root.relativeFilePath;
9984
10200
  const fileContent2 = await readFileContent(
9985
- join81(baseDir, paths.root.relativeDirPath, relativePath2)
10201
+ join82(baseDir, paths.root.relativeDirPath, relativePath2)
9986
10202
  );
9987
10203
  return new _CodexcliRule({
9988
10204
  baseDir,
@@ -9996,8 +10212,8 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
9996
10212
  if (!paths.nonRoot) {
9997
10213
  throw new Error("nonRoot path is not set");
9998
10214
  }
9999
- const relativePath = join81(paths.nonRoot.relativeDirPath, relativeFilePath);
10000
- const fileContent = await readFileContent(join81(baseDir, relativePath));
10215
+ const relativePath = join82(paths.nonRoot.relativeDirPath, relativeFilePath);
10216
+ const fileContent = await readFileContent(join82(baseDir, relativePath));
10001
10217
  return new _CodexcliRule({
10002
10218
  baseDir,
10003
10219
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -10056,12 +10272,12 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
10056
10272
  };
10057
10273
 
10058
10274
  // src/features/rules/copilot-rule.ts
10059
- import { join as join82 } from "path";
10060
- import { z as z41 } from "zod/mini";
10061
- var CopilotRuleFrontmatterSchema = z41.object({
10062
- description: z41.optional(z41.string()),
10063
- applyTo: z41.optional(z41.string()),
10064
- excludeAgent: z41.optional(z41.union([z41.literal("code-review"), z41.literal("coding-agent")]))
10275
+ import { join as join83 } from "path";
10276
+ import { z as z42 } from "zod/mini";
10277
+ var CopilotRuleFrontmatterSchema = z42.object({
10278
+ description: z42.optional(z42.string()),
10279
+ applyTo: z42.optional(z42.string()),
10280
+ excludeAgent: z42.optional(z42.union([z42.literal("code-review"), z42.literal("coding-agent")]))
10065
10281
  });
10066
10282
  var CopilotRule = class _CopilotRule extends ToolRule {
10067
10283
  frontmatter;
@@ -10073,7 +10289,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
10073
10289
  relativeFilePath: "copilot-instructions.md"
10074
10290
  },
10075
10291
  nonRoot: {
10076
- relativeDirPath: join82(".github", "instructions")
10292
+ relativeDirPath: join83(".github", "instructions")
10077
10293
  }
10078
10294
  };
10079
10295
  }
@@ -10082,7 +10298,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
10082
10298
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
10083
10299
  if (!result.success) {
10084
10300
  throw new Error(
10085
- `Invalid frontmatter in ${join82(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
10301
+ `Invalid frontmatter in ${join83(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
10086
10302
  );
10087
10303
  }
10088
10304
  }
@@ -10164,11 +10380,11 @@ var CopilotRule = class _CopilotRule extends ToolRule {
10164
10380
  validate = true
10165
10381
  }) {
10166
10382
  const isRoot = relativeFilePath === "copilot-instructions.md";
10167
- const relativePath = isRoot ? join82(
10383
+ const relativePath = isRoot ? join83(
10168
10384
  this.getSettablePaths().root.relativeDirPath,
10169
10385
  this.getSettablePaths().root.relativeFilePath
10170
- ) : join82(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
10171
- const fileContent = await readFileContent(join82(baseDir, relativePath));
10386
+ ) : join83(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
10387
+ const fileContent = await readFileContent(join83(baseDir, relativePath));
10172
10388
  if (isRoot) {
10173
10389
  return new _CopilotRule({
10174
10390
  baseDir,
@@ -10184,7 +10400,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
10184
10400
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
10185
10401
  if (!result.success) {
10186
10402
  throw new Error(
10187
- `Invalid frontmatter in ${join82(baseDir, relativeFilePath)}: ${formatError(result.error)}`
10403
+ `Invalid frontmatter in ${join83(baseDir, relativeFilePath)}: ${formatError(result.error)}`
10188
10404
  );
10189
10405
  }
10190
10406
  return new _CopilotRule({
@@ -10224,7 +10440,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
10224
10440
  return {
10225
10441
  success: false,
10226
10442
  error: new Error(
10227
- `Invalid frontmatter in ${join82(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10443
+ `Invalid frontmatter in ${join83(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10228
10444
  )
10229
10445
  };
10230
10446
  }
@@ -10244,12 +10460,12 @@ var CopilotRule = class _CopilotRule extends ToolRule {
10244
10460
  };
10245
10461
 
10246
10462
  // src/features/rules/cursor-rule.ts
10247
- import { basename as basename23, join as join83 } from "path";
10248
- import { z as z42 } from "zod/mini";
10249
- var CursorRuleFrontmatterSchema = z42.object({
10250
- description: z42.optional(z42.string()),
10251
- globs: z42.optional(z42.string()),
10252
- alwaysApply: z42.optional(z42.boolean())
10463
+ import { basename as basename23, join as join84 } from "path";
10464
+ import { z as z43 } from "zod/mini";
10465
+ var CursorRuleFrontmatterSchema = z43.object({
10466
+ description: z43.optional(z43.string()),
10467
+ globs: z43.optional(z43.string()),
10468
+ alwaysApply: z43.optional(z43.boolean())
10253
10469
  });
10254
10470
  var CursorRule = class _CursorRule extends ToolRule {
10255
10471
  frontmatter;
@@ -10257,7 +10473,7 @@ var CursorRule = class _CursorRule extends ToolRule {
10257
10473
  static getSettablePaths() {
10258
10474
  return {
10259
10475
  nonRoot: {
10260
- relativeDirPath: join83(".cursor", "rules")
10476
+ relativeDirPath: join84(".cursor", "rules")
10261
10477
  }
10262
10478
  };
10263
10479
  }
@@ -10266,7 +10482,7 @@ var CursorRule = class _CursorRule extends ToolRule {
10266
10482
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
10267
10483
  if (!result.success) {
10268
10484
  throw new Error(
10269
- `Invalid frontmatter in ${join83(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
10485
+ `Invalid frontmatter in ${join84(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
10270
10486
  );
10271
10487
  }
10272
10488
  }
@@ -10383,13 +10599,13 @@ var CursorRule = class _CursorRule extends ToolRule {
10383
10599
  validate = true
10384
10600
  }) {
10385
10601
  const fileContent = await readFileContent(
10386
- join83(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
10602
+ join84(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
10387
10603
  );
10388
10604
  const { frontmatter, body: content } = _CursorRule.parseCursorFrontmatter(fileContent);
10389
10605
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
10390
10606
  if (!result.success) {
10391
10607
  throw new Error(
10392
- `Invalid frontmatter in ${join83(baseDir, relativeFilePath)}: ${formatError(result.error)}`
10608
+ `Invalid frontmatter in ${join84(baseDir, relativeFilePath)}: ${formatError(result.error)}`
10393
10609
  );
10394
10610
  }
10395
10611
  return new _CursorRule({
@@ -10426,7 +10642,7 @@ var CursorRule = class _CursorRule extends ToolRule {
10426
10642
  return {
10427
10643
  success: false,
10428
10644
  error: new Error(
10429
- `Invalid frontmatter in ${join83(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10645
+ `Invalid frontmatter in ${join84(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10430
10646
  )
10431
10647
  };
10432
10648
  }
@@ -10446,7 +10662,7 @@ var CursorRule = class _CursorRule extends ToolRule {
10446
10662
  };
10447
10663
 
10448
10664
  // src/features/rules/geminicli-rule.ts
10449
- import { join as join84 } from "path";
10665
+ import { join as join85 } from "path";
10450
10666
  var GeminiCliRule = class _GeminiCliRule extends ToolRule {
10451
10667
  static getSettablePaths({
10452
10668
  global
@@ -10465,7 +10681,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
10465
10681
  relativeFilePath: "GEMINI.md"
10466
10682
  },
10467
10683
  nonRoot: {
10468
- relativeDirPath: join84(".gemini", "memories")
10684
+ relativeDirPath: join85(".gemini", "memories")
10469
10685
  }
10470
10686
  };
10471
10687
  }
@@ -10480,7 +10696,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
10480
10696
  if (isRoot) {
10481
10697
  const relativePath2 = paths.root.relativeFilePath;
10482
10698
  const fileContent2 = await readFileContent(
10483
- join84(baseDir, paths.root.relativeDirPath, relativePath2)
10699
+ join85(baseDir, paths.root.relativeDirPath, relativePath2)
10484
10700
  );
10485
10701
  return new _GeminiCliRule({
10486
10702
  baseDir,
@@ -10494,8 +10710,8 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
10494
10710
  if (!paths.nonRoot) {
10495
10711
  throw new Error("nonRoot path is not set");
10496
10712
  }
10497
- const relativePath = join84(paths.nonRoot.relativeDirPath, relativeFilePath);
10498
- const fileContent = await readFileContent(join84(baseDir, relativePath));
10713
+ const relativePath = join85(paths.nonRoot.relativeDirPath, relativeFilePath);
10714
+ const fileContent = await readFileContent(join85(baseDir, relativePath));
10499
10715
  return new _GeminiCliRule({
10500
10716
  baseDir,
10501
10717
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -10554,7 +10770,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
10554
10770
  };
10555
10771
 
10556
10772
  // src/features/rules/junie-rule.ts
10557
- import { join as join85 } from "path";
10773
+ import { join as join86 } from "path";
10558
10774
  var JunieRule = class _JunieRule extends ToolRule {
10559
10775
  static getSettablePaths() {
10560
10776
  return {
@@ -10563,7 +10779,7 @@ var JunieRule = class _JunieRule extends ToolRule {
10563
10779
  relativeFilePath: "guidelines.md"
10564
10780
  },
10565
10781
  nonRoot: {
10566
- relativeDirPath: join85(".junie", "memories")
10782
+ relativeDirPath: join86(".junie", "memories")
10567
10783
  }
10568
10784
  };
10569
10785
  }
@@ -10573,8 +10789,8 @@ var JunieRule = class _JunieRule extends ToolRule {
10573
10789
  validate = true
10574
10790
  }) {
10575
10791
  const isRoot = relativeFilePath === "guidelines.md";
10576
- const relativePath = isRoot ? "guidelines.md" : join85(".junie", "memories", relativeFilePath);
10577
- const fileContent = await readFileContent(join85(baseDir, relativePath));
10792
+ const relativePath = isRoot ? "guidelines.md" : join86(".junie", "memories", relativeFilePath);
10793
+ const fileContent = await readFileContent(join86(baseDir, relativePath));
10578
10794
  return new _JunieRule({
10579
10795
  baseDir,
10580
10796
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -10629,12 +10845,12 @@ var JunieRule = class _JunieRule extends ToolRule {
10629
10845
  };
10630
10846
 
10631
10847
  // src/features/rules/kilo-rule.ts
10632
- import { join as join86 } from "path";
10848
+ import { join as join87 } from "path";
10633
10849
  var KiloRule = class _KiloRule extends ToolRule {
10634
10850
  static getSettablePaths(_options = {}) {
10635
10851
  return {
10636
10852
  nonRoot: {
10637
- relativeDirPath: join86(".kilocode", "rules")
10853
+ relativeDirPath: join87(".kilocode", "rules")
10638
10854
  }
10639
10855
  };
10640
10856
  }
@@ -10644,7 +10860,7 @@ var KiloRule = class _KiloRule extends ToolRule {
10644
10860
  validate = true
10645
10861
  }) {
10646
10862
  const fileContent = await readFileContent(
10647
- join86(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
10863
+ join87(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
10648
10864
  );
10649
10865
  return new _KiloRule({
10650
10866
  baseDir,
@@ -10696,12 +10912,12 @@ var KiloRule = class _KiloRule extends ToolRule {
10696
10912
  };
10697
10913
 
10698
10914
  // src/features/rules/kiro-rule.ts
10699
- import { join as join87 } from "path";
10915
+ import { join as join88 } from "path";
10700
10916
  var KiroRule = class _KiroRule extends ToolRule {
10701
10917
  static getSettablePaths() {
10702
10918
  return {
10703
10919
  nonRoot: {
10704
- relativeDirPath: join87(".kiro", "steering")
10920
+ relativeDirPath: join88(".kiro", "steering")
10705
10921
  }
10706
10922
  };
10707
10923
  }
@@ -10711,7 +10927,7 @@ var KiroRule = class _KiroRule extends ToolRule {
10711
10927
  validate = true
10712
10928
  }) {
10713
10929
  const fileContent = await readFileContent(
10714
- join87(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
10930
+ join88(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
10715
10931
  );
10716
10932
  return new _KiroRule({
10717
10933
  baseDir,
@@ -10765,7 +10981,7 @@ var KiroRule = class _KiroRule extends ToolRule {
10765
10981
  };
10766
10982
 
10767
10983
  // src/features/rules/opencode-rule.ts
10768
- import { join as join88 } from "path";
10984
+ import { join as join89 } from "path";
10769
10985
  var OpenCodeRule = class _OpenCodeRule extends ToolRule {
10770
10986
  static getSettablePaths() {
10771
10987
  return {
@@ -10774,7 +10990,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
10774
10990
  relativeFilePath: "AGENTS.md"
10775
10991
  },
10776
10992
  nonRoot: {
10777
- relativeDirPath: join88(".opencode", "memories")
10993
+ relativeDirPath: join89(".opencode", "memories")
10778
10994
  }
10779
10995
  };
10780
10996
  }
@@ -10784,8 +11000,8 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
10784
11000
  validate = true
10785
11001
  }) {
10786
11002
  const isRoot = relativeFilePath === "AGENTS.md";
10787
- const relativePath = isRoot ? "AGENTS.md" : join88(".opencode", "memories", relativeFilePath);
10788
- const fileContent = await readFileContent(join88(baseDir, relativePath));
11003
+ const relativePath = isRoot ? "AGENTS.md" : join89(".opencode", "memories", relativeFilePath);
11004
+ const fileContent = await readFileContent(join89(baseDir, relativePath));
10789
11005
  return new _OpenCodeRule({
10790
11006
  baseDir,
10791
11007
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -10840,7 +11056,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
10840
11056
  };
10841
11057
 
10842
11058
  // src/features/rules/qwencode-rule.ts
10843
- import { join as join89 } from "path";
11059
+ import { join as join90 } from "path";
10844
11060
  var QwencodeRule = class _QwencodeRule extends ToolRule {
10845
11061
  static getSettablePaths() {
10846
11062
  return {
@@ -10849,7 +11065,7 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
10849
11065
  relativeFilePath: "QWEN.md"
10850
11066
  },
10851
11067
  nonRoot: {
10852
- relativeDirPath: join89(".qwen", "memories")
11068
+ relativeDirPath: join90(".qwen", "memories")
10853
11069
  }
10854
11070
  };
10855
11071
  }
@@ -10859,8 +11075,8 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
10859
11075
  validate = true
10860
11076
  }) {
10861
11077
  const isRoot = relativeFilePath === "QWEN.md";
10862
- const relativePath = isRoot ? "QWEN.md" : join89(".qwen", "memories", relativeFilePath);
10863
- const fileContent = await readFileContent(join89(baseDir, relativePath));
11078
+ const relativePath = isRoot ? "QWEN.md" : join90(".qwen", "memories", relativeFilePath);
11079
+ const fileContent = await readFileContent(join90(baseDir, relativePath));
10864
11080
  return new _QwencodeRule({
10865
11081
  baseDir,
10866
11082
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -10912,7 +11128,7 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
10912
11128
  };
10913
11129
 
10914
11130
  // src/features/rules/replit-rule.ts
10915
- import { join as join90 } from "path";
11131
+ import { join as join91 } from "path";
10916
11132
  var ReplitRule = class _ReplitRule extends ToolRule {
10917
11133
  static getSettablePaths() {
10918
11134
  return {
@@ -10934,7 +11150,7 @@ var ReplitRule = class _ReplitRule extends ToolRule {
10934
11150
  }
10935
11151
  const relativePath = paths.root.relativeFilePath;
10936
11152
  const fileContent = await readFileContent(
10937
- join90(baseDir, paths.root.relativeDirPath, relativePath)
11153
+ join91(baseDir, paths.root.relativeDirPath, relativePath)
10938
11154
  );
10939
11155
  return new _ReplitRule({
10940
11156
  baseDir,
@@ -11000,12 +11216,12 @@ var ReplitRule = class _ReplitRule extends ToolRule {
11000
11216
  };
11001
11217
 
11002
11218
  // src/features/rules/roo-rule.ts
11003
- import { join as join91 } from "path";
11219
+ import { join as join92 } from "path";
11004
11220
  var RooRule = class _RooRule extends ToolRule {
11005
11221
  static getSettablePaths() {
11006
11222
  return {
11007
11223
  nonRoot: {
11008
- relativeDirPath: join91(".roo", "rules")
11224
+ relativeDirPath: join92(".roo", "rules")
11009
11225
  }
11010
11226
  };
11011
11227
  }
@@ -11015,7 +11231,7 @@ var RooRule = class _RooRule extends ToolRule {
11015
11231
  validate = true
11016
11232
  }) {
11017
11233
  const fileContent = await readFileContent(
11018
- join91(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
11234
+ join92(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
11019
11235
  );
11020
11236
  return new _RooRule({
11021
11237
  baseDir,
@@ -11084,7 +11300,7 @@ var RooRule = class _RooRule extends ToolRule {
11084
11300
  };
11085
11301
 
11086
11302
  // src/features/rules/warp-rule.ts
11087
- import { join as join92 } from "path";
11303
+ import { join as join93 } from "path";
11088
11304
  var WarpRule = class _WarpRule extends ToolRule {
11089
11305
  constructor({ fileContent, root, ...rest }) {
11090
11306
  super({
@@ -11100,7 +11316,7 @@ var WarpRule = class _WarpRule extends ToolRule {
11100
11316
  relativeFilePath: "WARP.md"
11101
11317
  },
11102
11318
  nonRoot: {
11103
- relativeDirPath: join92(".warp", "memories")
11319
+ relativeDirPath: join93(".warp", "memories")
11104
11320
  }
11105
11321
  };
11106
11322
  }
@@ -11110,8 +11326,8 @@ var WarpRule = class _WarpRule extends ToolRule {
11110
11326
  validate = true
11111
11327
  }) {
11112
11328
  const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
11113
- const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join92(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
11114
- const fileContent = await readFileContent(join92(baseDir, relativePath));
11329
+ const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join93(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
11330
+ const fileContent = await readFileContent(join93(baseDir, relativePath));
11115
11331
  return new _WarpRule({
11116
11332
  baseDir,
11117
11333
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : ".warp",
@@ -11166,12 +11382,12 @@ var WarpRule = class _WarpRule extends ToolRule {
11166
11382
  };
11167
11383
 
11168
11384
  // src/features/rules/windsurf-rule.ts
11169
- import { join as join93 } from "path";
11385
+ import { join as join94 } from "path";
11170
11386
  var WindsurfRule = class _WindsurfRule extends ToolRule {
11171
11387
  static getSettablePaths() {
11172
11388
  return {
11173
11389
  nonRoot: {
11174
- relativeDirPath: join93(".windsurf", "rules")
11390
+ relativeDirPath: join94(".windsurf", "rules")
11175
11391
  }
11176
11392
  };
11177
11393
  }
@@ -11181,7 +11397,7 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
11181
11397
  validate = true
11182
11398
  }) {
11183
11399
  const fileContent = await readFileContent(
11184
- join93(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
11400
+ join94(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
11185
11401
  );
11186
11402
  return new _WindsurfRule({
11187
11403
  baseDir,
@@ -11255,7 +11471,7 @@ var rulesProcessorToolTargets = [
11255
11471
  "warp",
11256
11472
  "windsurf"
11257
11473
  ];
11258
- var RulesProcessorToolTargetSchema = z43.enum(rulesProcessorToolTargets);
11474
+ var RulesProcessorToolTargetSchema = z44.enum(rulesProcessorToolTargets);
11259
11475
  var toolRuleFactories = /* @__PURE__ */ new Map([
11260
11476
  [
11261
11477
  "agentsmd",
@@ -11487,9 +11703,11 @@ var RulesProcessor = class extends FeatureProcessor {
11487
11703
  const rulesyncRules = rulesyncFiles.filter(
11488
11704
  (file) => file instanceof RulesyncRule
11489
11705
  );
11706
+ const localRootRules = rulesyncRules.filter((rule) => rule.getFrontmatter().localRoot);
11707
+ const nonLocalRootRules = rulesyncRules.filter((rule) => !rule.getFrontmatter().localRoot);
11490
11708
  const factory = this.getFactory(this.toolTarget);
11491
11709
  const { meta } = factory;
11492
- const toolRules = rulesyncRules.map((rulesyncRule) => {
11710
+ const toolRules = nonLocalRootRules.map((rulesyncRule) => {
11493
11711
  if (!factory.class.isTargetedByRulesyncRule(rulesyncRule)) {
11494
11712
  return null;
11495
11713
  }
@@ -11500,6 +11718,12 @@ var RulesProcessor = class extends FeatureProcessor {
11500
11718
  global: this.global
11501
11719
  });
11502
11720
  }).filter((rule) => rule !== null);
11721
+ if (localRootRules.length > 0 && !this.global) {
11722
+ const localRootRule = localRootRules[0];
11723
+ if (localRootRule && factory.class.isTargetedByRulesyncRule(localRootRule)) {
11724
+ this.handleLocalRootRule(toolRules, localRootRule, factory);
11725
+ }
11726
+ }
11503
11727
  const isSimulated = this.simulateCommands || this.simulateSubagents || this.simulateSkills;
11504
11728
  if (isSimulated && meta.createsSeparateConventionsRule && meta.additionalConventions) {
11505
11729
  const conventionsContent = this.generateAdditionalConventionsSectionFromMeta(meta);
@@ -11546,7 +11770,7 @@ var RulesProcessor = class extends FeatureProcessor {
11546
11770
  }).relativeDirPath;
11547
11771
  return this.skills.filter((skill) => skillClass.isTargetedByRulesyncSkill(skill)).map((skill) => {
11548
11772
  const frontmatter = skill.getFrontmatter();
11549
- const relativePath = join94(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME);
11773
+ const relativePath = join95(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME);
11550
11774
  return {
11551
11775
  name: frontmatter.name,
11552
11776
  description: frontmatter.description,
@@ -11554,6 +11778,50 @@ var RulesProcessor = class extends FeatureProcessor {
11554
11778
  };
11555
11779
  });
11556
11780
  }
11781
+ /**
11782
+ * Handle localRoot rule generation based on tool target.
11783
+ * - Claude Code: generates `.claude/CLAUDE.local.md`
11784
+ * - Claude Code Legacy: generates `./CLAUDE.local.md`
11785
+ * - Other tools: appends content to the root file with one blank line separator
11786
+ */
11787
+ handleLocalRootRule(toolRules, localRootRule, _factory) {
11788
+ const localRootBody = localRootRule.getBody();
11789
+ if (this.toolTarget === "claudecode") {
11790
+ const paths = ClaudecodeRule.getSettablePaths({ global: this.global });
11791
+ toolRules.push(
11792
+ new ClaudecodeRule({
11793
+ baseDir: this.baseDir,
11794
+ relativeDirPath: paths.root.relativeDirPath,
11795
+ relativeFilePath: "CLAUDE.local.md",
11796
+ frontmatter: {},
11797
+ body: localRootBody,
11798
+ validate: true,
11799
+ root: true
11800
+ // Treat as root so it doesn't have frontmatter
11801
+ })
11802
+ );
11803
+ } else if (this.toolTarget === "claudecode-legacy") {
11804
+ const paths = ClaudecodeLegacyRule.getSettablePaths({ global: this.global });
11805
+ toolRules.push(
11806
+ new ClaudecodeLegacyRule({
11807
+ baseDir: this.baseDir,
11808
+ relativeDirPath: paths.root.relativeDirPath,
11809
+ relativeFilePath: "CLAUDE.local.md",
11810
+ fileContent: localRootBody,
11811
+ validate: true,
11812
+ root: true
11813
+ // Treat as root so it doesn't have frontmatter
11814
+ })
11815
+ );
11816
+ } else {
11817
+ const rootRule = toolRules.find((rule) => rule.isRoot());
11818
+ if (rootRule) {
11819
+ const currentContent = rootRule.getFileContent();
11820
+ const newContent = currentContent + "\n\n" + localRootBody;
11821
+ rootRule.setFileContent(newContent);
11822
+ }
11823
+ }
11824
+ }
11557
11825
  /**
11558
11826
  * Generate reference section based on meta configuration.
11559
11827
  */
@@ -11613,7 +11881,7 @@ var RulesProcessor = class extends FeatureProcessor {
11613
11881
  * Load and parse rulesync rule files from .rulesync/rules/ directory
11614
11882
  */
11615
11883
  async loadRulesyncFiles() {
11616
- const files = await findFilesByGlobs(join94(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md"));
11884
+ const files = await findFilesByGlobs(join95(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md"));
11617
11885
  logger.debug(`Found ${files.length} rulesync files`);
11618
11886
  const rulesyncRules = await Promise.all(
11619
11887
  files.map((file) => RulesyncRule.fromFile({ relativeFilePath: basename24(file) }))
@@ -11622,6 +11890,18 @@ var RulesProcessor = class extends FeatureProcessor {
11622
11890
  if (rootRules.length > 1) {
11623
11891
  throw new Error("Multiple root rulesync rules found");
11624
11892
  }
11893
+ if (rootRules.length === 0 && rulesyncRules.length > 0) {
11894
+ logger.warn(
11895
+ `No root rulesync rule file found. Consider adding 'root: true' to one of your rule files in ${RULESYNC_RULES_RELATIVE_DIR_PATH}.`
11896
+ );
11897
+ }
11898
+ const localRootRules = rulesyncRules.filter((rule) => rule.getFrontmatter().localRoot);
11899
+ if (localRootRules.length > 1) {
11900
+ throw new Error("Multiple localRoot rules found. Only one rule can have localRoot: true");
11901
+ }
11902
+ if (localRootRules.length > 0 && rootRules.length === 0) {
11903
+ throw new Error("localRoot: true requires a root: true rule to exist");
11904
+ }
11625
11905
  if (this.global) {
11626
11906
  const nonRootRules = rulesyncRules.filter((rule) => !rule.getFrontmatter().root);
11627
11907
  if (nonRootRules.length > 0) {
@@ -11629,12 +11909,17 @@ var RulesProcessor = class extends FeatureProcessor {
11629
11909
  `${nonRootRules.length} non-root rulesync rules found, but it's in global mode, so ignoring them`
11630
11910
  );
11631
11911
  }
11912
+ if (localRootRules.length > 0) {
11913
+ logger.warn(
11914
+ `${localRootRules.length} localRoot rules found, but localRoot is not supported in global mode, ignoring them`
11915
+ );
11916
+ }
11632
11917
  return rootRules;
11633
11918
  }
11634
11919
  return rulesyncRules;
11635
11920
  }
11636
11921
  async loadRulesyncFilesLegacy() {
11637
- const legacyFiles = await findFilesByGlobs(join94(RULESYNC_RELATIVE_DIR_PATH, "*.md"));
11922
+ const legacyFiles = await findFilesByGlobs(join95(RULESYNC_RELATIVE_DIR_PATH, "*.md"));
11638
11923
  logger.debug(`Found ${legacyFiles.length} legacy rulesync files`);
11639
11924
  return Promise.all(
11640
11925
  legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath: basename24(file) }))
@@ -11655,7 +11940,7 @@ var RulesProcessor = class extends FeatureProcessor {
11655
11940
  return [];
11656
11941
  }
11657
11942
  const rootFilePaths = await findFilesByGlobs(
11658
- join94(
11943
+ join95(
11659
11944
  this.baseDir,
11660
11945
  settablePaths.root.relativeDirPath ?? ".",
11661
11946
  settablePaths.root.relativeFilePath
@@ -11682,12 +11967,35 @@ var RulesProcessor = class extends FeatureProcessor {
11682
11967
  );
11683
11968
  })();
11684
11969
  logger.debug(`Found ${rootToolRules.length} root tool rule files`);
11970
+ const localRootToolRules = await (async () => {
11971
+ if (!forDeletion) {
11972
+ return [];
11973
+ }
11974
+ if (this.toolTarget !== "claudecode" && this.toolTarget !== "claudecode-legacy") {
11975
+ return [];
11976
+ }
11977
+ if (!settablePaths.root) {
11978
+ return [];
11979
+ }
11980
+ const localRootFilePaths = await findFilesByGlobs(
11981
+ join95(this.baseDir, settablePaths.root.relativeDirPath ?? ".", "CLAUDE.local.md")
11982
+ );
11983
+ return localRootFilePaths.map(
11984
+ (filePath) => factory.class.forDeletion({
11985
+ baseDir: this.baseDir,
11986
+ relativeDirPath: settablePaths.root?.relativeDirPath ?? ".",
11987
+ relativeFilePath: basename24(filePath),
11988
+ global: this.global
11989
+ })
11990
+ ).filter((rule) => rule.isDeletable());
11991
+ })();
11992
+ logger.debug(`Found ${localRootToolRules.length} local root tool rule files for deletion`);
11685
11993
  const nonRootToolRules = await (async () => {
11686
11994
  if (!settablePaths.nonRoot) {
11687
11995
  return [];
11688
11996
  }
11689
11997
  const nonRootFilePaths = await findFilesByGlobs(
11690
- join94(this.baseDir, settablePaths.nonRoot.relativeDirPath, `*.${factory.meta.extension}`)
11998
+ join95(this.baseDir, settablePaths.nonRoot.relativeDirPath, `*.${factory.meta.extension}`)
11691
11999
  );
11692
12000
  if (forDeletion) {
11693
12001
  return nonRootFilePaths.map(
@@ -11710,7 +12018,7 @@ var RulesProcessor = class extends FeatureProcessor {
11710
12018
  );
11711
12019
  })();
11712
12020
  logger.debug(`Found ${nonRootToolRules.length} non-root tool rule files`);
11713
- return [...rootToolRules, ...nonRootToolRules];
12021
+ return [...rootToolRules, ...localRootToolRules, ...nonRootToolRules];
11714
12022
  } catch (error) {
11715
12023
  logger.error(`Failed to load tool files: ${formatError(error)}`);
11716
12024
  return [];
@@ -11796,14 +12104,14 @@ s/<command> [arguments]
11796
12104
  This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
11797
12105
  The \`s\` in \`s/\` stands for *simulate*. Because custom slash commands are not built-in, this syntax provides a pseudo way to invoke them.
11798
12106
 
11799
- When users call a custom slash command, you have to look for the markdown file, \`${join94(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
12107
+ When users call a custom slash command, you have to look for the markdown file, \`${join95(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
11800
12108
  const subagentsSection = subagents ? `## Simulated Subagents
11801
12109
 
11802
12110
  Simulated subagents are specialized AI assistants that can be invoked to handle specific types of tasks. In this case, it can be appear something like custom slash commands simply. Simulated subagents can be called by custom slash commands.
11803
12111
 
11804
- When users call a simulated subagent, it will look for the corresponding markdown file, \`${join94(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "{subagent}.md")}\`, and execute its contents as the block of operations.
12112
+ When users call a simulated subagent, it will look for the corresponding markdown file, \`${join95(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "{subagent}.md")}\`, and execute its contents as the block of operations.
11805
12113
 
11806
- For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join94(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
12114
+ For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join95(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
11807
12115
  const skillsSection = skills ? this.generateSkillsSection(skills) : "";
11808
12116
  const result = [
11809
12117
  overview,
@@ -11830,48 +12138,34 @@ ${toonContent}`;
11830
12138
  }
11831
12139
  };
11832
12140
 
11833
- // src/cli/commands/generate.ts
11834
- async function generateCommand(options) {
11835
- const config = await ConfigResolver.resolve(options);
11836
- logger.setVerbose(config.getVerbose());
11837
- logger.info("Generating files...");
11838
- if (!await fileExists(RULESYNC_RELATIVE_DIR_PATH)) {
11839
- logger.error("\u274C .rulesync directory not found. Run 'rulesync init' first.");
11840
- process.exit(1);
11841
- }
11842
- logger.info(`Base directories: ${config.getBaseDirs().join(", ")}`);
11843
- const totalIgnoreOutputs = await generateIgnore(config);
11844
- const totalMcpOutputs = await generateMcp(config);
11845
- const totalCommandOutputs = await generateCommands(config);
11846
- const totalSubagentOutputs = await generateSubagents(config);
11847
- const skillsResult = await generateSkills(config);
11848
- const totalRulesOutputs = await generateRules(config, {
12141
+ // src/lib/generate.ts
12142
+ async function checkRulesyncDirExists(params) {
12143
+ return fileExists(join96(params.baseDir, RULESYNC_RELATIVE_DIR_PATH));
12144
+ }
12145
+ async function generate(params) {
12146
+ const { config } = params;
12147
+ const ignoreCount = await generateIgnoreCore({ config });
12148
+ const mcpCount = await generateMcpCore({ config });
12149
+ const commandsCount = await generateCommandsCore({ config });
12150
+ const subagentsCount = await generateSubagentsCore({ config });
12151
+ const skillsResult = await generateSkillsCore({ config });
12152
+ const rulesCount = await generateRulesCore({ config, skills: skillsResult.skills });
12153
+ return {
12154
+ rulesCount,
12155
+ ignoreCount,
12156
+ mcpCount,
12157
+ commandsCount,
12158
+ subagentsCount,
12159
+ skillsCount: skillsResult.count,
11849
12160
  skills: skillsResult.skills
11850
- });
11851
- const totalGenerated = totalRulesOutputs + totalMcpOutputs + totalCommandOutputs + totalIgnoreOutputs + totalSubagentOutputs + skillsResult.totalOutputs;
11852
- if (totalGenerated === 0) {
11853
- const enabledFeatures = config.getFeatures().join(", ");
11854
- logger.warn(`\u26A0\uFE0F No files generated for enabled features: ${enabledFeatures}`);
11855
- return;
11856
- }
11857
- if (totalGenerated > 0) {
11858
- const parts = [];
11859
- if (totalRulesOutputs > 0) parts.push(`${totalRulesOutputs} rules`);
11860
- if (totalIgnoreOutputs > 0) parts.push(`${totalIgnoreOutputs} ignore files`);
11861
- if (totalMcpOutputs > 0) parts.push(`${totalMcpOutputs} MCP files`);
11862
- if (totalCommandOutputs > 0) parts.push(`${totalCommandOutputs} commands`);
11863
- if (totalSubagentOutputs > 0) parts.push(`${totalSubagentOutputs} subagents`);
11864
- if (skillsResult.totalOutputs > 0) parts.push(`${skillsResult.totalOutputs} skills`);
11865
- logger.success(`\u{1F389} All done! Generated ${totalGenerated} file(s) total (${parts.join(" + ")})`);
11866
- }
12161
+ };
11867
12162
  }
11868
- async function generateRules(config, options) {
12163
+ async function generateRulesCore(params) {
12164
+ const { config, skills } = params;
11869
12165
  if (!config.getFeatures().includes("rules")) {
11870
- logger.debug("Skipping rule generation (not in --features)");
11871
12166
  return 0;
11872
12167
  }
11873
- let totalRulesOutputs = 0;
11874
- logger.info("Generating rule files...");
12168
+ let totalCount = 0;
11875
12169
  const toolTargets = intersection(
11876
12170
  config.getTargets(),
11877
12171
  RulesProcessor.getToolTargets({ global: config.getGlobal() })
@@ -11885,7 +12179,7 @@ async function generateRules(config, options) {
11885
12179
  simulateCommands: config.getSimulateCommands(),
11886
12180
  simulateSubagents: config.getSimulateSubagents(),
11887
12181
  simulateSkills: config.getSimulateSkills(),
11888
- skills: options?.skills
12182
+ skills
11889
12183
  });
11890
12184
  if (config.getDelete()) {
11891
12185
  const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
@@ -11894,23 +12188,20 @@ async function generateRules(config, options) {
11894
12188
  const rulesyncFiles = await processor.loadRulesyncFiles();
11895
12189
  const toolFiles = await processor.convertRulesyncFilesToToolFiles(rulesyncFiles);
11896
12190
  const writtenCount = await processor.writeAiFiles(toolFiles);
11897
- totalRulesOutputs += writtenCount;
11898
- logger.success(`Generated ${writtenCount} ${toolTarget} rule(s) in ${baseDir}`);
12191
+ totalCount += writtenCount;
11899
12192
  }
11900
12193
  }
11901
- return totalRulesOutputs;
12194
+ return totalCount;
11902
12195
  }
11903
- async function generateIgnore(config) {
12196
+ async function generateIgnoreCore(params) {
12197
+ const { config } = params;
11904
12198
  if (!config.getFeatures().includes("ignore")) {
11905
- logger.debug("Skipping ignore file generation (not in --features)");
11906
12199
  return 0;
11907
12200
  }
11908
12201
  if (config.getGlobal()) {
11909
- logger.debug("Skipping ignore file generation (not supported in global mode)");
11910
12202
  return 0;
11911
12203
  }
11912
- let totalIgnoreOutputs = 0;
11913
- logger.info("Generating ignore files...");
12204
+ let totalCount = 0;
11914
12205
  for (const toolTarget of intersection(config.getTargets(), IgnoreProcessor.getToolTargets())) {
11915
12206
  for (const baseDir of config.getBaseDirs()) {
11916
12207
  try {
@@ -11926,30 +12217,24 @@ async function generateIgnore(config) {
11926
12217
  if (rulesyncFiles.length > 0) {
11927
12218
  const toolFiles = await processor.convertRulesyncFilesToToolFiles(rulesyncFiles);
11928
12219
  const writtenCount = await processor.writeAiFiles(toolFiles);
11929
- totalIgnoreOutputs += writtenCount;
11930
- logger.success(`Generated ${writtenCount} ${toolTarget} ignore file(s) in ${baseDir}`);
12220
+ totalCount += writtenCount;
11931
12221
  }
11932
12222
  } catch (error) {
11933
12223
  logger.warn(
11934
- `Failed to generate ${toolTarget} ignore files for ${baseDir}:`,
11935
- error instanceof Error ? error.message : String(error)
12224
+ `Failed to generate ${toolTarget} ignore files for ${baseDir}: ${formatError(error)}`
11936
12225
  );
11937
12226
  continue;
11938
12227
  }
11939
12228
  }
11940
12229
  }
11941
- return totalIgnoreOutputs;
12230
+ return totalCount;
11942
12231
  }
11943
- async function generateMcp(config) {
12232
+ async function generateMcpCore(params) {
12233
+ const { config } = params;
11944
12234
  if (!config.getFeatures().includes("mcp")) {
11945
- logger.debug("Skipping MCP configuration generation (not in --features)");
11946
12235
  return 0;
11947
12236
  }
11948
- let totalMcpOutputs = 0;
11949
- logger.info("Generating MCP files...");
11950
- if (config.getModularMcp()) {
11951
- logger.info("\u2139\uFE0F Modular MCP support is experimental.");
11952
- }
12237
+ let totalCount = 0;
11953
12238
  const toolTargets = intersection(
11954
12239
  config.getTargets(),
11955
12240
  McpProcessor.getToolTargets({ global: config.getGlobal() })
@@ -11969,19 +12254,17 @@ async function generateMcp(config) {
11969
12254
  const rulesyncFiles = await processor.loadRulesyncFiles();
11970
12255
  const toolFiles = await processor.convertRulesyncFilesToToolFiles(rulesyncFiles);
11971
12256
  const writtenCount = await processor.writeAiFiles(toolFiles);
11972
- totalMcpOutputs += writtenCount;
11973
- logger.success(`Generated ${writtenCount} ${toolTarget} MCP configuration(s) in ${baseDir}`);
12257
+ totalCount += writtenCount;
11974
12258
  }
11975
12259
  }
11976
- return totalMcpOutputs;
12260
+ return totalCount;
11977
12261
  }
11978
- async function generateCommands(config) {
12262
+ async function generateCommandsCore(params) {
12263
+ const { config } = params;
11979
12264
  if (!config.getFeatures().includes("commands")) {
11980
- logger.debug("Skipping command file generation (not in --features)");
11981
12265
  return 0;
11982
12266
  }
11983
- let totalCommandOutputs = 0;
11984
- logger.info("Generating command files...");
12267
+ let totalCount = 0;
11985
12268
  const toolTargets = intersection(
11986
12269
  config.getTargets(),
11987
12270
  CommandsProcessor.getToolTargets({
@@ -12003,19 +12286,17 @@ async function generateCommands(config) {
12003
12286
  const rulesyncFiles = await processor.loadRulesyncFiles();
12004
12287
  const toolFiles = await processor.convertRulesyncFilesToToolFiles(rulesyncFiles);
12005
12288
  const writtenCount = await processor.writeAiFiles(toolFiles);
12006
- totalCommandOutputs += writtenCount;
12007
- logger.success(`Generated ${writtenCount} ${toolTarget} command(s) in ${baseDir}`);
12289
+ totalCount += writtenCount;
12008
12290
  }
12009
12291
  }
12010
- return totalCommandOutputs;
12292
+ return totalCount;
12011
12293
  }
12012
- async function generateSubagents(config) {
12294
+ async function generateSubagentsCore(params) {
12295
+ const { config } = params;
12013
12296
  if (!config.getFeatures().includes("subagents")) {
12014
- logger.debug("Skipping subagent file generation (not in --features)");
12015
12297
  return 0;
12016
12298
  }
12017
- let totalSubagentOutputs = 0;
12018
- logger.info("Generating subagent files...");
12299
+ let totalCount = 0;
12019
12300
  const toolTargets = intersection(
12020
12301
  config.getTargets(),
12021
12302
  SubagentsProcessor.getToolTargets({
@@ -12037,20 +12318,18 @@ async function generateSubagents(config) {
12037
12318
  const rulesyncFiles = await processor.loadRulesyncFiles();
12038
12319
  const toolFiles = await processor.convertRulesyncFilesToToolFiles(rulesyncFiles);
12039
12320
  const writtenCount = await processor.writeAiFiles(toolFiles);
12040
- totalSubagentOutputs += writtenCount;
12041
- logger.success(`Generated ${writtenCount} ${toolTarget} subagent(s) in ${baseDir}`);
12321
+ totalCount += writtenCount;
12042
12322
  }
12043
12323
  }
12044
- return totalSubagentOutputs;
12324
+ return totalCount;
12045
12325
  }
12046
- async function generateSkills(config) {
12326
+ async function generateSkillsCore(params) {
12327
+ const { config } = params;
12047
12328
  if (!config.getFeatures().includes("skills")) {
12048
- logger.debug("Skipping skill generation (not in --features)");
12049
- return { totalOutputs: 0, skills: [] };
12329
+ return { count: 0, skills: [] };
12050
12330
  }
12051
- let totalSkillOutputs = 0;
12331
+ let totalCount = 0;
12052
12332
  const allSkills = [];
12053
- logger.info("Generating skill files...");
12054
12333
  const toolTargets = intersection(
12055
12334
  config.getTargets(),
12056
12335
  SkillsProcessor.getToolTargets({
@@ -12077,15 +12356,84 @@ async function generateSkills(config) {
12077
12356
  }
12078
12357
  const toolDirs = await processor.convertRulesyncDirsToToolDirs(rulesyncDirs);
12079
12358
  const writtenCount = await processor.writeAiDirs(toolDirs);
12080
- totalSkillOutputs += writtenCount;
12081
- logger.success(`Generated ${writtenCount} ${toolTarget} skill(s) in ${baseDir}`);
12359
+ totalCount += writtenCount;
12360
+ }
12361
+ }
12362
+ return { count: totalCount, skills: allSkills };
12363
+ }
12364
+
12365
+ // src/cli/commands/generate.ts
12366
+ async function generateCommand(options) {
12367
+ const config = await ConfigResolver.resolve(options);
12368
+ logger.configure({
12369
+ verbose: config.getVerbose(),
12370
+ silent: config.getSilent()
12371
+ });
12372
+ logger.info("Generating files...");
12373
+ if (!await checkRulesyncDirExists({ baseDir: config.getBaseDirs()[0] ?? process.cwd() })) {
12374
+ logger.error("\u274C .rulesync directory not found. Run 'rulesync init' first.");
12375
+ process.exit(1);
12376
+ }
12377
+ logger.info(`Base directories: ${config.getBaseDirs().join(", ")}`);
12378
+ const features = config.getFeatures();
12379
+ if (features.includes("ignore")) {
12380
+ logger.info("Generating ignore files...");
12381
+ }
12382
+ if (features.includes("mcp")) {
12383
+ logger.info("Generating MCP files...");
12384
+ if (config.getModularMcp()) {
12385
+ logger.info("\u2139\uFE0F Modular MCP support is experimental.");
12082
12386
  }
12083
12387
  }
12084
- return { totalOutputs: totalSkillOutputs, skills: allSkills };
12388
+ if (features.includes("commands")) {
12389
+ logger.info("Generating command files...");
12390
+ }
12391
+ if (features.includes("subagents")) {
12392
+ logger.info("Generating subagent files...");
12393
+ }
12394
+ if (features.includes("skills")) {
12395
+ logger.info("Generating skill files...");
12396
+ }
12397
+ if (features.includes("rules")) {
12398
+ logger.info("Generating rule files...");
12399
+ }
12400
+ const result = await generate({ config });
12401
+ if (result.ignoreCount > 0) {
12402
+ logger.success(`Generated ${result.ignoreCount} ignore file(s)`);
12403
+ }
12404
+ if (result.mcpCount > 0) {
12405
+ logger.success(`Generated ${result.mcpCount} MCP configuration(s)`);
12406
+ }
12407
+ if (result.commandsCount > 0) {
12408
+ logger.success(`Generated ${result.commandsCount} command(s)`);
12409
+ }
12410
+ if (result.subagentsCount > 0) {
12411
+ logger.success(`Generated ${result.subagentsCount} subagent(s)`);
12412
+ }
12413
+ if (result.skillsCount > 0) {
12414
+ logger.success(`Generated ${result.skillsCount} skill(s)`);
12415
+ }
12416
+ if (result.rulesCount > 0) {
12417
+ logger.success(`Generated ${result.rulesCount} rule(s)`);
12418
+ }
12419
+ const totalGenerated = result.rulesCount + result.ignoreCount + result.mcpCount + result.commandsCount + result.subagentsCount + result.skillsCount;
12420
+ if (totalGenerated === 0) {
12421
+ const enabledFeatures = features.join(", ");
12422
+ logger.warn(`\u26A0\uFE0F No files generated for enabled features: ${enabledFeatures}`);
12423
+ return;
12424
+ }
12425
+ const parts = [];
12426
+ if (result.rulesCount > 0) parts.push(`${result.rulesCount} rules`);
12427
+ if (result.ignoreCount > 0) parts.push(`${result.ignoreCount} ignore files`);
12428
+ if (result.mcpCount > 0) parts.push(`${result.mcpCount} MCP files`);
12429
+ if (result.commandsCount > 0) parts.push(`${result.commandsCount} commands`);
12430
+ if (result.subagentsCount > 0) parts.push(`${result.subagentsCount} subagents`);
12431
+ if (result.skillsCount > 0) parts.push(`${result.skillsCount} skills`);
12432
+ logger.success(`\u{1F389} All done! Generated ${totalGenerated} file(s) total (${parts.join(" + ")})`);
12085
12433
  }
12086
12434
 
12087
12435
  // src/cli/commands/gitignore.ts
12088
- import { join as join95 } from "path";
12436
+ import { join as join97 } from "path";
12089
12437
  var RULESYNC_HEADER = "# Generated by Rulesync";
12090
12438
  var LEGACY_RULESYNC_HEADER = "# Generated by rulesync - AI tool configuration files";
12091
12439
  var RULESYNC_IGNORE_ENTRIES = [
@@ -12102,7 +12450,9 @@ var RULESYNC_IGNORE_ENTRIES = [
12102
12450
  "**/.augment-guidelines",
12103
12451
  // Claude Code
12104
12452
  "**/CLAUDE.md",
12453
+ "**/CLAUDE.local.md",
12105
12454
  "**/.claude/CLAUDE.md",
12455
+ "**/.claude/CLAUDE.local.md",
12106
12456
  "**/.claude/memories/",
12107
12457
  "**/.claude/rules/",
12108
12458
  "**/.claude/commands/",
@@ -12149,6 +12499,7 @@ var RULESYNC_IGNORE_ENTRIES = [
12149
12499
  // Kiro
12150
12500
  "**/.kiro/steering/",
12151
12501
  "**/.kiro/prompts/",
12502
+ "**/.kiro/skills/",
12152
12503
  "**/.kiro/agents/",
12153
12504
  "**/.kiro/settings/mcp.json",
12154
12505
  "**/.aiignore",
@@ -12225,7 +12576,7 @@ var removeExistingRulesyncEntries = (content) => {
12225
12576
  return result;
12226
12577
  };
12227
12578
  var gitignoreCommand = async () => {
12228
- const gitignorePath = join95(process.cwd(), ".gitignore");
12579
+ const gitignorePath = join97(process.cwd(), ".gitignore");
12229
12580
  let gitignoreContent = "";
12230
12581
  if (await fileExists(gitignorePath)) {
12231
12582
  gitignoreContent = await readFileContent(gitignorePath);
@@ -12259,7 +12610,10 @@ async function importCommand(options) {
12259
12610
  process.exit(1);
12260
12611
  }
12261
12612
  const config = await ConfigResolver.resolve(options);
12262
- logger.setVerbose(config.getVerbose());
12613
+ logger.configure({
12614
+ verbose: config.getVerbose(),
12615
+ silent: config.getSilent()
12616
+ });
12263
12617
  const tool = config.getTargets()[0];
12264
12618
  await importRules(config, tool);
12265
12619
  await importIgnore(config, tool);
@@ -12424,7 +12778,7 @@ async function importSkills(config, tool) {
12424
12778
  }
12425
12779
 
12426
12780
  // src/cli/commands/init.ts
12427
- import { join as join96 } from "path";
12781
+ import { join as join98 } from "path";
12428
12782
  async function initCommand() {
12429
12783
  logger.info("Initializing rulesync...");
12430
12784
  await ensureDir(RULESYNC_RELATIVE_DIR_PATH);
@@ -12602,14 +12956,14 @@ Keep the summary concise and ready to reuse in future tasks.`
12602
12956
  await ensureDir(subagentPaths.relativeDirPath);
12603
12957
  await ensureDir(skillPaths.relativeDirPath);
12604
12958
  await ensureDir(ignorePaths.recommended.relativeDirPath);
12605
- const ruleFilepath = join96(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
12959
+ const ruleFilepath = join98(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
12606
12960
  if (!await fileExists(ruleFilepath)) {
12607
12961
  await writeFileContent(ruleFilepath, sampleRuleFile.content);
12608
12962
  logger.success(`Created ${ruleFilepath}`);
12609
12963
  } else {
12610
12964
  logger.info(`Skipped ${ruleFilepath} (already exists)`);
12611
12965
  }
12612
- const mcpFilepath = join96(
12966
+ const mcpFilepath = join98(
12613
12967
  mcpPaths.recommended.relativeDirPath,
12614
12968
  mcpPaths.recommended.relativeFilePath
12615
12969
  );
@@ -12619,30 +12973,30 @@ Keep the summary concise and ready to reuse in future tasks.`
12619
12973
  } else {
12620
12974
  logger.info(`Skipped ${mcpFilepath} (already exists)`);
12621
12975
  }
12622
- const commandFilepath = join96(commandPaths.relativeDirPath, sampleCommandFile.filename);
12976
+ const commandFilepath = join98(commandPaths.relativeDirPath, sampleCommandFile.filename);
12623
12977
  if (!await fileExists(commandFilepath)) {
12624
12978
  await writeFileContent(commandFilepath, sampleCommandFile.content);
12625
12979
  logger.success(`Created ${commandFilepath}`);
12626
12980
  } else {
12627
12981
  logger.info(`Skipped ${commandFilepath} (already exists)`);
12628
12982
  }
12629
- const subagentFilepath = join96(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
12983
+ const subagentFilepath = join98(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
12630
12984
  if (!await fileExists(subagentFilepath)) {
12631
12985
  await writeFileContent(subagentFilepath, sampleSubagentFile.content);
12632
12986
  logger.success(`Created ${subagentFilepath}`);
12633
12987
  } else {
12634
12988
  logger.info(`Skipped ${subagentFilepath} (already exists)`);
12635
12989
  }
12636
- const skillDirPath = join96(skillPaths.relativeDirPath, sampleSkillFile.dirName);
12990
+ const skillDirPath = join98(skillPaths.relativeDirPath, sampleSkillFile.dirName);
12637
12991
  await ensureDir(skillDirPath);
12638
- const skillFilepath = join96(skillDirPath, SKILL_FILE_NAME);
12992
+ const skillFilepath = join98(skillDirPath, SKILL_FILE_NAME);
12639
12993
  if (!await fileExists(skillFilepath)) {
12640
12994
  await writeFileContent(skillFilepath, sampleSkillFile.content);
12641
12995
  logger.success(`Created ${skillFilepath}`);
12642
12996
  } else {
12643
12997
  logger.info(`Skipped ${skillFilepath} (already exists)`);
12644
12998
  }
12645
- const ignoreFilepath = join96(
12999
+ const ignoreFilepath = join98(
12646
13000
  ignorePaths.recommended.relativeDirPath,
12647
13001
  ignorePaths.recommended.relativeFilePath
12648
13002
  );
@@ -12658,15 +13012,15 @@ Keep the summary concise and ready to reuse in future tasks.`
12658
13012
  import { FastMCP } from "fastmcp";
12659
13013
 
12660
13014
  // src/mcp/tools.ts
12661
- import { z as z50 } from "zod/mini";
13015
+ import { z as z51 } from "zod/mini";
12662
13016
 
12663
13017
  // src/mcp/commands.ts
12664
- import { basename as basename25, join as join97 } from "path";
12665
- import { z as z44 } from "zod/mini";
13018
+ import { basename as basename25, join as join99 } from "path";
13019
+ import { z as z45 } from "zod/mini";
12666
13020
  var maxCommandSizeBytes = 1024 * 1024;
12667
13021
  var maxCommandsCount = 1e3;
12668
13022
  async function listCommands() {
12669
- const commandsDir = join97(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
13023
+ const commandsDir = join99(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
12670
13024
  try {
12671
13025
  const files = await listDirectoryFiles(commandsDir);
12672
13026
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -12678,7 +13032,7 @@ async function listCommands() {
12678
13032
  });
12679
13033
  const frontmatter = command.getFrontmatter();
12680
13034
  return {
12681
- relativePathFromCwd: join97(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
13035
+ relativePathFromCwd: join99(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
12682
13036
  frontmatter
12683
13037
  };
12684
13038
  } catch (error) {
@@ -12704,7 +13058,7 @@ async function getCommand({ relativePathFromCwd }) {
12704
13058
  relativeFilePath: filename
12705
13059
  });
12706
13060
  return {
12707
- relativePathFromCwd: join97(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
13061
+ relativePathFromCwd: join99(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
12708
13062
  frontmatter: command.getFrontmatter(),
12709
13063
  body: command.getBody()
12710
13064
  };
@@ -12733,7 +13087,7 @@ async function putCommand({
12733
13087
  try {
12734
13088
  const existingCommands = await listCommands();
12735
13089
  const isUpdate = existingCommands.some(
12736
- (command2) => command2.relativePathFromCwd === join97(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
13090
+ (command2) => command2.relativePathFromCwd === join99(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
12737
13091
  );
12738
13092
  if (!isUpdate && existingCommands.length >= maxCommandsCount) {
12739
13093
  throw new Error(`Maximum number of commands (${maxCommandsCount}) reached`);
@@ -12748,11 +13102,11 @@ async function putCommand({
12748
13102
  fileContent,
12749
13103
  validate: true
12750
13104
  });
12751
- const commandsDir = join97(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
13105
+ const commandsDir = join99(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
12752
13106
  await ensureDir(commandsDir);
12753
13107
  await writeFileContent(command.getFilePath(), command.getFileContent());
12754
13108
  return {
12755
- relativePathFromCwd: join97(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
13109
+ relativePathFromCwd: join99(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
12756
13110
  frontmatter: command.getFrontmatter(),
12757
13111
  body: command.getBody()
12758
13112
  };
@@ -12768,11 +13122,11 @@ async function deleteCommand({ relativePathFromCwd }) {
12768
13122
  intendedRootDir: process.cwd()
12769
13123
  });
12770
13124
  const filename = basename25(relativePathFromCwd);
12771
- const fullPath = join97(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
13125
+ const fullPath = join99(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
12772
13126
  try {
12773
13127
  await removeFile(fullPath);
12774
13128
  return {
12775
- relativePathFromCwd: join97(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
13129
+ relativePathFromCwd: join99(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
12776
13130
  };
12777
13131
  } catch (error) {
12778
13132
  throw new Error(`Failed to delete command file ${relativePathFromCwd}: ${formatError(error)}`, {
@@ -12781,23 +13135,23 @@ async function deleteCommand({ relativePathFromCwd }) {
12781
13135
  }
12782
13136
  }
12783
13137
  var commandToolSchemas = {
12784
- listCommands: z44.object({}),
12785
- getCommand: z44.object({
12786
- relativePathFromCwd: z44.string()
13138
+ listCommands: z45.object({}),
13139
+ getCommand: z45.object({
13140
+ relativePathFromCwd: z45.string()
12787
13141
  }),
12788
- putCommand: z44.object({
12789
- relativePathFromCwd: z44.string(),
13142
+ putCommand: z45.object({
13143
+ relativePathFromCwd: z45.string(),
12790
13144
  frontmatter: RulesyncCommandFrontmatterSchema,
12791
- body: z44.string()
13145
+ body: z45.string()
12792
13146
  }),
12793
- deleteCommand: z44.object({
12794
- relativePathFromCwd: z44.string()
13147
+ deleteCommand: z45.object({
13148
+ relativePathFromCwd: z45.string()
12795
13149
  })
12796
13150
  };
12797
13151
  var commandTools = {
12798
13152
  listCommands: {
12799
13153
  name: "listCommands",
12800
- description: `List all commands from ${join97(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
13154
+ description: `List all commands from ${join99(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
12801
13155
  parameters: commandToolSchemas.listCommands,
12802
13156
  execute: async () => {
12803
13157
  const commands = await listCommands();
@@ -12839,11 +13193,11 @@ var commandTools = {
12839
13193
  };
12840
13194
 
12841
13195
  // src/mcp/ignore.ts
12842
- import { join as join98 } from "path";
12843
- import { z as z45 } from "zod/mini";
13196
+ import { join as join100 } from "path";
13197
+ import { z as z46 } from "zod/mini";
12844
13198
  var maxIgnoreFileSizeBytes = 100 * 1024;
12845
13199
  async function getIgnoreFile() {
12846
- const ignoreFilePath = join98(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
13200
+ const ignoreFilePath = join100(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
12847
13201
  try {
12848
13202
  const content = await readFileContent(ignoreFilePath);
12849
13203
  return {
@@ -12857,7 +13211,7 @@ async function getIgnoreFile() {
12857
13211
  }
12858
13212
  }
12859
13213
  async function putIgnoreFile({ content }) {
12860
- const ignoreFilePath = join98(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
13214
+ const ignoreFilePath = join100(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
12861
13215
  const contentSizeBytes = Buffer.byteLength(content, "utf8");
12862
13216
  if (contentSizeBytes > maxIgnoreFileSizeBytes) {
12863
13217
  throw new Error(
@@ -12878,8 +13232,8 @@ async function putIgnoreFile({ content }) {
12878
13232
  }
12879
13233
  }
12880
13234
  async function deleteIgnoreFile() {
12881
- const aiignorePath = join98(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
12882
- const legacyIgnorePath = join98(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
13235
+ const aiignorePath = join100(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
13236
+ const legacyIgnorePath = join100(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
12883
13237
  try {
12884
13238
  await Promise.all([removeFile(aiignorePath), removeFile(legacyIgnorePath)]);
12885
13239
  return {
@@ -12897,11 +13251,11 @@ async function deleteIgnoreFile() {
12897
13251
  }
12898
13252
  }
12899
13253
  var ignoreToolSchemas = {
12900
- getIgnoreFile: z45.object({}),
12901
- putIgnoreFile: z45.object({
12902
- content: z45.string()
13254
+ getIgnoreFile: z46.object({}),
13255
+ putIgnoreFile: z46.object({
13256
+ content: z46.string()
12903
13257
  }),
12904
- deleteIgnoreFile: z45.object({})
13258
+ deleteIgnoreFile: z46.object({})
12905
13259
  };
12906
13260
  var ignoreTools = {
12907
13261
  getIgnoreFile: {
@@ -12934,8 +13288,8 @@ var ignoreTools = {
12934
13288
  };
12935
13289
 
12936
13290
  // src/mcp/mcp.ts
12937
- import { join as join99 } from "path";
12938
- import { z as z46 } from "zod/mini";
13291
+ import { join as join101 } from "path";
13292
+ import { z as z47 } from "zod/mini";
12939
13293
  var maxMcpSizeBytes = 1024 * 1024;
12940
13294
  async function getMcpFile() {
12941
13295
  const config = await ConfigResolver.resolve({});
@@ -12944,7 +13298,7 @@ async function getMcpFile() {
12944
13298
  validate: true,
12945
13299
  modularMcp: config.getModularMcp()
12946
13300
  });
12947
- const relativePathFromCwd = join99(
13301
+ const relativePathFromCwd = join101(
12948
13302
  rulesyncMcp.getRelativeDirPath(),
12949
13303
  rulesyncMcp.getRelativeFilePath()
12950
13304
  );
@@ -12977,7 +13331,7 @@ async function putMcpFile({ content }) {
12977
13331
  const paths = RulesyncMcp.getSettablePaths();
12978
13332
  const relativeDirPath = paths.recommended.relativeDirPath;
12979
13333
  const relativeFilePath = paths.recommended.relativeFilePath;
12980
- const fullPath = join99(baseDir, relativeDirPath, relativeFilePath);
13334
+ const fullPath = join101(baseDir, relativeDirPath, relativeFilePath);
12981
13335
  const rulesyncMcp = new RulesyncMcp({
12982
13336
  baseDir,
12983
13337
  relativeDirPath,
@@ -12986,9 +13340,9 @@ async function putMcpFile({ content }) {
12986
13340
  validate: true,
12987
13341
  modularMcp: config.getModularMcp()
12988
13342
  });
12989
- await ensureDir(join99(baseDir, relativeDirPath));
13343
+ await ensureDir(join101(baseDir, relativeDirPath));
12990
13344
  await writeFileContent(fullPath, content);
12991
- const relativePathFromCwd = join99(relativeDirPath, relativeFilePath);
13345
+ const relativePathFromCwd = join101(relativeDirPath, relativeFilePath);
12992
13346
  return {
12993
13347
  relativePathFromCwd,
12994
13348
  content: rulesyncMcp.getFileContent()
@@ -13003,15 +13357,15 @@ async function deleteMcpFile() {
13003
13357
  try {
13004
13358
  const baseDir = process.cwd();
13005
13359
  const paths = RulesyncMcp.getSettablePaths();
13006
- const recommendedPath = join99(
13360
+ const recommendedPath = join101(
13007
13361
  baseDir,
13008
13362
  paths.recommended.relativeDirPath,
13009
13363
  paths.recommended.relativeFilePath
13010
13364
  );
13011
- const legacyPath = join99(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
13365
+ const legacyPath = join101(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
13012
13366
  await removeFile(recommendedPath);
13013
13367
  await removeFile(legacyPath);
13014
- const relativePathFromCwd = join99(
13368
+ const relativePathFromCwd = join101(
13015
13369
  paths.recommended.relativeDirPath,
13016
13370
  paths.recommended.relativeFilePath
13017
13371
  );
@@ -13025,11 +13379,11 @@ async function deleteMcpFile() {
13025
13379
  }
13026
13380
  }
13027
13381
  var mcpToolSchemas = {
13028
- getMcpFile: z46.object({}),
13029
- putMcpFile: z46.object({
13030
- content: z46.string()
13382
+ getMcpFile: z47.object({}),
13383
+ putMcpFile: z47.object({
13384
+ content: z47.string()
13031
13385
  }),
13032
- deleteMcpFile: z46.object({})
13386
+ deleteMcpFile: z47.object({})
13033
13387
  };
13034
13388
  var mcpTools = {
13035
13389
  getMcpFile: {
@@ -13062,12 +13416,12 @@ var mcpTools = {
13062
13416
  };
13063
13417
 
13064
13418
  // src/mcp/rules.ts
13065
- import { basename as basename26, join as join100 } from "path";
13066
- import { z as z47 } from "zod/mini";
13419
+ import { basename as basename26, join as join102 } from "path";
13420
+ import { z as z48 } from "zod/mini";
13067
13421
  var maxRuleSizeBytes = 1024 * 1024;
13068
13422
  var maxRulesCount = 1e3;
13069
13423
  async function listRules() {
13070
- const rulesDir = join100(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
13424
+ const rulesDir = join102(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
13071
13425
  try {
13072
13426
  const files = await listDirectoryFiles(rulesDir);
13073
13427
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -13080,7 +13434,7 @@ async function listRules() {
13080
13434
  });
13081
13435
  const frontmatter = rule.getFrontmatter();
13082
13436
  return {
13083
- relativePathFromCwd: join100(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
13437
+ relativePathFromCwd: join102(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
13084
13438
  frontmatter
13085
13439
  };
13086
13440
  } catch (error) {
@@ -13107,7 +13461,7 @@ async function getRule({ relativePathFromCwd }) {
13107
13461
  validate: true
13108
13462
  });
13109
13463
  return {
13110
- relativePathFromCwd: join100(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
13464
+ relativePathFromCwd: join102(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
13111
13465
  frontmatter: rule.getFrontmatter(),
13112
13466
  body: rule.getBody()
13113
13467
  };
@@ -13136,7 +13490,7 @@ async function putRule({
13136
13490
  try {
13137
13491
  const existingRules = await listRules();
13138
13492
  const isUpdate = existingRules.some(
13139
- (rule2) => rule2.relativePathFromCwd === join100(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
13493
+ (rule2) => rule2.relativePathFromCwd === join102(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
13140
13494
  );
13141
13495
  if (!isUpdate && existingRules.length >= maxRulesCount) {
13142
13496
  throw new Error(`Maximum number of rules (${maxRulesCount}) reached`);
@@ -13149,11 +13503,11 @@ async function putRule({
13149
13503
  body,
13150
13504
  validate: true
13151
13505
  });
13152
- const rulesDir = join100(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
13506
+ const rulesDir = join102(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
13153
13507
  await ensureDir(rulesDir);
13154
13508
  await writeFileContent(rule.getFilePath(), rule.getFileContent());
13155
13509
  return {
13156
- relativePathFromCwd: join100(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
13510
+ relativePathFromCwd: join102(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
13157
13511
  frontmatter: rule.getFrontmatter(),
13158
13512
  body: rule.getBody()
13159
13513
  };
@@ -13169,11 +13523,11 @@ async function deleteRule({ relativePathFromCwd }) {
13169
13523
  intendedRootDir: process.cwd()
13170
13524
  });
13171
13525
  const filename = basename26(relativePathFromCwd);
13172
- const fullPath = join100(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
13526
+ const fullPath = join102(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
13173
13527
  try {
13174
13528
  await removeFile(fullPath);
13175
13529
  return {
13176
- relativePathFromCwd: join100(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
13530
+ relativePathFromCwd: join102(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
13177
13531
  };
13178
13532
  } catch (error) {
13179
13533
  throw new Error(`Failed to delete rule file ${relativePathFromCwd}: ${formatError(error)}`, {
@@ -13182,23 +13536,23 @@ async function deleteRule({ relativePathFromCwd }) {
13182
13536
  }
13183
13537
  }
13184
13538
  var ruleToolSchemas = {
13185
- listRules: z47.object({}),
13186
- getRule: z47.object({
13187
- relativePathFromCwd: z47.string()
13539
+ listRules: z48.object({}),
13540
+ getRule: z48.object({
13541
+ relativePathFromCwd: z48.string()
13188
13542
  }),
13189
- putRule: z47.object({
13190
- relativePathFromCwd: z47.string(),
13543
+ putRule: z48.object({
13544
+ relativePathFromCwd: z48.string(),
13191
13545
  frontmatter: RulesyncRuleFrontmatterSchema,
13192
- body: z47.string()
13546
+ body: z48.string()
13193
13547
  }),
13194
- deleteRule: z47.object({
13195
- relativePathFromCwd: z47.string()
13548
+ deleteRule: z48.object({
13549
+ relativePathFromCwd: z48.string()
13196
13550
  })
13197
13551
  };
13198
13552
  var ruleTools = {
13199
13553
  listRules: {
13200
13554
  name: "listRules",
13201
- description: `List all rules from ${join100(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
13555
+ description: `List all rules from ${join102(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
13202
13556
  parameters: ruleToolSchemas.listRules,
13203
13557
  execute: async () => {
13204
13558
  const rules = await listRules();
@@ -13240,8 +13594,8 @@ var ruleTools = {
13240
13594
  };
13241
13595
 
13242
13596
  // src/mcp/skills.ts
13243
- import { basename as basename27, dirname as dirname2, join as join101 } from "path";
13244
- import { z as z48 } from "zod/mini";
13597
+ import { basename as basename27, dirname as dirname2, join as join103 } from "path";
13598
+ import { z as z49 } from "zod/mini";
13245
13599
  var maxSkillSizeBytes = 1024 * 1024;
13246
13600
  var maxSkillsCount = 1e3;
13247
13601
  function aiDirFileToMcpSkillFile(file) {
@@ -13264,9 +13618,9 @@ function extractDirName(relativeDirPathFromCwd) {
13264
13618
  return dirName;
13265
13619
  }
13266
13620
  async function listSkills() {
13267
- const skillsDir = join101(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH);
13621
+ const skillsDir = join103(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH);
13268
13622
  try {
13269
- const skillDirPaths = await findFilesByGlobs(join101(skillsDir, "*"), { type: "dir" });
13623
+ const skillDirPaths = await findFilesByGlobs(join103(skillsDir, "*"), { type: "dir" });
13270
13624
  const skills = await Promise.all(
13271
13625
  skillDirPaths.map(async (dirPath) => {
13272
13626
  const dirName = basename27(dirPath);
@@ -13277,7 +13631,7 @@ async function listSkills() {
13277
13631
  });
13278
13632
  const frontmatter = skill.getFrontmatter();
13279
13633
  return {
13280
- relativeDirPathFromCwd: join101(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
13634
+ relativeDirPathFromCwd: join103(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
13281
13635
  frontmatter
13282
13636
  };
13283
13637
  } catch (error) {
@@ -13303,7 +13657,7 @@ async function getSkill({ relativeDirPathFromCwd }) {
13303
13657
  dirName
13304
13658
  });
13305
13659
  return {
13306
- relativeDirPathFromCwd: join101(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
13660
+ relativeDirPathFromCwd: join103(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
13307
13661
  frontmatter: skill.getFrontmatter(),
13308
13662
  body: skill.getBody(),
13309
13663
  otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
@@ -13337,7 +13691,7 @@ async function putSkill({
13337
13691
  try {
13338
13692
  const existingSkills = await listSkills();
13339
13693
  const isUpdate = existingSkills.some(
13340
- (skill2) => skill2.relativeDirPathFromCwd === join101(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
13694
+ (skill2) => skill2.relativeDirPathFromCwd === join103(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
13341
13695
  );
13342
13696
  if (!isUpdate && existingSkills.length >= maxSkillsCount) {
13343
13697
  throw new Error(`Maximum number of skills (${maxSkillsCount}) reached`);
@@ -13352,9 +13706,9 @@ async function putSkill({
13352
13706
  otherFiles: aiDirFiles,
13353
13707
  validate: true
13354
13708
  });
13355
- const skillDirPath = join101(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
13709
+ const skillDirPath = join103(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
13356
13710
  await ensureDir(skillDirPath);
13357
- const skillFilePath = join101(skillDirPath, SKILL_FILE_NAME);
13711
+ const skillFilePath = join103(skillDirPath, SKILL_FILE_NAME);
13358
13712
  const skillFileContent = stringifyFrontmatter(body, frontmatter);
13359
13713
  await writeFileContent(skillFilePath, skillFileContent);
13360
13714
  for (const file of otherFiles) {
@@ -13362,15 +13716,15 @@ async function putSkill({
13362
13716
  relativePath: file.name,
13363
13717
  intendedRootDir: skillDirPath
13364
13718
  });
13365
- const filePath = join101(skillDirPath, file.name);
13366
- const fileDir = join101(skillDirPath, dirname2(file.name));
13719
+ const filePath = join103(skillDirPath, file.name);
13720
+ const fileDir = join103(skillDirPath, dirname2(file.name));
13367
13721
  if (fileDir !== skillDirPath) {
13368
13722
  await ensureDir(fileDir);
13369
13723
  }
13370
13724
  await writeFileContent(filePath, file.body);
13371
13725
  }
13372
13726
  return {
13373
- relativeDirPathFromCwd: join101(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
13727
+ relativeDirPathFromCwd: join103(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
13374
13728
  frontmatter: skill.getFrontmatter(),
13375
13729
  body: skill.getBody(),
13376
13730
  otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
@@ -13392,13 +13746,13 @@ async function deleteSkill({
13392
13746
  intendedRootDir: process.cwd()
13393
13747
  });
13394
13748
  const dirName = extractDirName(relativeDirPathFromCwd);
13395
- const skillDirPath = join101(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
13749
+ const skillDirPath = join103(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
13396
13750
  try {
13397
13751
  if (await directoryExists(skillDirPath)) {
13398
13752
  await removeDirectory(skillDirPath);
13399
13753
  }
13400
13754
  return {
13401
- relativeDirPathFromCwd: join101(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
13755
+ relativeDirPathFromCwd: join103(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
13402
13756
  };
13403
13757
  } catch (error) {
13404
13758
  throw new Error(
@@ -13409,29 +13763,29 @@ async function deleteSkill({
13409
13763
  );
13410
13764
  }
13411
13765
  }
13412
- var McpSkillFileSchema = z48.object({
13413
- name: z48.string(),
13414
- body: z48.string()
13766
+ var McpSkillFileSchema = z49.object({
13767
+ name: z49.string(),
13768
+ body: z49.string()
13415
13769
  });
13416
13770
  var skillToolSchemas = {
13417
- listSkills: z48.object({}),
13418
- getSkill: z48.object({
13419
- relativeDirPathFromCwd: z48.string()
13771
+ listSkills: z49.object({}),
13772
+ getSkill: z49.object({
13773
+ relativeDirPathFromCwd: z49.string()
13420
13774
  }),
13421
- putSkill: z48.object({
13422
- relativeDirPathFromCwd: z48.string(),
13775
+ putSkill: z49.object({
13776
+ relativeDirPathFromCwd: z49.string(),
13423
13777
  frontmatter: RulesyncSkillFrontmatterSchema,
13424
- body: z48.string(),
13425
- otherFiles: z48.optional(z48.array(McpSkillFileSchema))
13778
+ body: z49.string(),
13779
+ otherFiles: z49.optional(z49.array(McpSkillFileSchema))
13426
13780
  }),
13427
- deleteSkill: z48.object({
13428
- relativeDirPathFromCwd: z48.string()
13781
+ deleteSkill: z49.object({
13782
+ relativeDirPathFromCwd: z49.string()
13429
13783
  })
13430
13784
  };
13431
13785
  var skillTools = {
13432
13786
  listSkills: {
13433
13787
  name: "listSkills",
13434
- description: `List all skills from ${join101(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "*", SKILL_FILE_NAME)} with their frontmatter.`,
13788
+ description: `List all skills from ${join103(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "*", SKILL_FILE_NAME)} with their frontmatter.`,
13435
13789
  parameters: skillToolSchemas.listSkills,
13436
13790
  execute: async () => {
13437
13791
  const skills = await listSkills();
@@ -13474,12 +13828,12 @@ var skillTools = {
13474
13828
  };
13475
13829
 
13476
13830
  // src/mcp/subagents.ts
13477
- import { basename as basename28, join as join102 } from "path";
13478
- import { z as z49 } from "zod/mini";
13831
+ import { basename as basename28, join as join104 } from "path";
13832
+ import { z as z50 } from "zod/mini";
13479
13833
  var maxSubagentSizeBytes = 1024 * 1024;
13480
13834
  var maxSubagentsCount = 1e3;
13481
13835
  async function listSubagents() {
13482
- const subagentsDir = join102(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
13836
+ const subagentsDir = join104(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
13483
13837
  try {
13484
13838
  const files = await listDirectoryFiles(subagentsDir);
13485
13839
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -13492,7 +13846,7 @@ async function listSubagents() {
13492
13846
  });
13493
13847
  const frontmatter = subagent.getFrontmatter();
13494
13848
  return {
13495
- relativePathFromCwd: join102(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
13849
+ relativePathFromCwd: join104(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
13496
13850
  frontmatter
13497
13851
  };
13498
13852
  } catch (error) {
@@ -13521,7 +13875,7 @@ async function getSubagent({ relativePathFromCwd }) {
13521
13875
  validate: true
13522
13876
  });
13523
13877
  return {
13524
- relativePathFromCwd: join102(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
13878
+ relativePathFromCwd: join104(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
13525
13879
  frontmatter: subagent.getFrontmatter(),
13526
13880
  body: subagent.getBody()
13527
13881
  };
@@ -13550,7 +13904,7 @@ async function putSubagent({
13550
13904
  try {
13551
13905
  const existingSubagents = await listSubagents();
13552
13906
  const isUpdate = existingSubagents.some(
13553
- (subagent2) => subagent2.relativePathFromCwd === join102(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
13907
+ (subagent2) => subagent2.relativePathFromCwd === join104(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
13554
13908
  );
13555
13909
  if (!isUpdate && existingSubagents.length >= maxSubagentsCount) {
13556
13910
  throw new Error(`Maximum number of subagents (${maxSubagentsCount}) reached`);
@@ -13563,11 +13917,11 @@ async function putSubagent({
13563
13917
  body,
13564
13918
  validate: true
13565
13919
  });
13566
- const subagentsDir = join102(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
13920
+ const subagentsDir = join104(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
13567
13921
  await ensureDir(subagentsDir);
13568
13922
  await writeFileContent(subagent.getFilePath(), subagent.getFileContent());
13569
13923
  return {
13570
- relativePathFromCwd: join102(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
13924
+ relativePathFromCwd: join104(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
13571
13925
  frontmatter: subagent.getFrontmatter(),
13572
13926
  body: subagent.getBody()
13573
13927
  };
@@ -13583,11 +13937,11 @@ async function deleteSubagent({ relativePathFromCwd }) {
13583
13937
  intendedRootDir: process.cwd()
13584
13938
  });
13585
13939
  const filename = basename28(relativePathFromCwd);
13586
- const fullPath = join102(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
13940
+ const fullPath = join104(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
13587
13941
  try {
13588
13942
  await removeFile(fullPath);
13589
13943
  return {
13590
- relativePathFromCwd: join102(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
13944
+ relativePathFromCwd: join104(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
13591
13945
  };
13592
13946
  } catch (error) {
13593
13947
  throw new Error(
@@ -13599,23 +13953,23 @@ async function deleteSubagent({ relativePathFromCwd }) {
13599
13953
  }
13600
13954
  }
13601
13955
  var subagentToolSchemas = {
13602
- listSubagents: z49.object({}),
13603
- getSubagent: z49.object({
13604
- relativePathFromCwd: z49.string()
13956
+ listSubagents: z50.object({}),
13957
+ getSubagent: z50.object({
13958
+ relativePathFromCwd: z50.string()
13605
13959
  }),
13606
- putSubagent: z49.object({
13607
- relativePathFromCwd: z49.string(),
13960
+ putSubagent: z50.object({
13961
+ relativePathFromCwd: z50.string(),
13608
13962
  frontmatter: RulesyncSubagentFrontmatterSchema,
13609
- body: z49.string()
13963
+ body: z50.string()
13610
13964
  }),
13611
- deleteSubagent: z49.object({
13612
- relativePathFromCwd: z49.string()
13965
+ deleteSubagent: z50.object({
13966
+ relativePathFromCwd: z50.string()
13613
13967
  })
13614
13968
  };
13615
13969
  var subagentTools = {
13616
13970
  listSubagents: {
13617
13971
  name: "listSubagents",
13618
- description: `List all subagents from ${join102(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
13972
+ description: `List all subagents from ${join104(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
13619
13973
  parameters: subagentToolSchemas.listSubagents,
13620
13974
  execute: async () => {
13621
13975
  const subagents = await listSubagents();
@@ -13657,20 +14011,20 @@ var subagentTools = {
13657
14011
  };
13658
14012
 
13659
14013
  // src/mcp/tools.ts
13660
- var rulesyncFeatureSchema = z50.enum(["rule", "command", "subagent", "skill", "ignore", "mcp"]);
13661
- var rulesyncOperationSchema = z50.enum(["list", "get", "put", "delete"]);
13662
- var skillFileSchema = z50.object({
13663
- name: z50.string(),
13664
- body: z50.string()
14014
+ var rulesyncFeatureSchema = z51.enum(["rule", "command", "subagent", "skill", "ignore", "mcp"]);
14015
+ var rulesyncOperationSchema = z51.enum(["list", "get", "put", "delete"]);
14016
+ var skillFileSchema = z51.object({
14017
+ name: z51.string(),
14018
+ body: z51.string()
13665
14019
  });
13666
- var rulesyncToolSchema = z50.object({
14020
+ var rulesyncToolSchema = z51.object({
13667
14021
  feature: rulesyncFeatureSchema,
13668
14022
  operation: rulesyncOperationSchema,
13669
- targetPathFromCwd: z50.optional(z50.string()),
13670
- frontmatter: z50.optional(z50.unknown()),
13671
- body: z50.optional(z50.string()),
13672
- otherFiles: z50.optional(z50.array(skillFileSchema)),
13673
- content: z50.optional(z50.string())
14023
+ targetPathFromCwd: z51.optional(z51.string()),
14024
+ frontmatter: z51.optional(z51.unknown()),
14025
+ body: z51.optional(z51.string()),
14026
+ otherFiles: z51.optional(z51.array(skillFileSchema)),
14027
+ content: z51.optional(z51.string())
13674
14028
  });
13675
14029
  var supportedOperationsByFeature = {
13676
14030
  rule: ["list", "get", "put", "delete"],
@@ -13866,7 +14220,7 @@ async function mcpCommand({ version }) {
13866
14220
  }
13867
14221
 
13868
14222
  // src/cli/index.ts
13869
- var getVersion = () => "5.7.0";
14223
+ var getVersion = () => "5.9.0";
13870
14224
  var main = async () => {
13871
14225
  const program = new Command();
13872
14226
  const version = getVersion();
@@ -13890,12 +14244,13 @@ var main = async () => {
13890
14244
  (value) => {
13891
14245
  return value.split(",").map((f) => f.trim());
13892
14246
  }
13893
- ).option("-V, --verbose", "Verbose output").option("-g, --global", "Import for global(user scope) configuration files").action(async (options) => {
14247
+ ).option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").option("-g, --global", "Import for global(user scope) configuration files").action(async (options) => {
13894
14248
  try {
13895
14249
  await importCommand({
13896
14250
  targets: options.targets,
13897
14251
  features: options.features,
13898
14252
  verbose: options.verbose,
14253
+ silent: options.silent,
13899
14254
  configPath: options.config,
13900
14255
  global: options.global
13901
14256
  });
@@ -13927,7 +14282,7 @@ var main = async () => {
13927
14282
  ).option("--delete", "Delete all existing files in output directories before generating").option(
13928
14283
  "-b, --base-dir <paths>",
13929
14284
  "Base directories to generate files (comma-separated for multiple paths)"
13930
- ).option("-V, --verbose", "Verbose output").option("-c, --config <path>", "Path to configuration file").option("-g, --global", "Generate for global(user scope) configuration files").option(
14285
+ ).option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").option("-c, --config <path>", "Path to configuration file").option("-g, --global", "Generate for global(user scope) configuration files").option(
13931
14286
  "--simulate-commands",
13932
14287
  "Generate simulated commands. This feature is only available for copilot, cursor and codexcli."
13933
14288
  ).option(
@@ -13945,6 +14300,7 @@ var main = async () => {
13945
14300
  targets: options.targets,
13946
14301
  features: options.features,
13947
14302
  verbose: options.verbose,
14303
+ silent: options.silent,
13948
14304
  delete: options.delete,
13949
14305
  baseDirs: options.baseDirs,
13950
14306
  configPath: options.config,