rulesync 7.13.0 → 7.14.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.
@@ -128,7 +128,7 @@ var Logger = class {
128
128
  var logger = new Logger();
129
129
 
130
130
  // src/lib/fetch.ts
131
- var import_node_path114 = require("path");
131
+ var import_node_path116 = require("path");
132
132
  var import_promise = require("es-toolkit/promise");
133
133
 
134
134
  // src/constants/rulesync-paths.ts
@@ -242,6 +242,24 @@ async function fileExists(filepath) {
242
242
  return false;
243
243
  }
244
244
  }
245
+ async function getFileSize(filepath) {
246
+ try {
247
+ const stats = await (0, import_promises.stat)(filepath);
248
+ return stats.size;
249
+ } catch (error) {
250
+ throw new Error(`Failed to get file size for "${filepath}": ${formatError(error)}`, {
251
+ cause: error
252
+ });
253
+ }
254
+ }
255
+ async function isSymlink(filepath) {
256
+ try {
257
+ const stats = await (0, import_promises.lstat)(filepath);
258
+ return stats.isSymbolicLink();
259
+ } catch {
260
+ return false;
261
+ }
262
+ }
245
263
  async function listDirectoryFiles(dir) {
246
264
  try {
247
265
  return await (0, import_promises.readdir)(dir);
@@ -7137,9 +7155,9 @@ var McpProcessor = class extends FeatureProcessor {
7137
7155
  };
7138
7156
 
7139
7157
  // src/features/rules/rules-processor.ts
7140
- var import_node_path113 = require("path");
7158
+ var import_node_path115 = require("path");
7141
7159
  var import_toon = require("@toon-format/toon");
7142
- var import_mini53 = require("zod/mini");
7160
+ var import_mini55 = require("zod/mini");
7143
7161
 
7144
7162
  // src/constants/general.ts
7145
7163
  var SKILL_FILE_NAME = "SKILL.md";
@@ -7607,8 +7625,8 @@ var FactorydroidSkill = class _FactorydroidSkill extends SimulatedSkill {
7607
7625
  };
7608
7626
 
7609
7627
  // src/features/skills/skills-processor.ts
7610
- var import_node_path75 = require("path");
7611
- var import_mini37 = require("zod/mini");
7628
+ var import_node_path76 = require("path");
7629
+ var import_mini38 = require("zod/mini");
7612
7630
 
7613
7631
  // src/types/dir-feature-processor.ts
7614
7632
  var import_node_path59 = require("path");
@@ -9160,17 +9178,193 @@ var GeminiCliSkill = class _GeminiCliSkill extends ToolSkill {
9160
9178
  }
9161
9179
  };
9162
9180
 
9163
- // src/features/skills/kilo-skill.ts
9181
+ // src/features/skills/junie-skill.ts
9164
9182
  var import_node_path69 = require("path");
9165
9183
  var import_mini32 = require("zod/mini");
9166
- var KiloSkillFrontmatterSchema = import_mini32.z.looseObject({
9184
+ var JunieSkillFrontmatterSchema = import_mini32.z.looseObject({
9167
9185
  name: import_mini32.z.string(),
9168
9186
  description: import_mini32.z.string()
9169
9187
  });
9188
+ var JunieSkill = class _JunieSkill extends ToolSkill {
9189
+ constructor({
9190
+ baseDir = process.cwd(),
9191
+ relativeDirPath = (0, import_node_path69.join)(".junie", "skills"),
9192
+ dirName,
9193
+ frontmatter,
9194
+ body,
9195
+ otherFiles = [],
9196
+ validate = true,
9197
+ global = false
9198
+ }) {
9199
+ super({
9200
+ baseDir,
9201
+ relativeDirPath,
9202
+ dirName,
9203
+ mainFile: {
9204
+ name: SKILL_FILE_NAME,
9205
+ body,
9206
+ frontmatter: { ...frontmatter }
9207
+ },
9208
+ otherFiles,
9209
+ global
9210
+ });
9211
+ if (validate) {
9212
+ const result = this.validate();
9213
+ if (!result.success) {
9214
+ throw result.error;
9215
+ }
9216
+ }
9217
+ }
9218
+ static getSettablePaths(options) {
9219
+ if (options?.global) {
9220
+ throw new Error("JunieSkill does not support global mode.");
9221
+ }
9222
+ return {
9223
+ relativeDirPath: (0, import_node_path69.join)(".junie", "skills")
9224
+ };
9225
+ }
9226
+ getFrontmatter() {
9227
+ const result = JunieSkillFrontmatterSchema.parse(this.requireMainFileFrontmatter());
9228
+ return result;
9229
+ }
9230
+ getBody() {
9231
+ return this.mainFile?.body ?? "";
9232
+ }
9233
+ validate() {
9234
+ if (!this.mainFile) {
9235
+ return {
9236
+ success: false,
9237
+ error: new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
9238
+ };
9239
+ }
9240
+ const result = JunieSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
9241
+ if (!result.success) {
9242
+ return {
9243
+ success: false,
9244
+ error: new Error(
9245
+ `Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
9246
+ )
9247
+ };
9248
+ }
9249
+ if (result.data.name !== this.getDirName()) {
9250
+ return {
9251
+ success: false,
9252
+ error: new Error(
9253
+ `${this.getDirPath()}: frontmatter name (${result.data.name}) must match directory name (${this.getDirName()})`
9254
+ )
9255
+ };
9256
+ }
9257
+ return { success: true, error: null };
9258
+ }
9259
+ toRulesyncSkill() {
9260
+ const frontmatter = this.getFrontmatter();
9261
+ const rulesyncFrontmatter = {
9262
+ name: frontmatter.name,
9263
+ description: frontmatter.description,
9264
+ targets: ["*"]
9265
+ };
9266
+ return new RulesyncSkill({
9267
+ baseDir: this.baseDir,
9268
+ relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH,
9269
+ dirName: this.getDirName(),
9270
+ frontmatter: rulesyncFrontmatter,
9271
+ body: this.getBody(),
9272
+ otherFiles: this.getOtherFiles(),
9273
+ validate: true,
9274
+ global: this.global
9275
+ });
9276
+ }
9277
+ static fromRulesyncSkill({
9278
+ rulesyncSkill,
9279
+ validate = true,
9280
+ global = false
9281
+ }) {
9282
+ const settablePaths = _JunieSkill.getSettablePaths({ global });
9283
+ const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
9284
+ const junieFrontmatter = {
9285
+ name: rulesyncFrontmatter.name,
9286
+ description: rulesyncFrontmatter.description
9287
+ };
9288
+ return new _JunieSkill({
9289
+ baseDir: rulesyncSkill.getBaseDir(),
9290
+ relativeDirPath: settablePaths.relativeDirPath,
9291
+ dirName: junieFrontmatter.name,
9292
+ frontmatter: junieFrontmatter,
9293
+ body: rulesyncSkill.getBody(),
9294
+ otherFiles: rulesyncSkill.getOtherFiles(),
9295
+ validate,
9296
+ global
9297
+ });
9298
+ }
9299
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
9300
+ const targets = rulesyncSkill.getFrontmatter().targets;
9301
+ return targets.includes("*") || targets.includes("junie");
9302
+ }
9303
+ static async fromDir(params) {
9304
+ const loaded = await this.loadSkillDirContent({
9305
+ ...params,
9306
+ getSettablePaths: _JunieSkill.getSettablePaths
9307
+ });
9308
+ const result = JunieSkillFrontmatterSchema.safeParse(loaded.frontmatter);
9309
+ if (!result.success) {
9310
+ const skillDirPath = (0, import_node_path69.join)(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9311
+ throw new Error(
9312
+ `Invalid frontmatter in ${(0, import_node_path69.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9313
+ );
9314
+ }
9315
+ if (result.data.name !== loaded.dirName) {
9316
+ const skillFilePath = (0, import_node_path69.join)(
9317
+ loaded.baseDir,
9318
+ loaded.relativeDirPath,
9319
+ loaded.dirName,
9320
+ SKILL_FILE_NAME
9321
+ );
9322
+ throw new Error(
9323
+ `Frontmatter name (${result.data.name}) must match directory name (${loaded.dirName}) in ${skillFilePath}`
9324
+ );
9325
+ }
9326
+ return new _JunieSkill({
9327
+ baseDir: loaded.baseDir,
9328
+ relativeDirPath: loaded.relativeDirPath,
9329
+ dirName: loaded.dirName,
9330
+ frontmatter: result.data,
9331
+ body: loaded.body,
9332
+ otherFiles: loaded.otherFiles,
9333
+ validate: true,
9334
+ global: loaded.global
9335
+ });
9336
+ }
9337
+ static forDeletion({
9338
+ baseDir = process.cwd(),
9339
+ relativeDirPath,
9340
+ dirName,
9341
+ global = false
9342
+ }) {
9343
+ const settablePaths = _JunieSkill.getSettablePaths({ global });
9344
+ return new _JunieSkill({
9345
+ baseDir,
9346
+ relativeDirPath: relativeDirPath ?? settablePaths.relativeDirPath,
9347
+ dirName,
9348
+ frontmatter: { name: "", description: "" },
9349
+ body: "",
9350
+ otherFiles: [],
9351
+ validate: false,
9352
+ global
9353
+ });
9354
+ }
9355
+ };
9356
+
9357
+ // src/features/skills/kilo-skill.ts
9358
+ var import_node_path70 = require("path");
9359
+ var import_mini33 = require("zod/mini");
9360
+ var KiloSkillFrontmatterSchema = import_mini33.z.looseObject({
9361
+ name: import_mini33.z.string(),
9362
+ description: import_mini33.z.string()
9363
+ });
9170
9364
  var KiloSkill = class _KiloSkill extends ToolSkill {
9171
9365
  constructor({
9172
9366
  baseDir = process.cwd(),
9173
- relativeDirPath = (0, import_node_path69.join)(".kilocode", "skills"),
9367
+ relativeDirPath = (0, import_node_path70.join)(".kilocode", "skills"),
9174
9368
  dirName,
9175
9369
  frontmatter,
9176
9370
  body,
@@ -9201,7 +9395,7 @@ var KiloSkill = class _KiloSkill extends ToolSkill {
9201
9395
  global: _global = false
9202
9396
  } = {}) {
9203
9397
  return {
9204
- relativeDirPath: (0, import_node_path69.join)(".kilocode", "skills")
9398
+ relativeDirPath: (0, import_node_path70.join)(".kilocode", "skills")
9205
9399
  };
9206
9400
  }
9207
9401
  getFrontmatter() {
@@ -9288,13 +9482,13 @@ var KiloSkill = class _KiloSkill extends ToolSkill {
9288
9482
  });
9289
9483
  const result = KiloSkillFrontmatterSchema.safeParse(loaded.frontmatter);
9290
9484
  if (!result.success) {
9291
- const skillDirPath = (0, import_node_path69.join)(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9485
+ const skillDirPath = (0, import_node_path70.join)(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9292
9486
  throw new Error(
9293
- `Invalid frontmatter in ${(0, import_node_path69.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9487
+ `Invalid frontmatter in ${(0, import_node_path70.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9294
9488
  );
9295
9489
  }
9296
9490
  if (result.data.name !== loaded.dirName) {
9297
- const skillFilePath = (0, import_node_path69.join)(
9491
+ const skillFilePath = (0, import_node_path70.join)(
9298
9492
  loaded.baseDir,
9299
9493
  loaded.relativeDirPath,
9300
9494
  loaded.dirName,
@@ -9335,16 +9529,16 @@ var KiloSkill = class _KiloSkill extends ToolSkill {
9335
9529
  };
9336
9530
 
9337
9531
  // src/features/skills/kiro-skill.ts
9338
- var import_node_path70 = require("path");
9339
- var import_mini33 = require("zod/mini");
9340
- var KiroSkillFrontmatterSchema = import_mini33.z.looseObject({
9341
- name: import_mini33.z.string(),
9342
- description: import_mini33.z.string()
9532
+ var import_node_path71 = require("path");
9533
+ var import_mini34 = require("zod/mini");
9534
+ var KiroSkillFrontmatterSchema = import_mini34.z.looseObject({
9535
+ name: import_mini34.z.string(),
9536
+ description: import_mini34.z.string()
9343
9537
  });
9344
9538
  var KiroSkill = class _KiroSkill extends ToolSkill {
9345
9539
  constructor({
9346
9540
  baseDir = process.cwd(),
9347
- relativeDirPath = (0, import_node_path70.join)(".kiro", "skills"),
9541
+ relativeDirPath = (0, import_node_path71.join)(".kiro", "skills"),
9348
9542
  dirName,
9349
9543
  frontmatter,
9350
9544
  body,
@@ -9376,7 +9570,7 @@ var KiroSkill = class _KiroSkill extends ToolSkill {
9376
9570
  throw new Error("KiroSkill does not support global mode.");
9377
9571
  }
9378
9572
  return {
9379
- relativeDirPath: (0, import_node_path70.join)(".kiro", "skills")
9573
+ relativeDirPath: (0, import_node_path71.join)(".kiro", "skills")
9380
9574
  };
9381
9575
  }
9382
9576
  getFrontmatter() {
@@ -9463,13 +9657,13 @@ var KiroSkill = class _KiroSkill extends ToolSkill {
9463
9657
  });
9464
9658
  const result = KiroSkillFrontmatterSchema.safeParse(loaded.frontmatter);
9465
9659
  if (!result.success) {
9466
- const skillDirPath = (0, import_node_path70.join)(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9660
+ const skillDirPath = (0, import_node_path71.join)(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9467
9661
  throw new Error(
9468
- `Invalid frontmatter in ${(0, import_node_path70.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9662
+ `Invalid frontmatter in ${(0, import_node_path71.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9469
9663
  );
9470
9664
  }
9471
9665
  if (result.data.name !== loaded.dirName) {
9472
- const skillFilePath = (0, import_node_path70.join)(
9666
+ const skillFilePath = (0, import_node_path71.join)(
9473
9667
  loaded.baseDir,
9474
9668
  loaded.relativeDirPath,
9475
9669
  loaded.dirName,
@@ -9511,17 +9705,17 @@ var KiroSkill = class _KiroSkill extends ToolSkill {
9511
9705
  };
9512
9706
 
9513
9707
  // src/features/skills/opencode-skill.ts
9514
- var import_node_path71 = require("path");
9515
- var import_mini34 = require("zod/mini");
9516
- var OpenCodeSkillFrontmatterSchema = import_mini34.z.looseObject({
9517
- name: import_mini34.z.string(),
9518
- description: import_mini34.z.string(),
9519
- "allowed-tools": import_mini34.z.optional(import_mini34.z.array(import_mini34.z.string()))
9708
+ var import_node_path72 = require("path");
9709
+ var import_mini35 = require("zod/mini");
9710
+ var OpenCodeSkillFrontmatterSchema = import_mini35.z.looseObject({
9711
+ name: import_mini35.z.string(),
9712
+ description: import_mini35.z.string(),
9713
+ "allowed-tools": import_mini35.z.optional(import_mini35.z.array(import_mini35.z.string()))
9520
9714
  });
9521
9715
  var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
9522
9716
  constructor({
9523
9717
  baseDir = process.cwd(),
9524
- relativeDirPath = (0, import_node_path71.join)(".opencode", "skill"),
9718
+ relativeDirPath = (0, import_node_path72.join)(".opencode", "skill"),
9525
9719
  dirName,
9526
9720
  frontmatter,
9527
9721
  body,
@@ -9550,7 +9744,7 @@ var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
9550
9744
  }
9551
9745
  static getSettablePaths({ global = false } = {}) {
9552
9746
  return {
9553
- relativeDirPath: global ? (0, import_node_path71.join)(".config", "opencode", "skill") : (0, import_node_path71.join)(".opencode", "skill")
9747
+ relativeDirPath: global ? (0, import_node_path72.join)(".config", "opencode", "skill") : (0, import_node_path72.join)(".opencode", "skill")
9554
9748
  };
9555
9749
  }
9556
9750
  getFrontmatter() {
@@ -9635,9 +9829,9 @@ var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
9635
9829
  });
9636
9830
  const result = OpenCodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
9637
9831
  if (!result.success) {
9638
- const skillDirPath = (0, import_node_path71.join)(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9832
+ const skillDirPath = (0, import_node_path72.join)(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9639
9833
  throw new Error(
9640
- `Invalid frontmatter in ${(0, import_node_path71.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9834
+ `Invalid frontmatter in ${(0, import_node_path72.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9641
9835
  );
9642
9836
  }
9643
9837
  return new _OpenCodeSkill({
@@ -9671,16 +9865,16 @@ var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
9671
9865
  };
9672
9866
 
9673
9867
  // src/features/skills/replit-skill.ts
9674
- var import_node_path72 = require("path");
9675
- var import_mini35 = require("zod/mini");
9676
- var ReplitSkillFrontmatterSchema = import_mini35.z.looseObject({
9677
- name: import_mini35.z.string(),
9678
- description: import_mini35.z.string()
9868
+ var import_node_path73 = require("path");
9869
+ var import_mini36 = require("zod/mini");
9870
+ var ReplitSkillFrontmatterSchema = import_mini36.z.looseObject({
9871
+ name: import_mini36.z.string(),
9872
+ description: import_mini36.z.string()
9679
9873
  });
9680
9874
  var ReplitSkill = class _ReplitSkill extends ToolSkill {
9681
9875
  constructor({
9682
9876
  baseDir = process.cwd(),
9683
- relativeDirPath = (0, import_node_path72.join)(".agents", "skills"),
9877
+ relativeDirPath = (0, import_node_path73.join)(".agents", "skills"),
9684
9878
  dirName,
9685
9879
  frontmatter,
9686
9880
  body,
@@ -9712,7 +9906,7 @@ var ReplitSkill = class _ReplitSkill extends ToolSkill {
9712
9906
  throw new Error("ReplitSkill does not support global mode.");
9713
9907
  }
9714
9908
  return {
9715
- relativeDirPath: (0, import_node_path72.join)(".agents", "skills")
9909
+ relativeDirPath: (0, import_node_path73.join)(".agents", "skills")
9716
9910
  };
9717
9911
  }
9718
9912
  getFrontmatter() {
@@ -9791,9 +9985,9 @@ var ReplitSkill = class _ReplitSkill extends ToolSkill {
9791
9985
  });
9792
9986
  const result = ReplitSkillFrontmatterSchema.safeParse(loaded.frontmatter);
9793
9987
  if (!result.success) {
9794
- const skillDirPath = (0, import_node_path72.join)(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9988
+ const skillDirPath = (0, import_node_path73.join)(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9795
9989
  throw new Error(
9796
- `Invalid frontmatter in ${(0, import_node_path72.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9990
+ `Invalid frontmatter in ${(0, import_node_path73.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9797
9991
  );
9798
9992
  }
9799
9993
  return new _ReplitSkill({
@@ -9828,16 +10022,16 @@ var ReplitSkill = class _ReplitSkill extends ToolSkill {
9828
10022
  };
9829
10023
 
9830
10024
  // src/features/skills/roo-skill.ts
9831
- var import_node_path73 = require("path");
9832
- var import_mini36 = require("zod/mini");
9833
- var RooSkillFrontmatterSchema = import_mini36.z.looseObject({
9834
- name: import_mini36.z.string(),
9835
- description: import_mini36.z.string()
10025
+ var import_node_path74 = require("path");
10026
+ var import_mini37 = require("zod/mini");
10027
+ var RooSkillFrontmatterSchema = import_mini37.z.looseObject({
10028
+ name: import_mini37.z.string(),
10029
+ description: import_mini37.z.string()
9836
10030
  });
9837
10031
  var RooSkill = class _RooSkill extends ToolSkill {
9838
10032
  constructor({
9839
10033
  baseDir = process.cwd(),
9840
- relativeDirPath = (0, import_node_path73.join)(".roo", "skills"),
10034
+ relativeDirPath = (0, import_node_path74.join)(".roo", "skills"),
9841
10035
  dirName,
9842
10036
  frontmatter,
9843
10037
  body,
@@ -9868,7 +10062,7 @@ var RooSkill = class _RooSkill extends ToolSkill {
9868
10062
  global: _global = false
9869
10063
  } = {}) {
9870
10064
  return {
9871
- relativeDirPath: (0, import_node_path73.join)(".roo", "skills")
10065
+ relativeDirPath: (0, import_node_path74.join)(".roo", "skills")
9872
10066
  };
9873
10067
  }
9874
10068
  getFrontmatter() {
@@ -9955,13 +10149,13 @@ var RooSkill = class _RooSkill extends ToolSkill {
9955
10149
  });
9956
10150
  const result = RooSkillFrontmatterSchema.safeParse(loaded.frontmatter);
9957
10151
  if (!result.success) {
9958
- const skillDirPath = (0, import_node_path73.join)(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
10152
+ const skillDirPath = (0, import_node_path74.join)(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9959
10153
  throw new Error(
9960
- `Invalid frontmatter in ${(0, import_node_path73.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
10154
+ `Invalid frontmatter in ${(0, import_node_path74.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9961
10155
  );
9962
10156
  }
9963
10157
  if (result.data.name !== loaded.dirName) {
9964
- const skillFilePath = (0, import_node_path73.join)(
10158
+ const skillFilePath = (0, import_node_path74.join)(
9965
10159
  loaded.baseDir,
9966
10160
  loaded.relativeDirPath,
9967
10161
  loaded.dirName,
@@ -10002,17 +10196,17 @@ var RooSkill = class _RooSkill extends ToolSkill {
10002
10196
  };
10003
10197
 
10004
10198
  // src/features/skills/skills-utils.ts
10005
- var import_node_path74 = require("path");
10199
+ var import_node_path75 = require("path");
10006
10200
  async function getLocalSkillDirNames(baseDir) {
10007
- const skillsDir = (0, import_node_path74.join)(baseDir, RULESYNC_SKILLS_RELATIVE_DIR_PATH);
10201
+ const skillsDir = (0, import_node_path75.join)(baseDir, RULESYNC_SKILLS_RELATIVE_DIR_PATH);
10008
10202
  const names = /* @__PURE__ */ new Set();
10009
10203
  if (!await directoryExists(skillsDir)) {
10010
10204
  return names;
10011
10205
  }
10012
- const dirPaths = await findFilesByGlobs((0, import_node_path74.join)(skillsDir, "*"), { type: "dir" });
10206
+ const dirPaths = await findFilesByGlobs((0, import_node_path75.join)(skillsDir, "*"), { type: "dir" });
10013
10207
  for (const dirPath of dirPaths) {
10014
- const name = (0, import_node_path74.basename)(dirPath);
10015
- if (name === (0, import_node_path74.basename)(RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH)) continue;
10208
+ const name = (0, import_node_path75.basename)(dirPath);
10209
+ if (name === (0, import_node_path75.basename)(RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH)) continue;
10016
10210
  names.add(name);
10017
10211
  }
10018
10212
  return names;
@@ -10031,13 +10225,14 @@ var skillsProcessorToolTargetTuple = [
10031
10225
  "cursor",
10032
10226
  "factorydroid",
10033
10227
  "geminicli",
10228
+ "junie",
10034
10229
  "kilo",
10035
10230
  "kiro",
10036
10231
  "opencode",
10037
10232
  "replit",
10038
10233
  "roo"
10039
10234
  ];
10040
- var SkillsProcessorToolTargetSchema = import_mini37.z.enum(skillsProcessorToolTargetTuple);
10235
+ var SkillsProcessorToolTargetSchema = import_mini38.z.enum(skillsProcessorToolTargetTuple);
10041
10236
  var toolSkillFactories = /* @__PURE__ */ new Map([
10042
10237
  [
10043
10238
  "agentsmd",
@@ -10116,6 +10311,13 @@ var toolSkillFactories = /* @__PURE__ */ new Map([
10116
10311
  meta: { supportsProject: true, supportsSimulated: false, supportsGlobal: true }
10117
10312
  }
10118
10313
  ],
10314
+ [
10315
+ "junie",
10316
+ {
10317
+ class: JunieSkill,
10318
+ meta: { supportsProject: true, supportsSimulated: false, supportsGlobal: false }
10319
+ }
10320
+ ],
10119
10321
  [
10120
10322
  "kilo",
10121
10323
  {
@@ -10238,11 +10440,11 @@ var SkillsProcessor = class extends DirFeatureProcessor {
10238
10440
  )
10239
10441
  );
10240
10442
  const localSkillNames = new Set(localDirNames);
10241
- const curatedDirPath = (0, import_node_path75.join)(process.cwd(), RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
10443
+ const curatedDirPath = (0, import_node_path76.join)(process.cwd(), RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
10242
10444
  let curatedSkills = [];
10243
10445
  if (await directoryExists(curatedDirPath)) {
10244
- const curatedDirPaths = await findFilesByGlobs((0, import_node_path75.join)(curatedDirPath, "*"), { type: "dir" });
10245
- const curatedDirNames = curatedDirPaths.map((path4) => (0, import_node_path75.basename)(path4));
10446
+ const curatedDirPaths = await findFilesByGlobs((0, import_node_path76.join)(curatedDirPath, "*"), { type: "dir" });
10447
+ const curatedDirNames = curatedDirPaths.map((path4) => (0, import_node_path76.basename)(path4));
10246
10448
  const nonConflicting = curatedDirNames.filter((name) => {
10247
10449
  if (localSkillNames.has(name)) {
10248
10450
  logger.debug(`Skipping curated skill "${name}": local skill takes precedence.`);
@@ -10275,9 +10477,9 @@ var SkillsProcessor = class extends DirFeatureProcessor {
10275
10477
  async loadToolDirs() {
10276
10478
  const factory = this.getFactory(this.toolTarget);
10277
10479
  const paths = factory.class.getSettablePaths({ global: this.global });
10278
- const skillsDirPath = (0, import_node_path75.join)(this.baseDir, paths.relativeDirPath);
10279
- const dirPaths = await findFilesByGlobs((0, import_node_path75.join)(skillsDirPath, "*"), { type: "dir" });
10280
- const dirNames = dirPaths.map((path4) => (0, import_node_path75.basename)(path4));
10480
+ const skillsDirPath = (0, import_node_path76.join)(this.baseDir, paths.relativeDirPath);
10481
+ const dirPaths = await findFilesByGlobs((0, import_node_path76.join)(skillsDirPath, "*"), { type: "dir" });
10482
+ const dirNames = dirPaths.map((path4) => (0, import_node_path76.basename)(path4));
10281
10483
  const toolSkills = await Promise.all(
10282
10484
  dirNames.map(
10283
10485
  (dirName) => factory.class.fromDir({
@@ -10293,9 +10495,9 @@ var SkillsProcessor = class extends DirFeatureProcessor {
10293
10495
  async loadToolDirsToDelete() {
10294
10496
  const factory = this.getFactory(this.toolTarget);
10295
10497
  const paths = factory.class.getSettablePaths({ global: this.global });
10296
- const skillsDirPath = (0, import_node_path75.join)(this.baseDir, paths.relativeDirPath);
10297
- const dirPaths = await findFilesByGlobs((0, import_node_path75.join)(skillsDirPath, "*"), { type: "dir" });
10298
- const dirNames = dirPaths.map((path4) => (0, import_node_path75.basename)(path4));
10498
+ const skillsDirPath = (0, import_node_path76.join)(this.baseDir, paths.relativeDirPath);
10499
+ const dirPaths = await findFilesByGlobs((0, import_node_path76.join)(skillsDirPath, "*"), { type: "dir" });
10500
+ const dirNames = dirPaths.map((path4) => (0, import_node_path76.basename)(path4));
10299
10501
  const toolSkills = dirNames.map(
10300
10502
  (dirName) => factory.class.forDeletion({
10301
10503
  baseDir: this.baseDir,
@@ -10356,11 +10558,11 @@ var SkillsProcessor = class extends DirFeatureProcessor {
10356
10558
  };
10357
10559
 
10358
10560
  // src/features/subagents/agentsmd-subagent.ts
10359
- var import_node_path77 = require("path");
10561
+ var import_node_path78 = require("path");
10360
10562
 
10361
10563
  // src/features/subagents/simulated-subagent.ts
10362
- var import_node_path76 = require("path");
10363
- var import_mini38 = require("zod/mini");
10564
+ var import_node_path77 = require("path");
10565
+ var import_mini39 = require("zod/mini");
10364
10566
 
10365
10567
  // src/features/subagents/tool-subagent.ts
10366
10568
  var ToolSubagent = class extends ToolFile {
@@ -10412,9 +10614,9 @@ var ToolSubagent = class extends ToolFile {
10412
10614
  };
10413
10615
 
10414
10616
  // src/features/subagents/simulated-subagent.ts
10415
- var SimulatedSubagentFrontmatterSchema = import_mini38.z.object({
10416
- name: import_mini38.z.string(),
10417
- description: import_mini38.z.optional(import_mini38.z.string())
10617
+ var SimulatedSubagentFrontmatterSchema = import_mini39.z.object({
10618
+ name: import_mini39.z.string(),
10619
+ description: import_mini39.z.optional(import_mini39.z.string())
10418
10620
  });
10419
10621
  var SimulatedSubagent = class extends ToolSubagent {
10420
10622
  frontmatter;
@@ -10424,7 +10626,7 @@ var SimulatedSubagent = class extends ToolSubagent {
10424
10626
  const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
10425
10627
  if (!result.success) {
10426
10628
  throw new Error(
10427
- `Invalid frontmatter in ${(0, import_node_path76.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
10629
+ `Invalid frontmatter in ${(0, import_node_path77.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
10428
10630
  );
10429
10631
  }
10430
10632
  }
@@ -10475,7 +10677,7 @@ var SimulatedSubagent = class extends ToolSubagent {
10475
10677
  return {
10476
10678
  success: false,
10477
10679
  error: new Error(
10478
- `Invalid frontmatter in ${(0, import_node_path76.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10680
+ `Invalid frontmatter in ${(0, import_node_path77.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10479
10681
  )
10480
10682
  };
10481
10683
  }
@@ -10485,7 +10687,7 @@ var SimulatedSubagent = class extends ToolSubagent {
10485
10687
  relativeFilePath,
10486
10688
  validate = true
10487
10689
  }) {
10488
- const filePath = (0, import_node_path76.join)(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
10690
+ const filePath = (0, import_node_path77.join)(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
10489
10691
  const fileContent = await readFileContent(filePath);
10490
10692
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
10491
10693
  const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -10495,7 +10697,7 @@ var SimulatedSubagent = class extends ToolSubagent {
10495
10697
  return {
10496
10698
  baseDir,
10497
10699
  relativeDirPath: this.getSettablePaths().relativeDirPath,
10498
- relativeFilePath: (0, import_node_path76.basename)(relativeFilePath),
10700
+ relativeFilePath: (0, import_node_path77.basename)(relativeFilePath),
10499
10701
  frontmatter: result.data,
10500
10702
  body: content.trim(),
10501
10703
  validate
@@ -10521,7 +10723,7 @@ var SimulatedSubagent = class extends ToolSubagent {
10521
10723
  var AgentsmdSubagent = class _AgentsmdSubagent extends SimulatedSubagent {
10522
10724
  static getSettablePaths() {
10523
10725
  return {
10524
- relativeDirPath: (0, import_node_path77.join)(".agents", "subagents")
10726
+ relativeDirPath: (0, import_node_path78.join)(".agents", "subagents")
10525
10727
  };
10526
10728
  }
10527
10729
  static async fromFile(params) {
@@ -10544,11 +10746,11 @@ var AgentsmdSubagent = class _AgentsmdSubagent extends SimulatedSubagent {
10544
10746
  };
10545
10747
 
10546
10748
  // src/features/subagents/factorydroid-subagent.ts
10547
- var import_node_path78 = require("path");
10749
+ var import_node_path79 = require("path");
10548
10750
  var FactorydroidSubagent = class _FactorydroidSubagent extends SimulatedSubagent {
10549
10751
  static getSettablePaths(_options) {
10550
10752
  return {
10551
- relativeDirPath: (0, import_node_path78.join)(".factory", "droids")
10753
+ relativeDirPath: (0, import_node_path79.join)(".factory", "droids")
10552
10754
  };
10553
10755
  }
10554
10756
  static async fromFile(params) {
@@ -10571,11 +10773,11 @@ var FactorydroidSubagent = class _FactorydroidSubagent extends SimulatedSubagent
10571
10773
  };
10572
10774
 
10573
10775
  // src/features/subagents/geminicli-subagent.ts
10574
- var import_node_path79 = require("path");
10776
+ var import_node_path80 = require("path");
10575
10777
  var GeminiCliSubagent = class _GeminiCliSubagent extends SimulatedSubagent {
10576
10778
  static getSettablePaths() {
10577
10779
  return {
10578
- relativeDirPath: (0, import_node_path79.join)(".gemini", "subagents")
10780
+ relativeDirPath: (0, import_node_path80.join)(".gemini", "subagents")
10579
10781
  };
10580
10782
  }
10581
10783
  static async fromFile(params) {
@@ -10598,11 +10800,11 @@ var GeminiCliSubagent = class _GeminiCliSubagent extends SimulatedSubagent {
10598
10800
  };
10599
10801
 
10600
10802
  // src/features/subagents/roo-subagent.ts
10601
- var import_node_path80 = require("path");
10803
+ var import_node_path81 = require("path");
10602
10804
  var RooSubagent = class _RooSubagent extends SimulatedSubagent {
10603
10805
  static getSettablePaths() {
10604
10806
  return {
10605
- relativeDirPath: (0, import_node_path80.join)(".roo", "subagents")
10807
+ relativeDirPath: (0, import_node_path81.join)(".roo", "subagents")
10606
10808
  };
10607
10809
  }
10608
10810
  static async fromFile(params) {
@@ -10625,20 +10827,20 @@ var RooSubagent = class _RooSubagent extends SimulatedSubagent {
10625
10827
  };
10626
10828
 
10627
10829
  // src/features/subagents/subagents-processor.ts
10628
- var import_node_path88 = require("path");
10629
- var import_mini46 = require("zod/mini");
10830
+ var import_node_path90 = require("path");
10831
+ var import_mini48 = require("zod/mini");
10630
10832
 
10631
10833
  // src/features/subagents/claudecode-subagent.ts
10632
- var import_node_path82 = require("path");
10633
- var import_mini40 = require("zod/mini");
10834
+ var import_node_path83 = require("path");
10835
+ var import_mini41 = require("zod/mini");
10634
10836
 
10635
10837
  // src/features/subagents/rulesync-subagent.ts
10636
- var import_node_path81 = require("path");
10637
- var import_mini39 = require("zod/mini");
10638
- var RulesyncSubagentFrontmatterSchema = import_mini39.z.looseObject({
10639
- targets: import_mini39.z._default(RulesyncTargetsSchema, ["*"]),
10640
- name: import_mini39.z.string(),
10641
- description: import_mini39.z.optional(import_mini39.z.string())
10838
+ var import_node_path82 = require("path");
10839
+ var import_mini40 = require("zod/mini");
10840
+ var RulesyncSubagentFrontmatterSchema = import_mini40.z.looseObject({
10841
+ targets: import_mini40.z._default(RulesyncTargetsSchema, ["*"]),
10842
+ name: import_mini40.z.string(),
10843
+ description: import_mini40.z.optional(import_mini40.z.string())
10642
10844
  });
10643
10845
  var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
10644
10846
  frontmatter;
@@ -10647,7 +10849,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
10647
10849
  const parseResult = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
10648
10850
  if (!parseResult.success && rest.validate !== false) {
10649
10851
  throw new Error(
10650
- `Invalid frontmatter in ${(0, import_node_path81.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(parseResult.error)}`
10852
+ `Invalid frontmatter in ${(0, import_node_path82.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(parseResult.error)}`
10651
10853
  );
10652
10854
  }
10653
10855
  const parsedFrontmatter = parseResult.success ? { ...frontmatter, ...parseResult.data } : { ...frontmatter, targets: frontmatter?.targets ?? ["*"] };
@@ -10680,7 +10882,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
10680
10882
  return {
10681
10883
  success: false,
10682
10884
  error: new Error(
10683
- `Invalid frontmatter in ${(0, import_node_path81.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10885
+ `Invalid frontmatter in ${(0, import_node_path82.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10684
10886
  )
10685
10887
  };
10686
10888
  }
@@ -10688,14 +10890,14 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
10688
10890
  static async fromFile({
10689
10891
  relativeFilePath
10690
10892
  }) {
10691
- const filePath = (0, import_node_path81.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, relativeFilePath);
10893
+ const filePath = (0, import_node_path82.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, relativeFilePath);
10692
10894
  const fileContent = await readFileContent(filePath);
10693
10895
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
10694
10896
  const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
10695
10897
  if (!result.success) {
10696
10898
  throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${formatError(result.error)}`);
10697
10899
  }
10698
- const filename = (0, import_node_path81.basename)(relativeFilePath);
10900
+ const filename = (0, import_node_path82.basename)(relativeFilePath);
10699
10901
  return new _RulesyncSubagent({
10700
10902
  baseDir: process.cwd(),
10701
10903
  relativeDirPath: this.getSettablePaths().relativeDirPath,
@@ -10707,13 +10909,13 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
10707
10909
  };
10708
10910
 
10709
10911
  // src/features/subagents/claudecode-subagent.ts
10710
- var ClaudecodeSubagentFrontmatterSchema = import_mini40.z.looseObject({
10711
- name: import_mini40.z.string(),
10712
- description: import_mini40.z.optional(import_mini40.z.string()),
10713
- model: import_mini40.z.optional(import_mini40.z.string()),
10714
- tools: import_mini40.z.optional(import_mini40.z.union([import_mini40.z.string(), import_mini40.z.array(import_mini40.z.string())])),
10715
- permissionMode: import_mini40.z.optional(import_mini40.z.string()),
10716
- skills: import_mini40.z.optional(import_mini40.z.union([import_mini40.z.string(), import_mini40.z.array(import_mini40.z.string())]))
10912
+ var ClaudecodeSubagentFrontmatterSchema = import_mini41.z.looseObject({
10913
+ name: import_mini41.z.string(),
10914
+ description: import_mini41.z.optional(import_mini41.z.string()),
10915
+ model: import_mini41.z.optional(import_mini41.z.string()),
10916
+ tools: import_mini41.z.optional(import_mini41.z.union([import_mini41.z.string(), import_mini41.z.array(import_mini41.z.string())])),
10917
+ permissionMode: import_mini41.z.optional(import_mini41.z.string()),
10918
+ skills: import_mini41.z.optional(import_mini41.z.union([import_mini41.z.string(), import_mini41.z.array(import_mini41.z.string())]))
10717
10919
  });
10718
10920
  var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
10719
10921
  frontmatter;
@@ -10723,7 +10925,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
10723
10925
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
10724
10926
  if (!result.success) {
10725
10927
  throw new Error(
10726
- `Invalid frontmatter in ${(0, import_node_path82.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
10928
+ `Invalid frontmatter in ${(0, import_node_path83.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
10727
10929
  );
10728
10930
  }
10729
10931
  }
@@ -10735,7 +10937,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
10735
10937
  }
10736
10938
  static getSettablePaths(_options = {}) {
10737
10939
  return {
10738
- relativeDirPath: (0, import_node_path82.join)(".claude", "agents")
10940
+ relativeDirPath: (0, import_node_path83.join)(".claude", "agents")
10739
10941
  };
10740
10942
  }
10741
10943
  getFrontmatter() {
@@ -10774,7 +10976,10 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
10774
10976
  global = false
10775
10977
  }) {
10776
10978
  const rulesyncFrontmatter = rulesyncSubagent.getFrontmatter();
10777
- const claudecodeSection = rulesyncFrontmatter.claudecode ?? {};
10979
+ const claudecodeSection = this.filterToolSpecificSection(rulesyncFrontmatter.claudecode ?? {}, [
10980
+ "name",
10981
+ "description"
10982
+ ]);
10778
10983
  const rawClaudecodeFrontmatter = {
10779
10984
  name: rulesyncFrontmatter.name,
10780
10985
  description: rulesyncFrontmatter.description,
@@ -10811,7 +11016,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
10811
11016
  return {
10812
11017
  success: false,
10813
11018
  error: new Error(
10814
- `Invalid frontmatter in ${(0, import_node_path82.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
11019
+ `Invalid frontmatter in ${(0, import_node_path83.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
10815
11020
  )
10816
11021
  };
10817
11022
  }
@@ -10829,7 +11034,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
10829
11034
  global = false
10830
11035
  }) {
10831
11036
  const paths = this.getSettablePaths({ global });
10832
- const filePath = (0, import_node_path82.join)(baseDir, paths.relativeDirPath, relativeFilePath);
11037
+ const filePath = (0, import_node_path83.join)(baseDir, paths.relativeDirPath, relativeFilePath);
10833
11038
  const fileContent = await readFileContent(filePath);
10834
11039
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
10835
11040
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -10864,16 +11069,16 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
10864
11069
  };
10865
11070
 
10866
11071
  // src/features/subagents/codexcli-subagent.ts
10867
- var import_node_path83 = require("path");
11072
+ var import_node_path84 = require("path");
10868
11073
  var smolToml2 = __toESM(require("smol-toml"), 1);
10869
- var import_mini41 = require("zod/mini");
10870
- var CodexCliSubagentTomlSchema = import_mini41.z.looseObject({
10871
- name: import_mini41.z.string(),
10872
- description: import_mini41.z.optional(import_mini41.z.string()),
10873
- developer_instructions: import_mini41.z.optional(import_mini41.z.string()),
10874
- model: import_mini41.z.optional(import_mini41.z.string()),
10875
- model_reasoning_effort: import_mini41.z.optional(import_mini41.z.string()),
10876
- sandbox_mode: import_mini41.z.optional(import_mini41.z.string())
11074
+ var import_mini42 = require("zod/mini");
11075
+ var CodexCliSubagentTomlSchema = import_mini42.z.looseObject({
11076
+ name: import_mini42.z.string(),
11077
+ description: import_mini42.z.optional(import_mini42.z.string()),
11078
+ developer_instructions: import_mini42.z.optional(import_mini42.z.string()),
11079
+ model: import_mini42.z.optional(import_mini42.z.string()),
11080
+ model_reasoning_effort: import_mini42.z.optional(import_mini42.z.string()),
11081
+ sandbox_mode: import_mini42.z.optional(import_mini42.z.string())
10877
11082
  });
10878
11083
  var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
10879
11084
  body;
@@ -10884,7 +11089,7 @@ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
10884
11089
  CodexCliSubagentTomlSchema.parse(parsed);
10885
11090
  } catch (error) {
10886
11091
  throw new Error(
10887
- `Invalid TOML in ${(0, import_node_path83.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${error instanceof Error ? error.message : String(error)}`,
11092
+ `Invalid TOML in ${(0, import_node_path84.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${error instanceof Error ? error.message : String(error)}`,
10888
11093
  { cause: error }
10889
11094
  );
10890
11095
  }
@@ -10896,7 +11101,7 @@ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
10896
11101
  }
10897
11102
  static getSettablePaths(_options = {}) {
10898
11103
  return {
10899
- relativeDirPath: (0, import_node_path83.join)(".codex", "agents")
11104
+ relativeDirPath: (0, import_node_path84.join)(".codex", "agents")
10900
11105
  };
10901
11106
  }
10902
11107
  getBody() {
@@ -10908,7 +11113,7 @@ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
10908
11113
  parsed = CodexCliSubagentTomlSchema.parse(smolToml2.parse(this.body));
10909
11114
  } catch (error) {
10910
11115
  throw new Error(
10911
- `Failed to parse TOML in ${(0, import_node_path83.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${error instanceof Error ? error.message : String(error)}`,
11116
+ `Failed to parse TOML in ${(0, import_node_path84.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${error instanceof Error ? error.message : String(error)}`,
10912
11117
  { cause: error }
10913
11118
  );
10914
11119
  }
@@ -10989,7 +11194,7 @@ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
10989
11194
  global = false
10990
11195
  }) {
10991
11196
  const paths = this.getSettablePaths({ global });
10992
- const filePath = (0, import_node_path83.join)(baseDir, paths.relativeDirPath, relativeFilePath);
11197
+ const filePath = (0, import_node_path84.join)(baseDir, paths.relativeDirPath, relativeFilePath);
10993
11198
  const fileContent = await readFileContent(filePath);
10994
11199
  const subagent = new _CodexCliSubagent({
10995
11200
  baseDir,
@@ -11027,13 +11232,13 @@ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
11027
11232
  };
11028
11233
 
11029
11234
  // src/features/subagents/copilot-subagent.ts
11030
- var import_node_path84 = require("path");
11031
- var import_mini42 = require("zod/mini");
11235
+ var import_node_path85 = require("path");
11236
+ var import_mini43 = require("zod/mini");
11032
11237
  var REQUIRED_TOOL = "agent/runSubagent";
11033
- var CopilotSubagentFrontmatterSchema = import_mini42.z.looseObject({
11034
- name: import_mini42.z.string(),
11035
- description: import_mini42.z.optional(import_mini42.z.string()),
11036
- tools: import_mini42.z.optional(import_mini42.z.union([import_mini42.z.string(), import_mini42.z.array(import_mini42.z.string())]))
11238
+ var CopilotSubagentFrontmatterSchema = import_mini43.z.looseObject({
11239
+ name: import_mini43.z.string(),
11240
+ description: import_mini43.z.optional(import_mini43.z.string()),
11241
+ tools: import_mini43.z.optional(import_mini43.z.union([import_mini43.z.string(), import_mini43.z.array(import_mini43.z.string())]))
11037
11242
  });
11038
11243
  var normalizeTools = (tools) => {
11039
11244
  if (!tools) {
@@ -11053,7 +11258,7 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
11053
11258
  const result = CopilotSubagentFrontmatterSchema.safeParse(frontmatter);
11054
11259
  if (!result.success) {
11055
11260
  throw new Error(
11056
- `Invalid frontmatter in ${(0, import_node_path84.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
11261
+ `Invalid frontmatter in ${(0, import_node_path85.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
11057
11262
  );
11058
11263
  }
11059
11264
  }
@@ -11065,7 +11270,7 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
11065
11270
  }
11066
11271
  static getSettablePaths(_options = {}) {
11067
11272
  return {
11068
- relativeDirPath: (0, import_node_path84.join)(".github", "agents")
11273
+ relativeDirPath: (0, import_node_path85.join)(".github", "agents")
11069
11274
  };
11070
11275
  }
11071
11276
  getFrontmatter() {
@@ -11139,7 +11344,7 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
11139
11344
  return {
11140
11345
  success: false,
11141
11346
  error: new Error(
11142
- `Invalid frontmatter in ${(0, import_node_path84.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
11347
+ `Invalid frontmatter in ${(0, import_node_path85.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
11143
11348
  )
11144
11349
  };
11145
11350
  }
@@ -11157,7 +11362,7 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
11157
11362
  global = false
11158
11363
  }) {
11159
11364
  const paths = this.getSettablePaths({ global });
11160
- const filePath = (0, import_node_path84.join)(baseDir, paths.relativeDirPath, relativeFilePath);
11365
+ const filePath = (0, import_node_path85.join)(baseDir, paths.relativeDirPath, relativeFilePath);
11161
11366
  const fileContent = await readFileContent(filePath);
11162
11367
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
11163
11368
  const result = CopilotSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -11193,11 +11398,11 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
11193
11398
  };
11194
11399
 
11195
11400
  // src/features/subagents/cursor-subagent.ts
11196
- var import_node_path85 = require("path");
11197
- var import_mini43 = require("zod/mini");
11198
- var CursorSubagentFrontmatterSchema = import_mini43.z.looseObject({
11199
- name: import_mini43.z.string(),
11200
- description: import_mini43.z.optional(import_mini43.z.string())
11401
+ var import_node_path86 = require("path");
11402
+ var import_mini44 = require("zod/mini");
11403
+ var CursorSubagentFrontmatterSchema = import_mini44.z.looseObject({
11404
+ name: import_mini44.z.string(),
11405
+ description: import_mini44.z.optional(import_mini44.z.string())
11201
11406
  });
11202
11407
  var CursorSubagent = class _CursorSubagent extends ToolSubagent {
11203
11408
  frontmatter;
@@ -11207,7 +11412,7 @@ var CursorSubagent = class _CursorSubagent extends ToolSubagent {
11207
11412
  const result = CursorSubagentFrontmatterSchema.safeParse(frontmatter);
11208
11413
  if (!result.success) {
11209
11414
  throw new Error(
11210
- `Invalid frontmatter in ${(0, import_node_path85.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
11415
+ `Invalid frontmatter in ${(0, import_node_path86.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
11211
11416
  );
11212
11417
  }
11213
11418
  }
@@ -11219,7 +11424,7 @@ var CursorSubagent = class _CursorSubagent extends ToolSubagent {
11219
11424
  }
11220
11425
  static getSettablePaths(_options = {}) {
11221
11426
  return {
11222
- relativeDirPath: (0, import_node_path85.join)(".cursor", "agents")
11427
+ relativeDirPath: (0, import_node_path86.join)(".cursor", "agents")
11223
11428
  };
11224
11429
  }
11225
11430
  getFrontmatter() {
@@ -11286,7 +11491,7 @@ var CursorSubagent = class _CursorSubagent extends ToolSubagent {
11286
11491
  return {
11287
11492
  success: false,
11288
11493
  error: new Error(
11289
- `Invalid frontmatter in ${(0, import_node_path85.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
11494
+ `Invalid frontmatter in ${(0, import_node_path86.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
11290
11495
  )
11291
11496
  };
11292
11497
  }
@@ -11304,7 +11509,7 @@ var CursorSubagent = class _CursorSubagent extends ToolSubagent {
11304
11509
  global = false
11305
11510
  }) {
11306
11511
  const paths = this.getSettablePaths({ global });
11307
- const filePath = (0, import_node_path85.join)(baseDir, paths.relativeDirPath, relativeFilePath);
11512
+ const filePath = (0, import_node_path86.join)(baseDir, paths.relativeDirPath, relativeFilePath);
11308
11513
  const fileContent = await readFileContent(filePath);
11309
11514
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
11310
11515
  const result = CursorSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -11339,24 +11544,182 @@ var CursorSubagent = class _CursorSubagent extends ToolSubagent {
11339
11544
  }
11340
11545
  };
11341
11546
 
11547
+ // src/features/subagents/junie-subagent.ts
11548
+ var import_node_path87 = require("path");
11549
+ var import_mini45 = require("zod/mini");
11550
+ var JunieSubagentFrontmatterSchema = import_mini45.z.looseObject({
11551
+ name: import_mini45.z.optional(import_mini45.z.string()),
11552
+ description: import_mini45.z.string()
11553
+ });
11554
+ var JunieSubagent = class _JunieSubagent extends ToolSubagent {
11555
+ frontmatter;
11556
+ body;
11557
+ constructor({ frontmatter, body, ...rest }) {
11558
+ if (rest.validate !== false) {
11559
+ const result = JunieSubagentFrontmatterSchema.safeParse(frontmatter);
11560
+ if (!result.success) {
11561
+ throw new Error(
11562
+ `Invalid frontmatter in ${(0, import_node_path87.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
11563
+ );
11564
+ }
11565
+ }
11566
+ super({
11567
+ ...rest
11568
+ });
11569
+ this.frontmatter = frontmatter;
11570
+ this.body = body;
11571
+ }
11572
+ static getSettablePaths(options = {}) {
11573
+ if (options?.global) {
11574
+ throw new Error("JunieSubagent does not support global mode.");
11575
+ }
11576
+ return {
11577
+ relativeDirPath: (0, import_node_path87.join)(".junie", "agents")
11578
+ };
11579
+ }
11580
+ getFrontmatter() {
11581
+ return this.frontmatter;
11582
+ }
11583
+ getBody() {
11584
+ return this.body;
11585
+ }
11586
+ toRulesyncSubagent() {
11587
+ const { name, description, ...restFields } = this.frontmatter;
11588
+ const junieSection = {
11589
+ ...restFields
11590
+ };
11591
+ const rulesyncFrontmatter = {
11592
+ targets: ["*"],
11593
+ name: name ?? this.getRelativeFilePath().replace(/\.md$/, ""),
11594
+ description,
11595
+ ...Object.keys(junieSection).length > 0 && { junie: junieSection }
11596
+ };
11597
+ return new RulesyncSubagent({
11598
+ baseDir: ".",
11599
+ frontmatter: rulesyncFrontmatter,
11600
+ body: this.body,
11601
+ relativeDirPath: RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH,
11602
+ relativeFilePath: this.getRelativeFilePath(),
11603
+ validate: true
11604
+ });
11605
+ }
11606
+ static fromRulesyncSubagent({
11607
+ baseDir = process.cwd(),
11608
+ rulesyncSubagent,
11609
+ validate = true,
11610
+ global = false
11611
+ }) {
11612
+ const rulesyncFrontmatter = rulesyncSubagent.getFrontmatter();
11613
+ const junieSection = this.filterToolSpecificSection(rulesyncFrontmatter.junie ?? {}, [
11614
+ "name",
11615
+ "description"
11616
+ ]);
11617
+ const rawJunieFrontmatter = {
11618
+ name: rulesyncFrontmatter.name,
11619
+ description: rulesyncFrontmatter.description,
11620
+ ...junieSection
11621
+ };
11622
+ const result = JunieSubagentFrontmatterSchema.safeParse(rawJunieFrontmatter);
11623
+ if (!result.success) {
11624
+ throw new Error(
11625
+ `Invalid junie subagent frontmatter in ${rulesyncSubagent.getRelativeFilePath()}: ${formatError(result.error)}`
11626
+ );
11627
+ }
11628
+ const junieFrontmatter = result.data;
11629
+ const body = rulesyncSubagent.getBody();
11630
+ const fileContent = stringifyFrontmatter(body, junieFrontmatter);
11631
+ const paths = this.getSettablePaths({ global });
11632
+ return new _JunieSubagent({
11633
+ baseDir,
11634
+ frontmatter: junieFrontmatter,
11635
+ body,
11636
+ relativeDirPath: paths.relativeDirPath,
11637
+ relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
11638
+ fileContent,
11639
+ validate
11640
+ });
11641
+ }
11642
+ validate() {
11643
+ if (!this.frontmatter) {
11644
+ return { success: true, error: null };
11645
+ }
11646
+ const result = JunieSubagentFrontmatterSchema.safeParse(this.frontmatter);
11647
+ if (result.success) {
11648
+ return { success: true, error: null };
11649
+ } else {
11650
+ return {
11651
+ success: false,
11652
+ error: new Error(
11653
+ `Invalid frontmatter in ${(0, import_node_path87.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
11654
+ )
11655
+ };
11656
+ }
11657
+ }
11658
+ static isTargetedByRulesyncSubagent(rulesyncSubagent) {
11659
+ return this.isTargetedByRulesyncSubagentDefault({
11660
+ rulesyncSubagent,
11661
+ toolTarget: "junie"
11662
+ });
11663
+ }
11664
+ static async fromFile({
11665
+ baseDir = process.cwd(),
11666
+ relativeFilePath,
11667
+ validate = true,
11668
+ global = false
11669
+ }) {
11670
+ const paths = this.getSettablePaths({ global });
11671
+ const filePath = (0, import_node_path87.join)(baseDir, paths.relativeDirPath, relativeFilePath);
11672
+ const fileContent = await readFileContent(filePath);
11673
+ const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
11674
+ const result = JunieSubagentFrontmatterSchema.safeParse(frontmatter);
11675
+ if (!result.success) {
11676
+ throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
11677
+ }
11678
+ return new _JunieSubagent({
11679
+ baseDir,
11680
+ relativeDirPath: paths.relativeDirPath,
11681
+ relativeFilePath,
11682
+ frontmatter: result.data,
11683
+ body: content.trim(),
11684
+ fileContent,
11685
+ validate
11686
+ });
11687
+ }
11688
+ static forDeletion({
11689
+ baseDir = process.cwd(),
11690
+ relativeDirPath,
11691
+ relativeFilePath
11692
+ }) {
11693
+ return new _JunieSubagent({
11694
+ baseDir,
11695
+ relativeDirPath,
11696
+ relativeFilePath,
11697
+ frontmatter: { name: "", description: "" },
11698
+ body: "",
11699
+ fileContent: "",
11700
+ validate: false
11701
+ });
11702
+ }
11703
+ };
11704
+
11342
11705
  // src/features/subagents/kiro-subagent.ts
11343
- var import_node_path86 = require("path");
11344
- var import_mini44 = require("zod/mini");
11345
- var KiroCliSubagentJsonSchema = import_mini44.z.looseObject({
11346
- name: import_mini44.z.string(),
11347
- description: import_mini44.z.optional(import_mini44.z.nullable(import_mini44.z.string())),
11348
- prompt: import_mini44.z.optional(import_mini44.z.nullable(import_mini44.z.string())),
11349
- tools: import_mini44.z.optional(import_mini44.z.nullable(import_mini44.z.array(import_mini44.z.string()))),
11350
- toolAliases: import_mini44.z.optional(import_mini44.z.nullable(import_mini44.z.record(import_mini44.z.string(), import_mini44.z.string()))),
11351
- toolSettings: import_mini44.z.optional(import_mini44.z.nullable(import_mini44.z.unknown())),
11352
- toolSchema: import_mini44.z.optional(import_mini44.z.nullable(import_mini44.z.unknown())),
11353
- hooks: import_mini44.z.optional(import_mini44.z.nullable(import_mini44.z.record(import_mini44.z.string(), import_mini44.z.array(import_mini44.z.unknown())))),
11354
- model: import_mini44.z.optional(import_mini44.z.nullable(import_mini44.z.string())),
11355
- mcpServers: import_mini44.z.optional(import_mini44.z.nullable(import_mini44.z.record(import_mini44.z.string(), import_mini44.z.unknown()))),
11356
- useLegacyMcpJson: import_mini44.z.optional(import_mini44.z.nullable(import_mini44.z.boolean())),
11357
- resources: import_mini44.z.optional(import_mini44.z.nullable(import_mini44.z.array(import_mini44.z.string()))),
11358
- allowedTools: import_mini44.z.optional(import_mini44.z.nullable(import_mini44.z.array(import_mini44.z.string()))),
11359
- includeMcpJson: import_mini44.z.optional(import_mini44.z.nullable(import_mini44.z.boolean()))
11706
+ var import_node_path88 = require("path");
11707
+ var import_mini46 = require("zod/mini");
11708
+ var KiroCliSubagentJsonSchema = import_mini46.z.looseObject({
11709
+ name: import_mini46.z.string(),
11710
+ description: import_mini46.z.optional(import_mini46.z.nullable(import_mini46.z.string())),
11711
+ prompt: import_mini46.z.optional(import_mini46.z.nullable(import_mini46.z.string())),
11712
+ tools: import_mini46.z.optional(import_mini46.z.nullable(import_mini46.z.array(import_mini46.z.string()))),
11713
+ toolAliases: import_mini46.z.optional(import_mini46.z.nullable(import_mini46.z.record(import_mini46.z.string(), import_mini46.z.string()))),
11714
+ toolSettings: import_mini46.z.optional(import_mini46.z.nullable(import_mini46.z.unknown())),
11715
+ toolSchema: import_mini46.z.optional(import_mini46.z.nullable(import_mini46.z.unknown())),
11716
+ hooks: import_mini46.z.optional(import_mini46.z.nullable(import_mini46.z.record(import_mini46.z.string(), import_mini46.z.array(import_mini46.z.unknown())))),
11717
+ model: import_mini46.z.optional(import_mini46.z.nullable(import_mini46.z.string())),
11718
+ mcpServers: import_mini46.z.optional(import_mini46.z.nullable(import_mini46.z.record(import_mini46.z.string(), import_mini46.z.unknown()))),
11719
+ useLegacyMcpJson: import_mini46.z.optional(import_mini46.z.nullable(import_mini46.z.boolean())),
11720
+ resources: import_mini46.z.optional(import_mini46.z.nullable(import_mini46.z.array(import_mini46.z.string()))),
11721
+ allowedTools: import_mini46.z.optional(import_mini46.z.nullable(import_mini46.z.array(import_mini46.z.string()))),
11722
+ includeMcpJson: import_mini46.z.optional(import_mini46.z.nullable(import_mini46.z.boolean()))
11360
11723
  });
11361
11724
  var KiroSubagent = class _KiroSubagent extends ToolSubagent {
11362
11725
  body;
@@ -11367,7 +11730,7 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
11367
11730
  KiroCliSubagentJsonSchema.parse(parsed);
11368
11731
  } catch (error) {
11369
11732
  throw new Error(
11370
- `Invalid JSON in ${(0, import_node_path86.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${error instanceof Error ? error.message : String(error)}`,
11733
+ `Invalid JSON in ${(0, import_node_path88.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${error instanceof Error ? error.message : String(error)}`,
11371
11734
  { cause: error }
11372
11735
  );
11373
11736
  }
@@ -11379,7 +11742,7 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
11379
11742
  }
11380
11743
  static getSettablePaths(_options = {}) {
11381
11744
  return {
11382
- relativeDirPath: (0, import_node_path86.join)(".kiro", "agents")
11745
+ relativeDirPath: (0, import_node_path88.join)(".kiro", "agents")
11383
11746
  };
11384
11747
  }
11385
11748
  getBody() {
@@ -11391,7 +11754,7 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
11391
11754
  parsed = JSON.parse(this.body);
11392
11755
  } catch (error) {
11393
11756
  throw new Error(
11394
- `Failed to parse JSON in ${(0, import_node_path86.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${error instanceof Error ? error.message : String(error)}`,
11757
+ `Failed to parse JSON in ${(0, import_node_path88.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${error instanceof Error ? error.message : String(error)}`,
11395
11758
  { cause: error }
11396
11759
  );
11397
11760
  }
@@ -11472,7 +11835,7 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
11472
11835
  global = false
11473
11836
  }) {
11474
11837
  const paths = this.getSettablePaths({ global });
11475
- const filePath = (0, import_node_path86.join)(baseDir, paths.relativeDirPath, relativeFilePath);
11838
+ const filePath = (0, import_node_path88.join)(baseDir, paths.relativeDirPath, relativeFilePath);
11476
11839
  const fileContent = await readFileContent(filePath);
11477
11840
  const subagent = new _KiroSubagent({
11478
11841
  baseDir,
@@ -11510,12 +11873,12 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
11510
11873
  };
11511
11874
 
11512
11875
  // src/features/subagents/opencode-subagent.ts
11513
- var import_node_path87 = require("path");
11514
- var import_mini45 = require("zod/mini");
11515
- var OpenCodeSubagentFrontmatterSchema = import_mini45.z.looseObject({
11516
- description: import_mini45.z.optional(import_mini45.z.string()),
11517
- mode: import_mini45.z._default(import_mini45.z.string(), "subagent"),
11518
- name: import_mini45.z.optional(import_mini45.z.string())
11876
+ var import_node_path89 = require("path");
11877
+ var import_mini47 = require("zod/mini");
11878
+ var OpenCodeSubagentFrontmatterSchema = import_mini47.z.looseObject({
11879
+ description: import_mini47.z.optional(import_mini47.z.string()),
11880
+ mode: import_mini47.z._default(import_mini47.z.string(), "subagent"),
11881
+ name: import_mini47.z.optional(import_mini47.z.string())
11519
11882
  });
11520
11883
  var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
11521
11884
  frontmatter;
@@ -11525,7 +11888,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
11525
11888
  const result = OpenCodeSubagentFrontmatterSchema.safeParse(frontmatter);
11526
11889
  if (!result.success) {
11527
11890
  throw new Error(
11528
- `Invalid frontmatter in ${(0, import_node_path87.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
11891
+ `Invalid frontmatter in ${(0, import_node_path89.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
11529
11892
  );
11530
11893
  }
11531
11894
  }
@@ -11539,7 +11902,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
11539
11902
  global = false
11540
11903
  } = {}) {
11541
11904
  return {
11542
- relativeDirPath: global ? (0, import_node_path87.join)(".config", "opencode", "agent") : (0, import_node_path87.join)(".opencode", "agent")
11905
+ relativeDirPath: global ? (0, import_node_path89.join)(".config", "opencode", "agent") : (0, import_node_path89.join)(".opencode", "agent")
11543
11906
  };
11544
11907
  }
11545
11908
  getFrontmatter() {
@@ -11552,7 +11915,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
11552
11915
  const { description, mode, name, ...opencodeSection } = this.frontmatter;
11553
11916
  const rulesyncFrontmatter = {
11554
11917
  targets: ["*"],
11555
- name: name ?? (0, import_node_path87.basename)(this.getRelativeFilePath(), ".md"),
11918
+ name: name ?? (0, import_node_path89.basename)(this.getRelativeFilePath(), ".md"),
11556
11919
  description,
11557
11920
  opencode: { mode, ...opencodeSection }
11558
11921
  };
@@ -11605,7 +11968,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
11605
11968
  return {
11606
11969
  success: false,
11607
11970
  error: new Error(
11608
- `Invalid frontmatter in ${(0, import_node_path87.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
11971
+ `Invalid frontmatter in ${(0, import_node_path89.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
11609
11972
  )
11610
11973
  };
11611
11974
  }
@@ -11622,7 +11985,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
11622
11985
  global = false
11623
11986
  }) {
11624
11987
  const paths = this.getSettablePaths({ global });
11625
- const filePath = (0, import_node_path87.join)(baseDir, paths.relativeDirPath, relativeFilePath);
11988
+ const filePath = (0, import_node_path89.join)(baseDir, paths.relativeDirPath, relativeFilePath);
11626
11989
  const fileContent = await readFileContent(filePath);
11627
11990
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
11628
11991
  const result = OpenCodeSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -11667,11 +12030,12 @@ var subagentsProcessorToolTargetTuple = [
11667
12030
  "cursor",
11668
12031
  "factorydroid",
11669
12032
  "geminicli",
12033
+ "junie",
11670
12034
  "kiro",
11671
12035
  "opencode",
11672
12036
  "roo"
11673
12037
  ];
11674
- var SubagentsProcessorToolTargetSchema = import_mini46.z.enum(subagentsProcessorToolTargetTuple);
12038
+ var SubagentsProcessorToolTargetSchema = import_mini48.z.enum(subagentsProcessorToolTargetTuple);
11675
12039
  var toolSubagentFactories = /* @__PURE__ */ new Map([
11676
12040
  [
11677
12041
  "agentsmd",
@@ -11729,6 +12093,13 @@ var toolSubagentFactories = /* @__PURE__ */ new Map([
11729
12093
  meta: { supportsSimulated: true, supportsGlobal: false, filePattern: "*.md" }
11730
12094
  }
11731
12095
  ],
12096
+ [
12097
+ "junie",
12098
+ {
12099
+ class: JunieSubagent,
12100
+ meta: { supportsSimulated: false, supportsGlobal: false, filePattern: "*.md" }
12101
+ }
12102
+ ],
11732
12103
  [
11733
12104
  "kiro",
11734
12105
  {
@@ -11833,7 +12204,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
11833
12204
  * Load and parse rulesync subagent files from .rulesync/subagents/ directory
11834
12205
  */
11835
12206
  async loadRulesyncFiles() {
11836
- const subagentsDir = (0, import_node_path88.join)(process.cwd(), RulesyncSubagent.getSettablePaths().relativeDirPath);
12207
+ const subagentsDir = (0, import_node_path90.join)(process.cwd(), RulesyncSubagent.getSettablePaths().relativeDirPath);
11837
12208
  const dirExists = await directoryExists(subagentsDir);
11838
12209
  if (!dirExists) {
11839
12210
  logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
@@ -11848,7 +12219,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
11848
12219
  logger.debug(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
11849
12220
  const rulesyncSubagents = [];
11850
12221
  for (const mdFile of mdFiles) {
11851
- const filepath = (0, import_node_path88.join)(subagentsDir, mdFile);
12222
+ const filepath = (0, import_node_path90.join)(subagentsDir, mdFile);
11852
12223
  try {
11853
12224
  const rulesyncSubagent = await RulesyncSubagent.fromFile({
11854
12225
  relativeFilePath: mdFile,
@@ -11878,14 +12249,14 @@ var SubagentsProcessor = class extends FeatureProcessor {
11878
12249
  const factory = this.getFactory(this.toolTarget);
11879
12250
  const paths = factory.class.getSettablePaths({ global: this.global });
11880
12251
  const subagentFilePaths = await findFilesByGlobs(
11881
- (0, import_node_path88.join)(this.baseDir, paths.relativeDirPath, factory.meta.filePattern)
12252
+ (0, import_node_path90.join)(this.baseDir, paths.relativeDirPath, factory.meta.filePattern)
11882
12253
  );
11883
12254
  if (forDeletion) {
11884
12255
  const toolSubagents2 = subagentFilePaths.map(
11885
12256
  (path4) => factory.class.forDeletion({
11886
12257
  baseDir: this.baseDir,
11887
12258
  relativeDirPath: paths.relativeDirPath,
11888
- relativeFilePath: (0, import_node_path88.basename)(path4),
12259
+ relativeFilePath: (0, import_node_path90.basename)(path4),
11889
12260
  global: this.global
11890
12261
  })
11891
12262
  ).filter((subagent) => subagent.isDeletable());
@@ -11898,7 +12269,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
11898
12269
  subagentFilePaths.map(
11899
12270
  (path4) => factory.class.fromFile({
11900
12271
  baseDir: this.baseDir,
11901
- relativeFilePath: (0, import_node_path88.basename)(path4),
12272
+ relativeFilePath: (0, import_node_path90.basename)(path4),
11902
12273
  global: this.global
11903
12274
  })
11904
12275
  )
@@ -11943,49 +12314,49 @@ var SubagentsProcessor = class extends FeatureProcessor {
11943
12314
  };
11944
12315
 
11945
12316
  // src/features/rules/agentsmd-rule.ts
11946
- var import_node_path91 = require("path");
12317
+ var import_node_path93 = require("path");
11947
12318
 
11948
12319
  // src/features/rules/tool-rule.ts
11949
- var import_node_path90 = require("path");
12320
+ var import_node_path92 = require("path");
11950
12321
 
11951
12322
  // src/features/rules/rulesync-rule.ts
11952
- var import_node_path89 = require("path");
11953
- var import_mini47 = require("zod/mini");
11954
- var RulesyncRuleFrontmatterSchema = import_mini47.z.object({
11955
- root: import_mini47.z.optional(import_mini47.z.boolean()),
11956
- localRoot: import_mini47.z.optional(import_mini47.z.boolean()),
11957
- targets: import_mini47.z._default(RulesyncTargetsSchema, ["*"]),
11958
- description: import_mini47.z.optional(import_mini47.z.string()),
11959
- globs: import_mini47.z.optional(import_mini47.z.array(import_mini47.z.string())),
11960
- agentsmd: import_mini47.z.optional(
11961
- import_mini47.z.object({
12323
+ var import_node_path91 = require("path");
12324
+ var import_mini49 = require("zod/mini");
12325
+ var RulesyncRuleFrontmatterSchema = import_mini49.z.object({
12326
+ root: import_mini49.z.optional(import_mini49.z.boolean()),
12327
+ localRoot: import_mini49.z.optional(import_mini49.z.boolean()),
12328
+ targets: import_mini49.z._default(RulesyncTargetsSchema, ["*"]),
12329
+ description: import_mini49.z.optional(import_mini49.z.string()),
12330
+ globs: import_mini49.z.optional(import_mini49.z.array(import_mini49.z.string())),
12331
+ agentsmd: import_mini49.z.optional(
12332
+ import_mini49.z.object({
11962
12333
  // @example "path/to/subproject"
11963
- subprojectPath: import_mini47.z.optional(import_mini47.z.string())
12334
+ subprojectPath: import_mini49.z.optional(import_mini49.z.string())
11964
12335
  })
11965
12336
  ),
11966
- claudecode: import_mini47.z.optional(
11967
- import_mini47.z.object({
12337
+ claudecode: import_mini49.z.optional(
12338
+ import_mini49.z.object({
11968
12339
  // Glob patterns for conditional rules (takes precedence over globs)
11969
12340
  // @example ["src/**/*.ts", "tests/**/*.test.ts"]
11970
- paths: import_mini47.z.optional(import_mini47.z.array(import_mini47.z.string()))
12341
+ paths: import_mini49.z.optional(import_mini49.z.array(import_mini49.z.string()))
11971
12342
  })
11972
12343
  ),
11973
- cursor: import_mini47.z.optional(
11974
- import_mini47.z.object({
11975
- alwaysApply: import_mini47.z.optional(import_mini47.z.boolean()),
11976
- description: import_mini47.z.optional(import_mini47.z.string()),
11977
- globs: import_mini47.z.optional(import_mini47.z.array(import_mini47.z.string()))
12344
+ cursor: import_mini49.z.optional(
12345
+ import_mini49.z.object({
12346
+ alwaysApply: import_mini49.z.optional(import_mini49.z.boolean()),
12347
+ description: import_mini49.z.optional(import_mini49.z.string()),
12348
+ globs: import_mini49.z.optional(import_mini49.z.array(import_mini49.z.string()))
11978
12349
  })
11979
12350
  ),
11980
- copilot: import_mini47.z.optional(
11981
- import_mini47.z.object({
11982
- excludeAgent: import_mini47.z.optional(import_mini47.z.union([import_mini47.z.literal("code-review"), import_mini47.z.literal("coding-agent")]))
12351
+ copilot: import_mini49.z.optional(
12352
+ import_mini49.z.object({
12353
+ excludeAgent: import_mini49.z.optional(import_mini49.z.union([import_mini49.z.literal("code-review"), import_mini49.z.literal("coding-agent")]))
11983
12354
  })
11984
12355
  ),
11985
- antigravity: import_mini47.z.optional(
11986
- import_mini47.z.looseObject({
11987
- trigger: import_mini47.z.optional(import_mini47.z.string()),
11988
- globs: import_mini47.z.optional(import_mini47.z.array(import_mini47.z.string()))
12356
+ antigravity: import_mini49.z.optional(
12357
+ import_mini49.z.looseObject({
12358
+ trigger: import_mini49.z.optional(import_mini49.z.string()),
12359
+ globs: import_mini49.z.optional(import_mini49.z.array(import_mini49.z.string()))
11989
12360
  })
11990
12361
  )
11991
12362
  });
@@ -11996,7 +12367,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
11996
12367
  const parseResult = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
11997
12368
  if (!parseResult.success && rest.validate !== false) {
11998
12369
  throw new Error(
11999
- `Invalid frontmatter in ${(0, import_node_path89.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(parseResult.error)}`
12370
+ `Invalid frontmatter in ${(0, import_node_path91.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(parseResult.error)}`
12000
12371
  );
12001
12372
  }
12002
12373
  const parsedFrontmatter = parseResult.success ? parseResult.data : { ...frontmatter, targets: frontmatter.targets ?? ["*"] };
@@ -12031,7 +12402,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
12031
12402
  return {
12032
12403
  success: false,
12033
12404
  error: new Error(
12034
- `Invalid frontmatter in ${(0, import_node_path89.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
12405
+ `Invalid frontmatter in ${(0, import_node_path91.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
12035
12406
  )
12036
12407
  };
12037
12408
  }
@@ -12040,7 +12411,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
12040
12411
  relativeFilePath,
12041
12412
  validate = true
12042
12413
  }) {
12043
- const filePath = (0, import_node_path89.join)(
12414
+ const filePath = (0, import_node_path91.join)(
12044
12415
  process.cwd(),
12045
12416
  this.getSettablePaths().recommended.relativeDirPath,
12046
12417
  relativeFilePath
@@ -12142,7 +12513,7 @@ var ToolRule = class extends ToolFile {
12142
12513
  rulesyncRule,
12143
12514
  validate = true,
12144
12515
  rootPath = { relativeDirPath: ".", relativeFilePath: "AGENTS.md" },
12145
- nonRootPath = { relativeDirPath: (0, import_node_path90.join)(".agents", "memories") }
12516
+ nonRootPath = { relativeDirPath: (0, import_node_path92.join)(".agents", "memories") }
12146
12517
  }) {
12147
12518
  const params = this.buildToolRuleParamsDefault({
12148
12519
  baseDir,
@@ -12153,7 +12524,7 @@ var ToolRule = class extends ToolFile {
12153
12524
  });
12154
12525
  const rulesyncFrontmatter = rulesyncRule.getFrontmatter();
12155
12526
  if (!rulesyncFrontmatter.root && rulesyncFrontmatter.agentsmd?.subprojectPath) {
12156
- params.relativeDirPath = (0, import_node_path90.join)(rulesyncFrontmatter.agentsmd.subprojectPath);
12527
+ params.relativeDirPath = (0, import_node_path92.join)(rulesyncFrontmatter.agentsmd.subprojectPath);
12157
12528
  params.relativeFilePath = "AGENTS.md";
12158
12529
  }
12159
12530
  return params;
@@ -12202,7 +12573,7 @@ var ToolRule = class extends ToolFile {
12202
12573
  }
12203
12574
  };
12204
12575
  function buildToolPath(toolDir, subDir, excludeToolDir) {
12205
- return excludeToolDir ? subDir : (0, import_node_path90.join)(toolDir, subDir);
12576
+ return excludeToolDir ? subDir : (0, import_node_path92.join)(toolDir, subDir);
12206
12577
  }
12207
12578
 
12208
12579
  // src/features/rules/agentsmd-rule.ts
@@ -12231,8 +12602,8 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
12231
12602
  validate = true
12232
12603
  }) {
12233
12604
  const isRoot = relativeFilePath === "AGENTS.md";
12234
- const relativePath = isRoot ? "AGENTS.md" : (0, import_node_path91.join)(".agents", "memories", relativeFilePath);
12235
- const fileContent = await readFileContent((0, import_node_path91.join)(baseDir, relativePath));
12605
+ const relativePath = isRoot ? "AGENTS.md" : (0, import_node_path93.join)(".agents", "memories", relativeFilePath);
12606
+ const fileContent = await readFileContent((0, import_node_path93.join)(baseDir, relativePath));
12236
12607
  return new _AgentsMdRule({
12237
12608
  baseDir,
12238
12609
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -12287,21 +12658,21 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
12287
12658
  };
12288
12659
 
12289
12660
  // src/features/rules/antigravity-rule.ts
12290
- var import_node_path92 = require("path");
12291
- var import_mini48 = require("zod/mini");
12292
- var AntigravityRuleFrontmatterSchema = import_mini48.z.looseObject({
12293
- trigger: import_mini48.z.optional(
12294
- import_mini48.z.union([
12295
- import_mini48.z.literal("always_on"),
12296
- import_mini48.z.literal("glob"),
12297
- import_mini48.z.literal("manual"),
12298
- import_mini48.z.literal("model_decision"),
12299
- import_mini48.z.string()
12661
+ var import_node_path94 = require("path");
12662
+ var import_mini50 = require("zod/mini");
12663
+ var AntigravityRuleFrontmatterSchema = import_mini50.z.looseObject({
12664
+ trigger: import_mini50.z.optional(
12665
+ import_mini50.z.union([
12666
+ import_mini50.z.literal("always_on"),
12667
+ import_mini50.z.literal("glob"),
12668
+ import_mini50.z.literal("manual"),
12669
+ import_mini50.z.literal("model_decision"),
12670
+ import_mini50.z.string()
12300
12671
  // accepts any string for forward compatibility
12301
12672
  ])
12302
12673
  ),
12303
- globs: import_mini48.z.optional(import_mini48.z.string()),
12304
- description: import_mini48.z.optional(import_mini48.z.string())
12674
+ globs: import_mini50.z.optional(import_mini50.z.string()),
12675
+ description: import_mini50.z.optional(import_mini50.z.string())
12305
12676
  });
12306
12677
  function parseGlobsString(globs) {
12307
12678
  if (!globs) {
@@ -12446,7 +12817,7 @@ var AntigravityRule = class _AntigravityRule extends ToolRule {
12446
12817
  const result = AntigravityRuleFrontmatterSchema.safeParse(frontmatter);
12447
12818
  if (!result.success) {
12448
12819
  throw new Error(
12449
- `Invalid frontmatter in ${(0, import_node_path92.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
12820
+ `Invalid frontmatter in ${(0, import_node_path94.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
12450
12821
  );
12451
12822
  }
12452
12823
  }
@@ -12470,7 +12841,7 @@ var AntigravityRule = class _AntigravityRule extends ToolRule {
12470
12841
  relativeFilePath,
12471
12842
  validate = true
12472
12843
  }) {
12473
- const filePath = (0, import_node_path92.join)(
12844
+ const filePath = (0, import_node_path94.join)(
12474
12845
  baseDir,
12475
12846
  this.getSettablePaths().nonRoot.relativeDirPath,
12476
12847
  relativeFilePath
@@ -12610,7 +12981,7 @@ var AntigravityRule = class _AntigravityRule extends ToolRule {
12610
12981
  };
12611
12982
 
12612
12983
  // src/features/rules/augmentcode-legacy-rule.ts
12613
- var import_node_path93 = require("path");
12984
+ var import_node_path95 = require("path");
12614
12985
  var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
12615
12986
  toRulesyncRule() {
12616
12987
  const rulesyncFrontmatter = {
@@ -12670,8 +13041,8 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
12670
13041
  }) {
12671
13042
  const settablePaths = this.getSettablePaths();
12672
13043
  const isRoot = relativeFilePath === settablePaths.root.relativeFilePath;
12673
- const relativePath = isRoot ? settablePaths.root.relativeFilePath : (0, import_node_path93.join)(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
12674
- const fileContent = await readFileContent((0, import_node_path93.join)(baseDir, relativePath));
13044
+ const relativePath = isRoot ? settablePaths.root.relativeFilePath : (0, import_node_path95.join)(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
13045
+ const fileContent = await readFileContent((0, import_node_path95.join)(baseDir, relativePath));
12675
13046
  return new _AugmentcodeLegacyRule({
12676
13047
  baseDir,
12677
13048
  relativeDirPath: isRoot ? settablePaths.root.relativeDirPath : settablePaths.nonRoot.relativeDirPath,
@@ -12700,7 +13071,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
12700
13071
  };
12701
13072
 
12702
13073
  // src/features/rules/augmentcode-rule.ts
12703
- var import_node_path94 = require("path");
13074
+ var import_node_path96 = require("path");
12704
13075
  var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
12705
13076
  toRulesyncRule() {
12706
13077
  return this.toRulesyncRuleDefault();
@@ -12731,7 +13102,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
12731
13102
  relativeFilePath,
12732
13103
  validate = true
12733
13104
  }) {
12734
- const filePath = (0, import_node_path94.join)(
13105
+ const filePath = (0, import_node_path96.join)(
12735
13106
  baseDir,
12736
13107
  this.getSettablePaths().nonRoot.relativeDirPath,
12737
13108
  relativeFilePath
@@ -12771,7 +13142,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
12771
13142
  };
12772
13143
 
12773
13144
  // src/features/rules/claudecode-legacy-rule.ts
12774
- var import_node_path95 = require("path");
13145
+ var import_node_path97 = require("path");
12775
13146
  var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
12776
13147
  static getSettablePaths({
12777
13148
  global,
@@ -12813,7 +13184,7 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
12813
13184
  if (isRoot) {
12814
13185
  const rootDirPath = overrideDirPath ?? paths.root.relativeDirPath;
12815
13186
  const fileContent2 = await readFileContent(
12816
- (0, import_node_path95.join)(baseDir, rootDirPath, paths.root.relativeFilePath)
13187
+ (0, import_node_path97.join)(baseDir, rootDirPath, paths.root.relativeFilePath)
12817
13188
  );
12818
13189
  return new _ClaudecodeLegacyRule({
12819
13190
  baseDir,
@@ -12827,8 +13198,8 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
12827
13198
  if (!paths.nonRoot) {
12828
13199
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
12829
13200
  }
12830
- const relativePath = (0, import_node_path95.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
12831
- const fileContent = await readFileContent((0, import_node_path95.join)(baseDir, relativePath));
13201
+ const relativePath = (0, import_node_path97.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
13202
+ const fileContent = await readFileContent((0, import_node_path97.join)(baseDir, relativePath));
12832
13203
  return new _ClaudecodeLegacyRule({
12833
13204
  baseDir,
12834
13205
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -12887,10 +13258,10 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
12887
13258
  };
12888
13259
 
12889
13260
  // src/features/rules/claudecode-rule.ts
12890
- var import_node_path96 = require("path");
12891
- var import_mini49 = require("zod/mini");
12892
- var ClaudecodeRuleFrontmatterSchema = import_mini49.z.object({
12893
- paths: import_mini49.z.optional(import_mini49.z.array(import_mini49.z.string()))
13261
+ var import_node_path98 = require("path");
13262
+ var import_mini51 = require("zod/mini");
13263
+ var ClaudecodeRuleFrontmatterSchema = import_mini51.z.object({
13264
+ paths: import_mini51.z.optional(import_mini51.z.array(import_mini51.z.string()))
12894
13265
  });
12895
13266
  var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
12896
13267
  frontmatter;
@@ -12928,7 +13299,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
12928
13299
  const result = ClaudecodeRuleFrontmatterSchema.safeParse(frontmatter);
12929
13300
  if (!result.success) {
12930
13301
  throw new Error(
12931
- `Invalid frontmatter in ${(0, import_node_path96.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
13302
+ `Invalid frontmatter in ${(0, import_node_path98.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
12932
13303
  );
12933
13304
  }
12934
13305
  }
@@ -12958,7 +13329,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
12958
13329
  if (isRoot) {
12959
13330
  const rootDirPath = overrideDirPath ?? paths.root.relativeDirPath;
12960
13331
  const fileContent2 = await readFileContent(
12961
- (0, import_node_path96.join)(baseDir, rootDirPath, paths.root.relativeFilePath)
13332
+ (0, import_node_path98.join)(baseDir, rootDirPath, paths.root.relativeFilePath)
12962
13333
  );
12963
13334
  return new _ClaudecodeRule({
12964
13335
  baseDir,
@@ -12973,8 +13344,8 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
12973
13344
  if (!paths.nonRoot) {
12974
13345
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
12975
13346
  }
12976
- const relativePath = (0, import_node_path96.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
12977
- const filePath = (0, import_node_path96.join)(baseDir, relativePath);
13347
+ const relativePath = (0, import_node_path98.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
13348
+ const filePath = (0, import_node_path98.join)(baseDir, relativePath);
12978
13349
  const fileContent = await readFileContent(filePath);
12979
13350
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
12980
13351
  const result = ClaudecodeRuleFrontmatterSchema.safeParse(frontmatter);
@@ -13085,7 +13456,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
13085
13456
  return {
13086
13457
  success: false,
13087
13458
  error: new Error(
13088
- `Invalid frontmatter in ${(0, import_node_path96.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
13459
+ `Invalid frontmatter in ${(0, import_node_path98.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
13089
13460
  )
13090
13461
  };
13091
13462
  }
@@ -13105,10 +13476,10 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
13105
13476
  };
13106
13477
 
13107
13478
  // src/features/rules/cline-rule.ts
13108
- var import_node_path97 = require("path");
13109
- var import_mini50 = require("zod/mini");
13110
- var ClineRuleFrontmatterSchema = import_mini50.z.object({
13111
- description: import_mini50.z.string()
13479
+ var import_node_path99 = require("path");
13480
+ var import_mini52 = require("zod/mini");
13481
+ var ClineRuleFrontmatterSchema = import_mini52.z.object({
13482
+ description: import_mini52.z.string()
13112
13483
  });
13113
13484
  var ClineRule = class _ClineRule extends ToolRule {
13114
13485
  static getSettablePaths(_options = {}) {
@@ -13151,7 +13522,7 @@ var ClineRule = class _ClineRule extends ToolRule {
13151
13522
  validate = true
13152
13523
  }) {
13153
13524
  const fileContent = await readFileContent(
13154
- (0, import_node_path97.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
13525
+ (0, import_node_path99.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
13155
13526
  );
13156
13527
  return new _ClineRule({
13157
13528
  baseDir,
@@ -13177,7 +13548,7 @@ var ClineRule = class _ClineRule extends ToolRule {
13177
13548
  };
13178
13549
 
13179
13550
  // src/features/rules/codexcli-rule.ts
13180
- var import_node_path98 = require("path");
13551
+ var import_node_path100 = require("path");
13181
13552
  var CodexcliRule = class _CodexcliRule extends ToolRule {
13182
13553
  static getSettablePaths({
13183
13554
  global,
@@ -13212,7 +13583,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
13212
13583
  if (isRoot) {
13213
13584
  const relativePath2 = paths.root.relativeFilePath;
13214
13585
  const fileContent2 = await readFileContent(
13215
- (0, import_node_path98.join)(baseDir, paths.root.relativeDirPath, relativePath2)
13586
+ (0, import_node_path100.join)(baseDir, paths.root.relativeDirPath, relativePath2)
13216
13587
  );
13217
13588
  return new _CodexcliRule({
13218
13589
  baseDir,
@@ -13226,8 +13597,8 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
13226
13597
  if (!paths.nonRoot) {
13227
13598
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
13228
13599
  }
13229
- const relativePath = (0, import_node_path98.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
13230
- const fileContent = await readFileContent((0, import_node_path98.join)(baseDir, relativePath));
13600
+ const relativePath = (0, import_node_path100.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
13601
+ const fileContent = await readFileContent((0, import_node_path100.join)(baseDir, relativePath));
13231
13602
  return new _CodexcliRule({
13232
13603
  baseDir,
13233
13604
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -13286,12 +13657,12 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
13286
13657
  };
13287
13658
 
13288
13659
  // src/features/rules/copilot-rule.ts
13289
- var import_node_path99 = require("path");
13290
- var import_mini51 = require("zod/mini");
13291
- var CopilotRuleFrontmatterSchema = import_mini51.z.object({
13292
- description: import_mini51.z.optional(import_mini51.z.string()),
13293
- applyTo: import_mini51.z.optional(import_mini51.z.string()),
13294
- excludeAgent: import_mini51.z.optional(import_mini51.z.union([import_mini51.z.literal("code-review"), import_mini51.z.literal("coding-agent")]))
13660
+ var import_node_path101 = require("path");
13661
+ var import_mini53 = require("zod/mini");
13662
+ var CopilotRuleFrontmatterSchema = import_mini53.z.object({
13663
+ description: import_mini53.z.optional(import_mini53.z.string()),
13664
+ applyTo: import_mini53.z.optional(import_mini53.z.string()),
13665
+ excludeAgent: import_mini53.z.optional(import_mini53.z.union([import_mini53.z.literal("code-review"), import_mini53.z.literal("coding-agent")]))
13295
13666
  });
13296
13667
  var CopilotRule = class _CopilotRule extends ToolRule {
13297
13668
  frontmatter;
@@ -13302,6 +13673,9 @@ var CopilotRule = class _CopilotRule extends ToolRule {
13302
13673
  root: {
13303
13674
  relativeDirPath: buildToolPath(".copilot", ".", options.excludeToolDir),
13304
13675
  relativeFilePath: "copilot-instructions.md"
13676
+ },
13677
+ nonRoot: {
13678
+ relativeDirPath: buildToolPath(".copilot", "instructions", options.excludeToolDir)
13305
13679
  }
13306
13680
  };
13307
13681
  }
@@ -13320,7 +13694,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
13320
13694
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
13321
13695
  if (!result.success) {
13322
13696
  throw new Error(
13323
- `Invalid frontmatter in ${(0, import_node_path99.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
13697
+ `Invalid frontmatter in ${(0, import_node_path101.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
13324
13698
  );
13325
13699
  }
13326
13700
  }
@@ -13410,8 +13784,8 @@ var CopilotRule = class _CopilotRule extends ToolRule {
13410
13784
  const paths = this.getSettablePaths({ global });
13411
13785
  const isRoot = relativeFilePath === paths.root.relativeFilePath;
13412
13786
  if (isRoot) {
13413
- const relativePath2 = (0, import_node_path99.join)(paths.root.relativeDirPath, paths.root.relativeFilePath);
13414
- const filePath2 = (0, import_node_path99.join)(baseDir, relativePath2);
13787
+ const relativePath2 = (0, import_node_path101.join)(paths.root.relativeDirPath, paths.root.relativeFilePath);
13788
+ const filePath2 = (0, import_node_path101.join)(baseDir, relativePath2);
13415
13789
  const fileContent2 = await readFileContent(filePath2);
13416
13790
  return new _CopilotRule({
13417
13791
  baseDir,
@@ -13426,8 +13800,8 @@ var CopilotRule = class _CopilotRule extends ToolRule {
13426
13800
  if (!paths.nonRoot) {
13427
13801
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
13428
13802
  }
13429
- const relativePath = (0, import_node_path99.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
13430
- const filePath = (0, import_node_path99.join)(baseDir, relativePath);
13803
+ const relativePath = (0, import_node_path101.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
13804
+ const filePath = (0, import_node_path101.join)(baseDir, relativePath);
13431
13805
  const fileContent = await readFileContent(filePath);
13432
13806
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
13433
13807
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
@@ -13473,7 +13847,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
13473
13847
  return {
13474
13848
  success: false,
13475
13849
  error: new Error(
13476
- `Invalid frontmatter in ${(0, import_node_path99.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
13850
+ `Invalid frontmatter in ${(0, import_node_path101.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
13477
13851
  )
13478
13852
  };
13479
13853
  }
@@ -13493,12 +13867,12 @@ var CopilotRule = class _CopilotRule extends ToolRule {
13493
13867
  };
13494
13868
 
13495
13869
  // src/features/rules/cursor-rule.ts
13496
- var import_node_path100 = require("path");
13497
- var import_mini52 = require("zod/mini");
13498
- var CursorRuleFrontmatterSchema = import_mini52.z.object({
13499
- description: import_mini52.z.optional(import_mini52.z.string()),
13500
- globs: import_mini52.z.optional(import_mini52.z.string()),
13501
- alwaysApply: import_mini52.z.optional(import_mini52.z.boolean())
13870
+ var import_node_path102 = require("path");
13871
+ var import_mini54 = require("zod/mini");
13872
+ var CursorRuleFrontmatterSchema = import_mini54.z.object({
13873
+ description: import_mini54.z.optional(import_mini54.z.string()),
13874
+ globs: import_mini54.z.optional(import_mini54.z.string()),
13875
+ alwaysApply: import_mini54.z.optional(import_mini54.z.boolean())
13502
13876
  });
13503
13877
  var CursorRule = class _CursorRule extends ToolRule {
13504
13878
  frontmatter;
@@ -13515,7 +13889,7 @@ var CursorRule = class _CursorRule extends ToolRule {
13515
13889
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
13516
13890
  if (!result.success) {
13517
13891
  throw new Error(
13518
- `Invalid frontmatter in ${(0, import_node_path100.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
13892
+ `Invalid frontmatter in ${(0, import_node_path102.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
13519
13893
  );
13520
13894
  }
13521
13895
  }
@@ -13631,7 +14005,7 @@ var CursorRule = class _CursorRule extends ToolRule {
13631
14005
  relativeFilePath,
13632
14006
  validate = true
13633
14007
  }) {
13634
- const filePath = (0, import_node_path100.join)(
14008
+ const filePath = (0, import_node_path102.join)(
13635
14009
  baseDir,
13636
14010
  this.getSettablePaths().nonRoot.relativeDirPath,
13637
14011
  relativeFilePath
@@ -13641,7 +14015,7 @@ var CursorRule = class _CursorRule extends ToolRule {
13641
14015
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
13642
14016
  if (!result.success) {
13643
14017
  throw new Error(
13644
- `Invalid frontmatter in ${(0, import_node_path100.join)(baseDir, relativeFilePath)}: ${formatError(result.error)}`
14018
+ `Invalid frontmatter in ${(0, import_node_path102.join)(baseDir, relativeFilePath)}: ${formatError(result.error)}`
13645
14019
  );
13646
14020
  }
13647
14021
  return new _CursorRule({
@@ -13678,7 +14052,7 @@ var CursorRule = class _CursorRule extends ToolRule {
13678
14052
  return {
13679
14053
  success: false,
13680
14054
  error: new Error(
13681
- `Invalid frontmatter in ${(0, import_node_path100.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
14055
+ `Invalid frontmatter in ${(0, import_node_path102.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
13682
14056
  )
13683
14057
  };
13684
14058
  }
@@ -13698,7 +14072,7 @@ var CursorRule = class _CursorRule extends ToolRule {
13698
14072
  };
13699
14073
 
13700
14074
  // src/features/rules/factorydroid-rule.ts
13701
- var import_node_path101 = require("path");
14075
+ var import_node_path103 = require("path");
13702
14076
  var FactorydroidRule = class _FactorydroidRule extends ToolRule {
13703
14077
  constructor({ fileContent, root, ...rest }) {
13704
14078
  super({
@@ -13738,8 +14112,8 @@ var FactorydroidRule = class _FactorydroidRule extends ToolRule {
13738
14112
  const paths = this.getSettablePaths({ global });
13739
14113
  const isRoot = relativeFilePath === paths.root.relativeFilePath;
13740
14114
  if (isRoot) {
13741
- const relativePath2 = (0, import_node_path101.join)(paths.root.relativeDirPath, paths.root.relativeFilePath);
13742
- const fileContent2 = await readFileContent((0, import_node_path101.join)(baseDir, relativePath2));
14115
+ const relativePath2 = (0, import_node_path103.join)(paths.root.relativeDirPath, paths.root.relativeFilePath);
14116
+ const fileContent2 = await readFileContent((0, import_node_path103.join)(baseDir, relativePath2));
13743
14117
  return new _FactorydroidRule({
13744
14118
  baseDir,
13745
14119
  relativeDirPath: paths.root.relativeDirPath,
@@ -13752,8 +14126,8 @@ var FactorydroidRule = class _FactorydroidRule extends ToolRule {
13752
14126
  if (!paths.nonRoot) {
13753
14127
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
13754
14128
  }
13755
- const relativePath = (0, import_node_path101.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
13756
- const fileContent = await readFileContent((0, import_node_path101.join)(baseDir, relativePath));
14129
+ const relativePath = (0, import_node_path103.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
14130
+ const fileContent = await readFileContent((0, import_node_path103.join)(baseDir, relativePath));
13757
14131
  return new _FactorydroidRule({
13758
14132
  baseDir,
13759
14133
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -13812,7 +14186,7 @@ var FactorydroidRule = class _FactorydroidRule extends ToolRule {
13812
14186
  };
13813
14187
 
13814
14188
  // src/features/rules/geminicli-rule.ts
13815
- var import_node_path102 = require("path");
14189
+ var import_node_path104 = require("path");
13816
14190
  var GeminiCliRule = class _GeminiCliRule extends ToolRule {
13817
14191
  static getSettablePaths({
13818
14192
  global,
@@ -13847,7 +14221,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
13847
14221
  if (isRoot) {
13848
14222
  const relativePath2 = paths.root.relativeFilePath;
13849
14223
  const fileContent2 = await readFileContent(
13850
- (0, import_node_path102.join)(baseDir, paths.root.relativeDirPath, relativePath2)
14224
+ (0, import_node_path104.join)(baseDir, paths.root.relativeDirPath, relativePath2)
13851
14225
  );
13852
14226
  return new _GeminiCliRule({
13853
14227
  baseDir,
@@ -13861,8 +14235,8 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
13861
14235
  if (!paths.nonRoot) {
13862
14236
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
13863
14237
  }
13864
- const relativePath = (0, import_node_path102.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
13865
- const fileContent = await readFileContent((0, import_node_path102.join)(baseDir, relativePath));
14238
+ const relativePath = (0, import_node_path104.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
14239
+ const fileContent = await readFileContent((0, import_node_path104.join)(baseDir, relativePath));
13866
14240
  return new _GeminiCliRule({
13867
14241
  baseDir,
13868
14242
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -13921,7 +14295,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
13921
14295
  };
13922
14296
 
13923
14297
  // src/features/rules/goose-rule.ts
13924
- var import_node_path103 = require("path");
14298
+ var import_node_path105 = require("path");
13925
14299
  var GooseRule = class _GooseRule extends ToolRule {
13926
14300
  static getSettablePaths({
13927
14301
  global,
@@ -13956,7 +14330,7 @@ var GooseRule = class _GooseRule extends ToolRule {
13956
14330
  if (isRoot) {
13957
14331
  const relativePath2 = paths.root.relativeFilePath;
13958
14332
  const fileContent2 = await readFileContent(
13959
- (0, import_node_path103.join)(baseDir, paths.root.relativeDirPath, relativePath2)
14333
+ (0, import_node_path105.join)(baseDir, paths.root.relativeDirPath, relativePath2)
13960
14334
  );
13961
14335
  return new _GooseRule({
13962
14336
  baseDir,
@@ -13970,8 +14344,8 @@ var GooseRule = class _GooseRule extends ToolRule {
13970
14344
  if (!paths.nonRoot) {
13971
14345
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
13972
14346
  }
13973
- const relativePath = (0, import_node_path103.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
13974
- const fileContent = await readFileContent((0, import_node_path103.join)(baseDir, relativePath));
14347
+ const relativePath = (0, import_node_path105.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
14348
+ const fileContent = await readFileContent((0, import_node_path105.join)(baseDir, relativePath));
13975
14349
  return new _GooseRule({
13976
14350
  baseDir,
13977
14351
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -14030,7 +14404,7 @@ var GooseRule = class _GooseRule extends ToolRule {
14030
14404
  };
14031
14405
 
14032
14406
  // src/features/rules/junie-rule.ts
14033
- var import_node_path104 = require("path");
14407
+ var import_node_path106 = require("path");
14034
14408
  var JunieRule = class _JunieRule extends ToolRule {
14035
14409
  static getSettablePaths(_options = {}) {
14036
14410
  return {
@@ -14049,8 +14423,8 @@ var JunieRule = class _JunieRule extends ToolRule {
14049
14423
  validate = true
14050
14424
  }) {
14051
14425
  const isRoot = relativeFilePath === "guidelines.md";
14052
- const relativePath = isRoot ? "guidelines.md" : (0, import_node_path104.join)(".junie", "memories", relativeFilePath);
14053
- const fileContent = await readFileContent((0, import_node_path104.join)(baseDir, relativePath));
14426
+ const relativePath = isRoot ? "guidelines.md" : (0, import_node_path106.join)(".junie", "memories", relativeFilePath);
14427
+ const fileContent = await readFileContent((0, import_node_path106.join)(baseDir, relativePath));
14054
14428
  return new _JunieRule({
14055
14429
  baseDir,
14056
14430
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -14105,7 +14479,7 @@ var JunieRule = class _JunieRule extends ToolRule {
14105
14479
  };
14106
14480
 
14107
14481
  // src/features/rules/kilo-rule.ts
14108
- var import_node_path105 = require("path");
14482
+ var import_node_path107 = require("path");
14109
14483
  var KiloRule = class _KiloRule extends ToolRule {
14110
14484
  static getSettablePaths(_options = {}) {
14111
14485
  return {
@@ -14120,7 +14494,7 @@ var KiloRule = class _KiloRule extends ToolRule {
14120
14494
  validate = true
14121
14495
  }) {
14122
14496
  const fileContent = await readFileContent(
14123
- (0, import_node_path105.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
14497
+ (0, import_node_path107.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
14124
14498
  );
14125
14499
  return new _KiloRule({
14126
14500
  baseDir,
@@ -14172,7 +14546,7 @@ var KiloRule = class _KiloRule extends ToolRule {
14172
14546
  };
14173
14547
 
14174
14548
  // src/features/rules/kiro-rule.ts
14175
- var import_node_path106 = require("path");
14549
+ var import_node_path108 = require("path");
14176
14550
  var KiroRule = class _KiroRule extends ToolRule {
14177
14551
  static getSettablePaths(_options = {}) {
14178
14552
  return {
@@ -14187,7 +14561,7 @@ var KiroRule = class _KiroRule extends ToolRule {
14187
14561
  validate = true
14188
14562
  }) {
14189
14563
  const fileContent = await readFileContent(
14190
- (0, import_node_path106.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
14564
+ (0, import_node_path108.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
14191
14565
  );
14192
14566
  return new _KiroRule({
14193
14567
  baseDir,
@@ -14241,7 +14615,7 @@ var KiroRule = class _KiroRule extends ToolRule {
14241
14615
  };
14242
14616
 
14243
14617
  // src/features/rules/opencode-rule.ts
14244
- var import_node_path107 = require("path");
14618
+ var import_node_path109 = require("path");
14245
14619
  var OpenCodeRule = class _OpenCodeRule extends ToolRule {
14246
14620
  static getSettablePaths({
14247
14621
  global,
@@ -14276,7 +14650,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
14276
14650
  if (isRoot) {
14277
14651
  const relativePath2 = paths.root.relativeFilePath;
14278
14652
  const fileContent2 = await readFileContent(
14279
- (0, import_node_path107.join)(baseDir, paths.root.relativeDirPath, relativePath2)
14653
+ (0, import_node_path109.join)(baseDir, paths.root.relativeDirPath, relativePath2)
14280
14654
  );
14281
14655
  return new _OpenCodeRule({
14282
14656
  baseDir,
@@ -14290,8 +14664,8 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
14290
14664
  if (!paths.nonRoot) {
14291
14665
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
14292
14666
  }
14293
- const relativePath = (0, import_node_path107.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
14294
- const fileContent = await readFileContent((0, import_node_path107.join)(baseDir, relativePath));
14667
+ const relativePath = (0, import_node_path109.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
14668
+ const fileContent = await readFileContent((0, import_node_path109.join)(baseDir, relativePath));
14295
14669
  return new _OpenCodeRule({
14296
14670
  baseDir,
14297
14671
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -14350,7 +14724,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
14350
14724
  };
14351
14725
 
14352
14726
  // src/features/rules/qwencode-rule.ts
14353
- var import_node_path108 = require("path");
14727
+ var import_node_path110 = require("path");
14354
14728
  var QwencodeRule = class _QwencodeRule extends ToolRule {
14355
14729
  static getSettablePaths(_options = {}) {
14356
14730
  return {
@@ -14369,8 +14743,8 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
14369
14743
  validate = true
14370
14744
  }) {
14371
14745
  const isRoot = relativeFilePath === "QWEN.md";
14372
- const relativePath = isRoot ? "QWEN.md" : (0, import_node_path108.join)(".qwen", "memories", relativeFilePath);
14373
- const fileContent = await readFileContent((0, import_node_path108.join)(baseDir, relativePath));
14746
+ const relativePath = isRoot ? "QWEN.md" : (0, import_node_path110.join)(".qwen", "memories", relativeFilePath);
14747
+ const fileContent = await readFileContent((0, import_node_path110.join)(baseDir, relativePath));
14374
14748
  return new _QwencodeRule({
14375
14749
  baseDir,
14376
14750
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -14422,7 +14796,7 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
14422
14796
  };
14423
14797
 
14424
14798
  // src/features/rules/replit-rule.ts
14425
- var import_node_path109 = require("path");
14799
+ var import_node_path111 = require("path");
14426
14800
  var ReplitRule = class _ReplitRule extends ToolRule {
14427
14801
  static getSettablePaths(_options = {}) {
14428
14802
  return {
@@ -14444,7 +14818,7 @@ var ReplitRule = class _ReplitRule extends ToolRule {
14444
14818
  }
14445
14819
  const relativePath = paths.root.relativeFilePath;
14446
14820
  const fileContent = await readFileContent(
14447
- (0, import_node_path109.join)(baseDir, paths.root.relativeDirPath, relativePath)
14821
+ (0, import_node_path111.join)(baseDir, paths.root.relativeDirPath, relativePath)
14448
14822
  );
14449
14823
  return new _ReplitRule({
14450
14824
  baseDir,
@@ -14510,7 +14884,7 @@ var ReplitRule = class _ReplitRule extends ToolRule {
14510
14884
  };
14511
14885
 
14512
14886
  // src/features/rules/roo-rule.ts
14513
- var import_node_path110 = require("path");
14887
+ var import_node_path112 = require("path");
14514
14888
  var RooRule = class _RooRule extends ToolRule {
14515
14889
  static getSettablePaths(_options = {}) {
14516
14890
  return {
@@ -14525,7 +14899,7 @@ var RooRule = class _RooRule extends ToolRule {
14525
14899
  validate = true
14526
14900
  }) {
14527
14901
  const fileContent = await readFileContent(
14528
- (0, import_node_path110.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
14902
+ (0, import_node_path112.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
14529
14903
  );
14530
14904
  return new _RooRule({
14531
14905
  baseDir,
@@ -14594,7 +14968,7 @@ var RooRule = class _RooRule extends ToolRule {
14594
14968
  };
14595
14969
 
14596
14970
  // src/features/rules/warp-rule.ts
14597
- var import_node_path111 = require("path");
14971
+ var import_node_path113 = require("path");
14598
14972
  var WarpRule = class _WarpRule extends ToolRule {
14599
14973
  constructor({ fileContent, root, ...rest }) {
14600
14974
  super({
@@ -14620,8 +14994,8 @@ var WarpRule = class _WarpRule extends ToolRule {
14620
14994
  validate = true
14621
14995
  }) {
14622
14996
  const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
14623
- const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : (0, import_node_path111.join)(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
14624
- const fileContent = await readFileContent((0, import_node_path111.join)(baseDir, relativePath));
14997
+ const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : (0, import_node_path113.join)(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
14998
+ const fileContent = await readFileContent((0, import_node_path113.join)(baseDir, relativePath));
14625
14999
  return new _WarpRule({
14626
15000
  baseDir,
14627
15001
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : ".warp",
@@ -14676,7 +15050,7 @@ var WarpRule = class _WarpRule extends ToolRule {
14676
15050
  };
14677
15051
 
14678
15052
  // src/features/rules/windsurf-rule.ts
14679
- var import_node_path112 = require("path");
15053
+ var import_node_path114 = require("path");
14680
15054
  var WindsurfRule = class _WindsurfRule extends ToolRule {
14681
15055
  static getSettablePaths(_options = {}) {
14682
15056
  return {
@@ -14691,7 +15065,7 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
14691
15065
  validate = true
14692
15066
  }) {
14693
15067
  const fileContent = await readFileContent(
14694
- (0, import_node_path112.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
15068
+ (0, import_node_path114.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
14695
15069
  );
14696
15070
  return new _WindsurfRule({
14697
15071
  baseDir,
@@ -14767,8 +15141,8 @@ var rulesProcessorToolTargets = [
14767
15141
  "warp",
14768
15142
  "windsurf"
14769
15143
  ];
14770
- var RulesProcessorToolTargetSchema = import_mini53.z.enum(rulesProcessorToolTargets);
14771
- var formatRulePaths = (rules) => rules.map((r) => (0, import_node_path113.join)(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
15144
+ var RulesProcessorToolTargetSchema = import_mini55.z.enum(rulesProcessorToolTargets);
15145
+ var formatRulePaths = (rules) => rules.map((r) => (0, import_node_path115.join)(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
14772
15146
  var toolRuleFactories = /* @__PURE__ */ new Map([
14773
15147
  [
14774
15148
  "agentsmd",
@@ -15143,7 +15517,7 @@ var RulesProcessor = class extends FeatureProcessor {
15143
15517
  }).relativeDirPath;
15144
15518
  return this.skills.filter((skill) => skillClass.isTargetedByRulesyncSkill(skill)).map((skill) => {
15145
15519
  const frontmatter = skill.getFrontmatter();
15146
- const relativePath = (0, import_node_path113.join)(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME);
15520
+ const relativePath = (0, import_node_path115.join)(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME);
15147
15521
  return {
15148
15522
  name: frontmatter.name,
15149
15523
  description: frontmatter.description,
@@ -15256,12 +15630,12 @@ var RulesProcessor = class extends FeatureProcessor {
15256
15630
  * Load and parse rulesync rule files from .rulesync/rules/ directory
15257
15631
  */
15258
15632
  async loadRulesyncFiles() {
15259
- const rulesyncBaseDir = (0, import_node_path113.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
15260
- const files = await findFilesByGlobs((0, import_node_path113.join)(rulesyncBaseDir, "**", "*.md"));
15633
+ const rulesyncBaseDir = (0, import_node_path115.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
15634
+ const files = await findFilesByGlobs((0, import_node_path115.join)(rulesyncBaseDir, "**", "*.md"));
15261
15635
  logger.debug(`Found ${files.length} rulesync files`);
15262
15636
  const rulesyncRules = await Promise.all(
15263
15637
  files.map((file) => {
15264
- const relativeFilePath = (0, import_node_path113.relative)(rulesyncBaseDir, file);
15638
+ const relativeFilePath = (0, import_node_path115.relative)(rulesyncBaseDir, file);
15265
15639
  checkPathTraversal({
15266
15640
  relativePath: relativeFilePath,
15267
15641
  intendedRootDir: rulesyncBaseDir
@@ -15271,41 +15645,57 @@ var RulesProcessor = class extends FeatureProcessor {
15271
15645
  });
15272
15646
  })
15273
15647
  );
15648
+ const factory = this.getFactory(this.toolTarget);
15274
15649
  const rootRules = rulesyncRules.filter((rule) => rule.getFrontmatter().root);
15275
- if (rootRules.length > 1) {
15276
- throw new Error(`Multiple root rulesync rules found: ${formatRulePaths(rootRules)}`);
15650
+ const targetedRootRules = rootRules.filter(
15651
+ (rule) => factory.class.isTargetedByRulesyncRule(rule)
15652
+ );
15653
+ if (targetedRootRules.length > 1) {
15654
+ throw new Error(
15655
+ `Multiple root rulesync rules found for target '${this.toolTarget}': ${formatRulePaths(targetedRootRules)}`
15656
+ );
15277
15657
  }
15278
- if (rootRules.length === 0 && rulesyncRules.length > 0) {
15658
+ if (targetedRootRules.length === 0 && rulesyncRules.length > 0) {
15279
15659
  logger.warn(
15280
- `No root rulesync rule file found. Consider adding 'root: true' to one of your rule files in ${RULESYNC_RULES_RELATIVE_DIR_PATH}.`
15660
+ `No root rulesync rule file found for target '${this.toolTarget}'. Consider adding 'root: true' to one of your rule files in ${RULESYNC_RULES_RELATIVE_DIR_PATH}.`
15281
15661
  );
15282
15662
  }
15283
15663
  const localRootRules = rulesyncRules.filter((rule) => rule.getFrontmatter().localRoot);
15284
- if (localRootRules.length > 1) {
15664
+ const targetedLocalRootRules = localRootRules.filter(
15665
+ (rule) => factory.class.isTargetedByRulesyncRule(rule)
15666
+ );
15667
+ if (targetedLocalRootRules.length > 1) {
15285
15668
  throw new Error(
15286
- `Multiple localRoot rules found: ${formatRulePaths(localRootRules)}. Only one rule can have localRoot: true`
15669
+ `Multiple localRoot rules found for target '${this.toolTarget}': ${formatRulePaths(targetedLocalRootRules)}. Only one rule can have localRoot: true`
15287
15670
  );
15288
15671
  }
15289
- if (localRootRules.length > 0 && rootRules.length === 0) {
15672
+ if (targetedLocalRootRules.length > 0 && targetedRootRules.length === 0) {
15290
15673
  throw new Error(
15291
- `localRoot: true requires a root: true rule to exist (found in ${formatRulePaths(localRootRules)})`
15674
+ `localRoot: true requires a root: true rule to exist for target '${this.toolTarget}' (found in ${formatRulePaths(targetedLocalRootRules)})`
15292
15675
  );
15293
15676
  }
15294
15677
  if (this.global) {
15295
- const nonRootRules = rulesyncRules.filter((rule) => !rule.getFrontmatter().root);
15296
- if (nonRootRules.length > 0) {
15678
+ const globalPaths = factory.class.getSettablePaths({ global: true });
15679
+ const supportsGlobalNonRoot = "nonRoot" in globalPaths && globalPaths.nonRoot !== null;
15680
+ const nonRootRules2 = rulesyncRules.filter(
15681
+ (rule) => !rule.getFrontmatter().root && !rule.getFrontmatter().localRoot && factory.class.isTargetedByRulesyncRule(rule)
15682
+ );
15683
+ if (nonRootRules2.length > 0 && !supportsGlobalNonRoot) {
15297
15684
  logger.warn(
15298
- `${nonRootRules.length} non-root rulesync rules found, but it's in global mode, so ignoring them: ${formatRulePaths(nonRootRules)}`
15685
+ `${nonRootRules2.length} non-root rulesync rules found, but it's in global mode, so ignoring them: ${formatRulePaths(nonRootRules2)}`
15299
15686
  );
15300
15687
  }
15301
- if (localRootRules.length > 0) {
15688
+ if (targetedLocalRootRules.length > 0) {
15302
15689
  logger.warn(
15303
- `${localRootRules.length} localRoot rules found, but localRoot is not supported in global mode, ignoring them: ${formatRulePaths(localRootRules)}`
15690
+ `${targetedLocalRootRules.length} localRoot rules found, but localRoot is not supported in global mode, ignoring them: ${formatRulePaths(targetedLocalRootRules)}`
15304
15691
  );
15305
15692
  }
15306
- return rootRules;
15693
+ return supportsGlobalNonRoot ? [...targetedRootRules, ...nonRootRules2] : targetedRootRules;
15307
15694
  }
15308
- return rulesyncRules;
15695
+ const nonRootRules = rulesyncRules.filter(
15696
+ (rule) => !rule.getFrontmatter().root && factory.class.isTargetedByRulesyncRule(rule)
15697
+ );
15698
+ return [...targetedRootRules, ...nonRootRules];
15309
15699
  }
15310
15700
  /**
15311
15701
  * Implementation of abstract method from FeatureProcessor
@@ -15320,7 +15710,7 @@ var RulesProcessor = class extends FeatureProcessor {
15320
15710
  global: this.global
15321
15711
  });
15322
15712
  const resolveRelativeDirPath = (filePath) => {
15323
- const dirName = (0, import_node_path113.dirname)((0, import_node_path113.relative)(this.baseDir, filePath));
15713
+ const dirName = (0, import_node_path115.dirname)((0, import_node_path115.relative)(this.baseDir, filePath));
15324
15714
  return dirName === "" ? "." : dirName;
15325
15715
  };
15326
15716
  const findFilesWithFallback = async (primaryGlob, alternativeRoots, buildAltGlob) => {
@@ -15338,13 +15728,13 @@ var RulesProcessor = class extends FeatureProcessor {
15338
15728
  return [];
15339
15729
  }
15340
15730
  const uniqueRootFilePaths = await findFilesWithFallback(
15341
- (0, import_node_path113.join)(
15731
+ (0, import_node_path115.join)(
15342
15732
  this.baseDir,
15343
15733
  settablePaths.root.relativeDirPath ?? ".",
15344
15734
  settablePaths.root.relativeFilePath
15345
15735
  ),
15346
15736
  settablePaths.alternativeRoots,
15347
- (alt) => (0, import_node_path113.join)(this.baseDir, alt.relativeDirPath, alt.relativeFilePath)
15737
+ (alt) => (0, import_node_path115.join)(this.baseDir, alt.relativeDirPath, alt.relativeFilePath)
15348
15738
  );
15349
15739
  if (forDeletion) {
15350
15740
  return uniqueRootFilePaths.map((filePath) => {
@@ -15356,7 +15746,7 @@ var RulesProcessor = class extends FeatureProcessor {
15356
15746
  return factory.class.forDeletion({
15357
15747
  baseDir: this.baseDir,
15358
15748
  relativeDirPath,
15359
- relativeFilePath: (0, import_node_path113.basename)(filePath),
15749
+ relativeFilePath: (0, import_node_path115.basename)(filePath),
15360
15750
  global: this.global
15361
15751
  });
15362
15752
  }).filter((rule) => rule.isDeletable());
@@ -15370,7 +15760,7 @@ var RulesProcessor = class extends FeatureProcessor {
15370
15760
  });
15371
15761
  return factory.class.fromFile({
15372
15762
  baseDir: this.baseDir,
15373
- relativeFilePath: (0, import_node_path113.basename)(filePath),
15763
+ relativeFilePath: (0, import_node_path115.basename)(filePath),
15374
15764
  relativeDirPath,
15375
15765
  global: this.global
15376
15766
  });
@@ -15389,9 +15779,9 @@ var RulesProcessor = class extends FeatureProcessor {
15389
15779
  return [];
15390
15780
  }
15391
15781
  const uniqueLocalRootFilePaths = await findFilesWithFallback(
15392
- (0, import_node_path113.join)(this.baseDir, settablePaths.root.relativeDirPath ?? ".", "CLAUDE.local.md"),
15782
+ (0, import_node_path115.join)(this.baseDir, settablePaths.root.relativeDirPath ?? ".", "CLAUDE.local.md"),
15393
15783
  settablePaths.alternativeRoots,
15394
- (alt) => (0, import_node_path113.join)(this.baseDir, alt.relativeDirPath, "CLAUDE.local.md")
15784
+ (alt) => (0, import_node_path115.join)(this.baseDir, alt.relativeDirPath, "CLAUDE.local.md")
15395
15785
  );
15396
15786
  return uniqueLocalRootFilePaths.map((filePath) => {
15397
15787
  const relativeDirPath = resolveRelativeDirPath(filePath);
@@ -15402,7 +15792,7 @@ var RulesProcessor = class extends FeatureProcessor {
15402
15792
  return factory.class.forDeletion({
15403
15793
  baseDir: this.baseDir,
15404
15794
  relativeDirPath,
15405
- relativeFilePath: (0, import_node_path113.basename)(filePath),
15795
+ relativeFilePath: (0, import_node_path115.basename)(filePath),
15406
15796
  global: this.global
15407
15797
  });
15408
15798
  }).filter((rule) => rule.isDeletable());
@@ -15412,13 +15802,13 @@ var RulesProcessor = class extends FeatureProcessor {
15412
15802
  if (!settablePaths.nonRoot) {
15413
15803
  return [];
15414
15804
  }
15415
- const nonRootBaseDir = (0, import_node_path113.join)(this.baseDir, settablePaths.nonRoot.relativeDirPath);
15805
+ const nonRootBaseDir = (0, import_node_path115.join)(this.baseDir, settablePaths.nonRoot.relativeDirPath);
15416
15806
  const nonRootFilePaths = await findFilesByGlobs(
15417
- (0, import_node_path113.join)(nonRootBaseDir, "**", `*.${factory.meta.extension}`)
15807
+ (0, import_node_path115.join)(nonRootBaseDir, "**", `*.${factory.meta.extension}`)
15418
15808
  );
15419
15809
  if (forDeletion) {
15420
15810
  return nonRootFilePaths.map((filePath) => {
15421
- const relativeFilePath = (0, import_node_path113.relative)(nonRootBaseDir, filePath);
15811
+ const relativeFilePath = (0, import_node_path115.relative)(nonRootBaseDir, filePath);
15422
15812
  checkPathTraversal({
15423
15813
  relativePath: relativeFilePath,
15424
15814
  intendedRootDir: nonRootBaseDir
@@ -15433,7 +15823,7 @@ var RulesProcessor = class extends FeatureProcessor {
15433
15823
  }
15434
15824
  return await Promise.all(
15435
15825
  nonRootFilePaths.map((filePath) => {
15436
- const relativeFilePath = (0, import_node_path113.relative)(nonRootBaseDir, filePath);
15826
+ const relativeFilePath = (0, import_node_path115.relative)(nonRootBaseDir, filePath);
15437
15827
  checkPathTraversal({
15438
15828
  relativePath: relativeFilePath,
15439
15829
  intendedRootDir: nonRootBaseDir
@@ -15546,14 +15936,14 @@ s/<command> [arguments]
15546
15936
  This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
15547
15937
  The \`s\` in \`s/\` stands for *simulate*. Because custom slash commands are not built-in, this syntax provides a pseudo way to invoke them.
15548
15938
 
15549
- When users call a custom slash command, you have to look for the markdown file, \`${(0, import_node_path113.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
15939
+ When users call a custom slash command, you have to look for the markdown file, \`${(0, import_node_path115.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
15550
15940
  const subagentsSection = subagents ? `## Simulated Subagents
15551
15941
 
15552
15942
  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.
15553
15943
 
15554
- When users call a simulated subagent, it will look for the corresponding markdown file, \`${(0, import_node_path113.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "{subagent}.md")}\`, and execute its contents as the block of operations.
15944
+ When users call a simulated subagent, it will look for the corresponding markdown file, \`${(0, import_node_path115.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "{subagent}.md")}\`, and execute its contents as the block of operations.
15555
15945
 
15556
- For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${(0, import_node_path113.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
15946
+ For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${(0, import_node_path115.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
15557
15947
  const skillsSection = skills ? this.generateSkillsSection(skills) : "";
15558
15948
  const result = [
15559
15949
  overview,
@@ -15585,51 +15975,51 @@ var import_request_error = require("@octokit/request-error");
15585
15975
  var import_rest = require("@octokit/rest");
15586
15976
 
15587
15977
  // src/types/fetch.ts
15588
- var import_mini55 = require("zod/mini");
15978
+ var import_mini57 = require("zod/mini");
15589
15979
 
15590
15980
  // src/types/fetch-targets.ts
15591
- var import_mini54 = require("zod/mini");
15981
+ var import_mini56 = require("zod/mini");
15592
15982
  var ALL_FETCH_TARGETS = ["rulesync", ...ALL_TOOL_TARGETS];
15593
- var FetchTargetSchema = import_mini54.z.enum(ALL_FETCH_TARGETS);
15983
+ var FetchTargetSchema = import_mini56.z.enum(ALL_FETCH_TARGETS);
15594
15984
 
15595
15985
  // src/types/fetch.ts
15596
- var ConflictStrategySchema = import_mini55.z.enum(["skip", "overwrite"]);
15597
- var GitHubFileTypeSchema = import_mini55.z.enum(["file", "dir", "symlink", "submodule"]);
15598
- var GitHubFileEntrySchema = import_mini55.z.looseObject({
15599
- name: import_mini55.z.string(),
15600
- path: import_mini55.z.string(),
15601
- sha: import_mini55.z.string(),
15602
- size: import_mini55.z.number(),
15986
+ var ConflictStrategySchema = import_mini57.z.enum(["skip", "overwrite"]);
15987
+ var GitHubFileTypeSchema = import_mini57.z.enum(["file", "dir", "symlink", "submodule"]);
15988
+ var GitHubFileEntrySchema = import_mini57.z.looseObject({
15989
+ name: import_mini57.z.string(),
15990
+ path: import_mini57.z.string(),
15991
+ sha: import_mini57.z.string(),
15992
+ size: import_mini57.z.number(),
15603
15993
  type: GitHubFileTypeSchema,
15604
- download_url: import_mini55.z.nullable(import_mini55.z.string())
15994
+ download_url: import_mini57.z.nullable(import_mini57.z.string())
15605
15995
  });
15606
- var FetchOptionsSchema = import_mini55.z.looseObject({
15607
- target: import_mini55.z.optional(FetchTargetSchema),
15608
- features: import_mini55.z.optional(import_mini55.z.array(import_mini55.z.enum(ALL_FEATURES_WITH_WILDCARD))),
15609
- ref: import_mini55.z.optional(import_mini55.z.string()),
15610
- path: import_mini55.z.optional(import_mini55.z.string()),
15611
- output: import_mini55.z.optional(import_mini55.z.string()),
15612
- conflict: import_mini55.z.optional(ConflictStrategySchema),
15613
- token: import_mini55.z.optional(import_mini55.z.string()),
15614
- verbose: import_mini55.z.optional(import_mini55.z.boolean()),
15615
- silent: import_mini55.z.optional(import_mini55.z.boolean())
15996
+ var FetchOptionsSchema = import_mini57.z.looseObject({
15997
+ target: import_mini57.z.optional(FetchTargetSchema),
15998
+ features: import_mini57.z.optional(import_mini57.z.array(import_mini57.z.enum(ALL_FEATURES_WITH_WILDCARD))),
15999
+ ref: import_mini57.z.optional(import_mini57.z.string()),
16000
+ path: import_mini57.z.optional(import_mini57.z.string()),
16001
+ output: import_mini57.z.optional(import_mini57.z.string()),
16002
+ conflict: import_mini57.z.optional(ConflictStrategySchema),
16003
+ token: import_mini57.z.optional(import_mini57.z.string()),
16004
+ verbose: import_mini57.z.optional(import_mini57.z.boolean()),
16005
+ silent: import_mini57.z.optional(import_mini57.z.boolean())
15616
16006
  });
15617
- var FetchFileStatusSchema = import_mini55.z.enum(["created", "overwritten", "skipped"]);
15618
- var GitHubRepoInfoSchema = import_mini55.z.looseObject({
15619
- default_branch: import_mini55.z.string(),
15620
- private: import_mini55.z.boolean()
16007
+ var FetchFileStatusSchema = import_mini57.z.enum(["created", "overwritten", "skipped"]);
16008
+ var GitHubRepoInfoSchema = import_mini57.z.looseObject({
16009
+ default_branch: import_mini57.z.string(),
16010
+ private: import_mini57.z.boolean()
15621
16011
  });
15622
- var GitHubReleaseAssetSchema = import_mini55.z.looseObject({
15623
- name: import_mini55.z.string(),
15624
- browser_download_url: import_mini55.z.string(),
15625
- size: import_mini55.z.number()
16012
+ var GitHubReleaseAssetSchema = import_mini57.z.looseObject({
16013
+ name: import_mini57.z.string(),
16014
+ browser_download_url: import_mini57.z.string(),
16015
+ size: import_mini57.z.number()
15626
16016
  });
15627
- var GitHubReleaseSchema = import_mini55.z.looseObject({
15628
- tag_name: import_mini55.z.string(),
15629
- name: import_mini55.z.nullable(import_mini55.z.string()),
15630
- prerelease: import_mini55.z.boolean(),
15631
- draft: import_mini55.z.boolean(),
15632
- assets: import_mini55.z.array(GitHubReleaseAssetSchema)
16017
+ var GitHubReleaseSchema = import_mini57.z.looseObject({
16018
+ tag_name: import_mini57.z.string(),
16019
+ name: import_mini57.z.nullable(import_mini57.z.string()),
16020
+ prerelease: import_mini57.z.boolean(),
16021
+ draft: import_mini57.z.boolean(),
16022
+ assets: import_mini57.z.array(GitHubReleaseAssetSchema)
15633
16023
  });
15634
16024
 
15635
16025
  // src/lib/github-client.ts
@@ -15929,9 +16319,9 @@ async function listDirectoryRecursive(params) {
15929
16319
  }
15930
16320
 
15931
16321
  // src/types/git-provider.ts
15932
- var import_mini56 = require("zod/mini");
16322
+ var import_mini58 = require("zod/mini");
15933
16323
  var ALL_GIT_PROVIDERS = ["github", "gitlab"];
15934
- var GitProviderSchema = import_mini56.z.enum(ALL_GIT_PROVIDERS);
16324
+ var GitProviderSchema = import_mini58.z.enum(ALL_GIT_PROVIDERS);
15935
16325
 
15936
16326
  // src/lib/source-parser.ts
15937
16327
  var GITHUB_HOSTS = /* @__PURE__ */ new Set(["github.com", "www.github.com"]);
@@ -16056,8 +16446,8 @@ async function processFeatureConversion(params) {
16056
16446
  }
16057
16447
  const rulesyncFiles = await processor.convertToolFilesToRulesyncFiles(toolFiles);
16058
16448
  for (const file of rulesyncFiles) {
16059
- const relativePath = (0, import_node_path114.join)(file.getRelativeDirPath(), file.getRelativeFilePath());
16060
- const outputPath = (0, import_node_path114.join)(outputDir, relativePath);
16449
+ const relativePath = (0, import_node_path116.join)(file.getRelativeDirPath(), file.getRelativeFilePath());
16450
+ const outputPath = (0, import_node_path116.join)(outputDir, relativePath);
16061
16451
  await writeFileContent(outputPath, file.getFileContent());
16062
16452
  paths.push(relativePath);
16063
16453
  }
@@ -16203,7 +16593,7 @@ async function fetchFiles(params) {
16203
16593
  skipped: 0
16204
16594
  };
16205
16595
  }
16206
- const outputBasePath = (0, import_node_path114.join)(baseDir, outputDir);
16596
+ const outputBasePath = (0, import_node_path116.join)(baseDir, outputDir);
16207
16597
  for (const { relativePath, size } of filesToFetch) {
16208
16598
  checkPathTraversal({
16209
16599
  relativePath,
@@ -16213,7 +16603,7 @@ async function fetchFiles(params) {
16213
16603
  }
16214
16604
  const results = await Promise.all(
16215
16605
  filesToFetch.map(async ({ remotePath, relativePath }) => {
16216
- const localPath = (0, import_node_path114.join)(outputBasePath, relativePath);
16606
+ const localPath = (0, import_node_path116.join)(outputBasePath, relativePath);
16217
16607
  const exists = await fileExists(localPath);
16218
16608
  if (exists && conflictStrategy === "skip") {
16219
16609
  logger.debug(`Skipping existing file: ${relativePath}`);
@@ -16255,7 +16645,7 @@ async function collectFeatureFiles(params) {
16255
16645
  );
16256
16646
  const results = await Promise.all(
16257
16647
  tasks.map(async ({ featurePath }) => {
16258
- const fullPath = basePath === "." || basePath === "" ? featurePath : (0, import_node_path114.join)(basePath, featurePath);
16648
+ const fullPath = basePath === "." || basePath === "" ? featurePath : (0, import_node_path116.join)(basePath, featurePath);
16259
16649
  const collected = [];
16260
16650
  try {
16261
16651
  if (featurePath.includes(".")) {
@@ -16355,7 +16745,7 @@ async function fetchAndConvertToolFiles(params) {
16355
16745
  relativePath: toolRelativePath,
16356
16746
  intendedRootDir: tempDir
16357
16747
  });
16358
- const localPath = (0, import_node_path114.join)(tempDir, toolRelativePath);
16748
+ const localPath = (0, import_node_path116.join)(tempDir, toolRelativePath);
16359
16749
  const content = await withSemaphore(
16360
16750
  semaphore,
16361
16751
  () => client.getFileContent(parsed.owner, parsed.repo, remotePath, ref)
@@ -16364,7 +16754,7 @@ async function fetchAndConvertToolFiles(params) {
16364
16754
  logger.debug(`Fetched to temp: ${toolRelativePath}`);
16365
16755
  })
16366
16756
  );
16367
- const outputBasePath = (0, import_node_path114.join)(baseDir, outputDir);
16757
+ const outputBasePath = (0, import_node_path116.join)(baseDir, outputDir);
16368
16758
  const { converted, convertedPaths } = await convertFetchedFilesToRulesync({
16369
16759
  tempDir,
16370
16760
  outputDir: outputBasePath,
@@ -16437,7 +16827,7 @@ function mapToToolPath(relativePath, toolPaths) {
16437
16827
  if (relativePath.startsWith("rules/")) {
16438
16828
  const restPath = relativePath.substring("rules/".length);
16439
16829
  if (toolPaths.rules?.nonRoot) {
16440
- return (0, import_node_path114.join)(toolPaths.rules.nonRoot, restPath);
16830
+ return (0, import_node_path116.join)(toolPaths.rules.nonRoot, restPath);
16441
16831
  }
16442
16832
  }
16443
16833
  if (toolPaths.rules?.root && relativePath === toolPaths.rules.root) {
@@ -16446,19 +16836,19 @@ function mapToToolPath(relativePath, toolPaths) {
16446
16836
  if (relativePath.startsWith("commands/")) {
16447
16837
  const restPath = relativePath.substring("commands/".length);
16448
16838
  if (toolPaths.commands) {
16449
- return (0, import_node_path114.join)(toolPaths.commands, restPath);
16839
+ return (0, import_node_path116.join)(toolPaths.commands, restPath);
16450
16840
  }
16451
16841
  }
16452
16842
  if (relativePath.startsWith("subagents/")) {
16453
16843
  const restPath = relativePath.substring("subagents/".length);
16454
16844
  if (toolPaths.subagents) {
16455
- return (0, import_node_path114.join)(toolPaths.subagents, restPath);
16845
+ return (0, import_node_path116.join)(toolPaths.subagents, restPath);
16456
16846
  }
16457
16847
  }
16458
16848
  if (relativePath.startsWith("skills/")) {
16459
16849
  const restPath = relativePath.substring("skills/".length);
16460
16850
  if (toolPaths.skills) {
16461
- return (0, import_node_path114.join)(toolPaths.skills, restPath);
16851
+ return (0, import_node_path116.join)(toolPaths.skills, restPath);
16462
16852
  }
16463
16853
  }
16464
16854
  return relativePath;
@@ -16510,38 +16900,60 @@ async function fetchCommand(options) {
16510
16900
  }
16511
16901
 
16512
16902
  // src/config/config-resolver.ts
16513
- var import_node_path115 = require("path");
16903
+ var import_node_path118 = require("path");
16514
16904
  var import_jsonc_parser2 = require("jsonc-parser");
16515
16905
 
16516
16906
  // src/config/config.ts
16517
- var import_mini57 = require("zod/mini");
16518
- var SourceEntrySchema = import_mini57.z.object({
16519
- source: import_mini57.z.string().check((0, import_mini57.minLength)(1, "source must be a non-empty string")),
16520
- skills: (0, import_mini57.optional)(import_mini57.z.array(import_mini57.z.string()))
16907
+ var import_node_path117 = require("path");
16908
+ var import_mini59 = require("zod/mini");
16909
+ function hasControlCharacters(value) {
16910
+ for (let i = 0; i < value.length; i++) {
16911
+ const code = value.charCodeAt(i);
16912
+ if (code >= 0 && code <= 31 || code === 127) return true;
16913
+ }
16914
+ return false;
16915
+ }
16916
+ var SourceEntrySchema = import_mini59.z.object({
16917
+ source: import_mini59.z.string().check((0, import_mini59.minLength)(1, "source must be a non-empty string")),
16918
+ skills: (0, import_mini59.optional)(import_mini59.z.array(import_mini59.z.string())),
16919
+ transport: (0, import_mini59.optional)(import_mini59.z.enum(["github", "git"])),
16920
+ ref: (0, import_mini59.optional)(
16921
+ import_mini59.z.string().check(
16922
+ (0, import_mini59.refine)((v) => !v.startsWith("-"), 'ref must not start with "-"'),
16923
+ (0, import_mini59.refine)((v) => !hasControlCharacters(v), "ref must not contain control characters")
16924
+ )
16925
+ ),
16926
+ path: (0, import_mini59.optional)(
16927
+ import_mini59.z.string().check(
16928
+ (0, import_mini59.refine)((v) => !v.includes(".."), 'path must not contain ".."'),
16929
+ (0, import_mini59.refine)((v) => !(0, import_node_path117.isAbsolute)(v), "path must not be absolute"),
16930
+ (0, import_mini59.refine)((v) => !hasControlCharacters(v), "path must not contain control characters")
16931
+ )
16932
+ )
16521
16933
  });
16522
- var ConfigParamsSchema = import_mini57.z.object({
16523
- baseDirs: import_mini57.z.array(import_mini57.z.string()),
16934
+ var ConfigParamsSchema = import_mini59.z.object({
16935
+ baseDirs: import_mini59.z.array(import_mini59.z.string()),
16524
16936
  targets: RulesyncTargetsSchema,
16525
16937
  features: RulesyncFeaturesSchema,
16526
- verbose: import_mini57.z.boolean(),
16527
- delete: import_mini57.z.boolean(),
16938
+ verbose: import_mini59.z.boolean(),
16939
+ delete: import_mini59.z.boolean(),
16528
16940
  // New non-experimental options
16529
- global: (0, import_mini57.optional)(import_mini57.z.boolean()),
16530
- silent: (0, import_mini57.optional)(import_mini57.z.boolean()),
16531
- simulateCommands: (0, import_mini57.optional)(import_mini57.z.boolean()),
16532
- simulateSubagents: (0, import_mini57.optional)(import_mini57.z.boolean()),
16533
- simulateSkills: (0, import_mini57.optional)(import_mini57.z.boolean()),
16534
- dryRun: (0, import_mini57.optional)(import_mini57.z.boolean()),
16535
- check: (0, import_mini57.optional)(import_mini57.z.boolean()),
16941
+ global: (0, import_mini59.optional)(import_mini59.z.boolean()),
16942
+ silent: (0, import_mini59.optional)(import_mini59.z.boolean()),
16943
+ simulateCommands: (0, import_mini59.optional)(import_mini59.z.boolean()),
16944
+ simulateSubagents: (0, import_mini59.optional)(import_mini59.z.boolean()),
16945
+ simulateSkills: (0, import_mini59.optional)(import_mini59.z.boolean()),
16946
+ dryRun: (0, import_mini59.optional)(import_mini59.z.boolean()),
16947
+ check: (0, import_mini59.optional)(import_mini59.z.boolean()),
16536
16948
  // Declarative skill sources
16537
- sources: (0, import_mini57.optional)(import_mini57.z.array(SourceEntrySchema))
16949
+ sources: (0, import_mini59.optional)(import_mini59.z.array(SourceEntrySchema))
16538
16950
  });
16539
- var PartialConfigParamsSchema = import_mini57.z.partial(ConfigParamsSchema);
16540
- var ConfigFileSchema = import_mini57.z.object({
16541
- $schema: (0, import_mini57.optional)(import_mini57.z.string()),
16542
- ...import_mini57.z.partial(ConfigParamsSchema).shape
16951
+ var PartialConfigParamsSchema = import_mini59.z.partial(ConfigParamsSchema);
16952
+ var ConfigFileSchema = import_mini59.z.object({
16953
+ $schema: (0, import_mini59.optional)(import_mini59.z.string()),
16954
+ ...import_mini59.z.partial(ConfigParamsSchema).shape
16543
16955
  });
16544
- var RequiredConfigParamsSchema = import_mini57.z.required(ConfigParamsSchema);
16956
+ var RequiredConfigParamsSchema = import_mini59.z.required(ConfigParamsSchema);
16545
16957
  var CONFLICTING_TARGET_PAIRS = [
16546
16958
  ["augmentcode", "augmentcode-legacy"],
16547
16959
  ["claudecode", "claudecode-legacy"]
@@ -16762,8 +17174,8 @@ var ConfigResolver = class {
16762
17174
  }) {
16763
17175
  const validatedConfigPath = resolvePath(configPath, process.cwd());
16764
17176
  const baseConfig = await loadConfigFromFile(validatedConfigPath);
16765
- const configDir = (0, import_node_path115.dirname)(validatedConfigPath);
16766
- const localConfigPath = (0, import_node_path115.join)(configDir, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH);
17177
+ const configDir = (0, import_node_path118.dirname)(validatedConfigPath);
17178
+ const localConfigPath = (0, import_node_path118.join)(configDir, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH);
16767
17179
  const localConfig = await loadConfigFromFile(localConfigPath);
16768
17180
  const configByFile = mergeConfigs(baseConfig, localConfig);
16769
17181
  const resolvedGlobal = global ?? configByFile.global ?? getDefaults().global;
@@ -16798,7 +17210,7 @@ function getBaseDirsInLightOfGlobal({
16798
17210
  if (global) {
16799
17211
  return [getHomeDirectory()];
16800
17212
  }
16801
- const resolvedBaseDirs = baseDirs.map((baseDir) => (0, import_node_path115.resolve)(baseDir));
17213
+ const resolvedBaseDirs = baseDirs.map((baseDir) => (0, import_node_path118.resolve)(baseDir));
16802
17214
  resolvedBaseDirs.forEach((baseDir) => {
16803
17215
  validateBaseDir(baseDir);
16804
17216
  });
@@ -16806,7 +17218,7 @@ function getBaseDirsInLightOfGlobal({
16806
17218
  }
16807
17219
 
16808
17220
  // src/lib/generate.ts
16809
- var import_node_path116 = require("path");
17221
+ var import_node_path119 = require("path");
16810
17222
  var import_es_toolkit4 = require("es-toolkit");
16811
17223
  async function processFeatureGeneration(params) {
16812
17224
  const { config, processor, toolFiles } = params;
@@ -16860,7 +17272,7 @@ function warnUnsupportedTargets(params) {
16860
17272
  }
16861
17273
  }
16862
17274
  async function checkRulesyncDirExists(params) {
16863
- return fileExists((0, import_node_path116.join)(params.baseDir, RULESYNC_RELATIVE_DIR_PATH));
17275
+ return fileExists((0, import_node_path119.join)(params.baseDir, RULESYNC_RELATIVE_DIR_PATH));
16864
17276
  }
16865
17277
  async function generate(params) {
16866
17278
  const { config } = params;
@@ -17318,7 +17730,7 @@ async function generateCommand(options) {
17318
17730
  }
17319
17731
 
17320
17732
  // src/cli/commands/gitignore.ts
17321
- var import_node_path117 = require("path");
17733
+ var import_node_path120 = require("path");
17322
17734
  var RULESYNC_HEADER = "# Generated by Rulesync";
17323
17735
  var LEGACY_RULESYNC_HEADER = "# Generated by rulesync - AI tool configuration files";
17324
17736
  var RULESYNC_IGNORE_ENTRIES = [
@@ -17386,6 +17798,8 @@ var RULESYNC_IGNORE_ENTRIES = [
17386
17798
  // Junie
17387
17799
  "**/.junie/guidelines.md",
17388
17800
  "**/.junie/mcp.json",
17801
+ "**/.junie/skills/",
17802
+ "**/.junie/agents/",
17389
17803
  // Kilo Code
17390
17804
  "**/.kilocode/rules/",
17391
17805
  "**/.kilocode/skills/",
@@ -17474,7 +17888,7 @@ var removeExistingRulesyncEntries = (content) => {
17474
17888
  return result;
17475
17889
  };
17476
17890
  var gitignoreCommand = async () => {
17477
- const gitignorePath = (0, import_node_path117.join)(process.cwd(), ".gitignore");
17891
+ const gitignorePath = (0, import_node_path120.join)(process.cwd(), ".gitignore");
17478
17892
  let gitignoreContent = "";
17479
17893
  if (await fileExists(gitignorePath)) {
17480
17894
  gitignoreContent = await readFileContent(gitignorePath);
@@ -17761,7 +18175,7 @@ async function importCommand(options) {
17761
18175
  }
17762
18176
 
17763
18177
  // src/lib/init.ts
17764
- var import_node_path118 = require("path");
18178
+ var import_node_path121 = require("path");
17765
18179
  async function init() {
17766
18180
  const sampleFiles = await createSampleFiles();
17767
18181
  const configFile = await createConfigFile();
@@ -17951,27 +18365,27 @@ Keep the summary concise and ready to reuse in future tasks.`
17951
18365
  await ensureDir(subagentPaths.relativeDirPath);
17952
18366
  await ensureDir(skillPaths.relativeDirPath);
17953
18367
  await ensureDir(ignorePaths.recommended.relativeDirPath);
17954
- const ruleFilepath = (0, import_node_path118.join)(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
18368
+ const ruleFilepath = (0, import_node_path121.join)(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
17955
18369
  results.push(await writeIfNotExists(ruleFilepath, sampleRuleFile.content));
17956
- const mcpFilepath = (0, import_node_path118.join)(
18370
+ const mcpFilepath = (0, import_node_path121.join)(
17957
18371
  mcpPaths.recommended.relativeDirPath,
17958
18372
  mcpPaths.recommended.relativeFilePath
17959
18373
  );
17960
18374
  results.push(await writeIfNotExists(mcpFilepath, sampleMcpFile.content));
17961
- const commandFilepath = (0, import_node_path118.join)(commandPaths.relativeDirPath, sampleCommandFile.filename);
18375
+ const commandFilepath = (0, import_node_path121.join)(commandPaths.relativeDirPath, sampleCommandFile.filename);
17962
18376
  results.push(await writeIfNotExists(commandFilepath, sampleCommandFile.content));
17963
- const subagentFilepath = (0, import_node_path118.join)(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
18377
+ const subagentFilepath = (0, import_node_path121.join)(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
17964
18378
  results.push(await writeIfNotExists(subagentFilepath, sampleSubagentFile.content));
17965
- const skillDirPath = (0, import_node_path118.join)(skillPaths.relativeDirPath, sampleSkillFile.dirName);
18379
+ const skillDirPath = (0, import_node_path121.join)(skillPaths.relativeDirPath, sampleSkillFile.dirName);
17966
18380
  await ensureDir(skillDirPath);
17967
- const skillFilepath = (0, import_node_path118.join)(skillDirPath, SKILL_FILE_NAME);
18381
+ const skillFilepath = (0, import_node_path121.join)(skillDirPath, SKILL_FILE_NAME);
17968
18382
  results.push(await writeIfNotExists(skillFilepath, sampleSkillFile.content));
17969
- const ignoreFilepath = (0, import_node_path118.join)(
18383
+ const ignoreFilepath = (0, import_node_path121.join)(
17970
18384
  ignorePaths.recommended.relativeDirPath,
17971
18385
  ignorePaths.recommended.relativeFilePath
17972
18386
  );
17973
18387
  results.push(await writeIfNotExists(ignoreFilepath, sampleIgnoreFile.content));
17974
- const hooksFilepath = (0, import_node_path118.join)(hooksPaths.relativeDirPath, hooksPaths.relativeFilePath);
18388
+ const hooksFilepath = (0, import_node_path121.join)(hooksPaths.relativeDirPath, hooksPaths.relativeFilePath);
17975
18389
  results.push(await writeIfNotExists(hooksFilepath, sampleHooksFile.content));
17976
18390
  return results;
17977
18391
  }
@@ -18009,33 +18423,196 @@ async function initCommand() {
18009
18423
  }
18010
18424
 
18011
18425
  // src/lib/sources.ts
18012
- var import_node_path120 = require("path");
18426
+ var import_node_path124 = require("path");
18013
18427
  var import_promise2 = require("es-toolkit/promise");
18014
18428
 
18429
+ // src/lib/git-client.ts
18430
+ var import_node_child_process = require("child_process");
18431
+ var import_node_path122 = require("path");
18432
+ var import_node_util = require("util");
18433
+ var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
18434
+ var GIT_TIMEOUT_MS = 6e4;
18435
+ var ALLOWED_URL_SCHEMES = /^(https?:\/\/|ssh:\/\/|git:\/\/|file:\/\/\/|[a-zA-Z0-9_.+-]+@[a-zA-Z0-9.-]+:[a-zA-Z0-9_.+/~-]+)/;
18436
+ var INSECURE_URL_SCHEMES = /^(git:\/\/|http:\/\/)/;
18437
+ function findControlCharacter(value) {
18438
+ for (let i = 0; i < value.length; i++) {
18439
+ const code = value.charCodeAt(i);
18440
+ if (code >= 0 && code <= 31 || code === 127) {
18441
+ return { position: i, hex: `0x${code.toString(16).padStart(2, "0")}` };
18442
+ }
18443
+ }
18444
+ return null;
18445
+ }
18446
+ var GitClientError = class extends Error {
18447
+ constructor(message, cause) {
18448
+ super(message, { cause });
18449
+ this.name = "GitClientError";
18450
+ }
18451
+ };
18452
+ function validateGitUrl(url) {
18453
+ const ctrl = findControlCharacter(url);
18454
+ if (ctrl) {
18455
+ throw new GitClientError(
18456
+ `Git URL contains control character ${ctrl.hex} at position ${ctrl.position}`
18457
+ );
18458
+ }
18459
+ if (!ALLOWED_URL_SCHEMES.test(url)) {
18460
+ throw new GitClientError(
18461
+ `Unsupported or unsafe git URL: "${url}". Use https, ssh, git, or file schemes.`
18462
+ );
18463
+ }
18464
+ if (INSECURE_URL_SCHEMES.test(url)) {
18465
+ logger.warn(
18466
+ `URL "${url}" uses an unencrypted protocol. Consider using https:// or ssh:// instead.`
18467
+ );
18468
+ }
18469
+ }
18470
+ function validateRef(ref) {
18471
+ if (ref.startsWith("-")) {
18472
+ throw new GitClientError(`Ref must not start with "-": "${ref}"`);
18473
+ }
18474
+ const ctrl = findControlCharacter(ref);
18475
+ if (ctrl) {
18476
+ throw new GitClientError(
18477
+ `Ref contains control character ${ctrl.hex} at position ${ctrl.position}`
18478
+ );
18479
+ }
18480
+ }
18481
+ var gitChecked = false;
18482
+ async function checkGitAvailable() {
18483
+ if (gitChecked) return;
18484
+ try {
18485
+ await execFileAsync("git", ["--version"], { timeout: GIT_TIMEOUT_MS });
18486
+ gitChecked = true;
18487
+ } catch {
18488
+ throw new GitClientError("git is not installed or not found in PATH");
18489
+ }
18490
+ }
18491
+ async function resolveDefaultRef(url) {
18492
+ validateGitUrl(url);
18493
+ await checkGitAvailable();
18494
+ try {
18495
+ const { stdout } = await execFileAsync("git", ["ls-remote", "--symref", "--", url, "HEAD"], {
18496
+ timeout: GIT_TIMEOUT_MS
18497
+ });
18498
+ const ref = stdout.match(/^ref: refs\/heads\/(.+)\tHEAD$/m)?.[1];
18499
+ const sha = stdout.match(/^([0-9a-f]{40})\tHEAD$/m)?.[1];
18500
+ if (!ref || !sha) throw new GitClientError(`Could not parse default branch from: ${url}`);
18501
+ return { ref, sha };
18502
+ } catch (error) {
18503
+ if (error instanceof GitClientError) throw error;
18504
+ throw new GitClientError(`Failed to resolve default ref for ${url}`, error);
18505
+ }
18506
+ }
18507
+ async function resolveRefToSha(url, ref) {
18508
+ validateGitUrl(url);
18509
+ validateRef(ref);
18510
+ await checkGitAvailable();
18511
+ try {
18512
+ const { stdout } = await execFileAsync("git", ["ls-remote", "--", url, ref], {
18513
+ timeout: GIT_TIMEOUT_MS
18514
+ });
18515
+ const sha = stdout.match(/^([0-9a-f]{40})\t/m)?.[1];
18516
+ if (!sha) throw new GitClientError(`Ref "${ref}" not found in ${url}`);
18517
+ return sha;
18518
+ } catch (error) {
18519
+ if (error instanceof GitClientError) throw error;
18520
+ throw new GitClientError(`Failed to resolve ref "${ref}" for ${url}`, error);
18521
+ }
18522
+ }
18523
+ async function fetchSkillFiles(params) {
18524
+ const { url, ref, skillsPath } = params;
18525
+ validateGitUrl(url);
18526
+ validateRef(ref);
18527
+ await checkGitAvailable();
18528
+ const tmpDir = await createTempDirectory("rulesync-git-");
18529
+ try {
18530
+ await execFileAsync(
18531
+ "git",
18532
+ [
18533
+ "clone",
18534
+ "--depth",
18535
+ "1",
18536
+ "--branch",
18537
+ ref,
18538
+ "--no-checkout",
18539
+ "--filter=blob:none",
18540
+ "--",
18541
+ url,
18542
+ tmpDir
18543
+ ],
18544
+ { timeout: GIT_TIMEOUT_MS }
18545
+ );
18546
+ await execFileAsync("git", ["-C", tmpDir, "sparse-checkout", "set", "--", skillsPath], {
18547
+ timeout: GIT_TIMEOUT_MS
18548
+ });
18549
+ await execFileAsync("git", ["-C", tmpDir, "checkout"], { timeout: GIT_TIMEOUT_MS });
18550
+ const skillsDir = (0, import_node_path122.join)(tmpDir, skillsPath);
18551
+ if (!await directoryExists(skillsDir)) return [];
18552
+ return await walkDirectory(skillsDir, skillsDir);
18553
+ } catch (error) {
18554
+ if (error instanceof GitClientError) throw error;
18555
+ throw new GitClientError(`Failed to fetch skill files from ${url}`, error);
18556
+ } finally {
18557
+ await removeTempDirectory(tmpDir);
18558
+ }
18559
+ }
18560
+ var MAX_WALK_DEPTH = 20;
18561
+ async function walkDirectory(dir, baseDir, depth = 0) {
18562
+ if (depth > MAX_WALK_DEPTH) {
18563
+ throw new GitClientError(
18564
+ `Directory tree exceeds max depth of ${MAX_WALK_DEPTH}: "${dir}". Aborting to prevent resource exhaustion.`
18565
+ );
18566
+ }
18567
+ const results = [];
18568
+ for (const name of await listDirectoryFiles(dir)) {
18569
+ if (name === ".git") continue;
18570
+ const fullPath = (0, import_node_path122.join)(dir, name);
18571
+ if (await isSymlink(fullPath)) {
18572
+ logger.warn(`Skipping symlink "${fullPath}".`);
18573
+ continue;
18574
+ }
18575
+ if (await directoryExists(fullPath)) {
18576
+ results.push(...await walkDirectory(fullPath, baseDir, depth + 1));
18577
+ } else {
18578
+ const size = await getFileSize(fullPath);
18579
+ if (size > MAX_FILE_SIZE) {
18580
+ logger.warn(
18581
+ `Skipping file "${fullPath}" (${(size / 1024 / 1024).toFixed(2)}MB exceeds ${MAX_FILE_SIZE / 1024 / 1024}MB limit).`
18582
+ );
18583
+ continue;
18584
+ }
18585
+ const content = await readFileContent(fullPath);
18586
+ results.push({ relativePath: fullPath.substring(baseDir.length + 1), content, size });
18587
+ }
18588
+ }
18589
+ return results;
18590
+ }
18591
+
18015
18592
  // src/lib/sources-lock.ts
18016
18593
  var import_node_crypto = require("crypto");
18017
- var import_node_path119 = require("path");
18018
- var import_mini58 = require("zod/mini");
18594
+ var import_node_path123 = require("path");
18595
+ var import_mini60 = require("zod/mini");
18019
18596
  var LOCKFILE_VERSION = 1;
18020
- var LockedSkillSchema = import_mini58.z.object({
18021
- integrity: import_mini58.z.string()
18597
+ var LockedSkillSchema = import_mini60.z.object({
18598
+ integrity: import_mini60.z.string()
18022
18599
  });
18023
- var LockedSourceSchema = import_mini58.z.object({
18024
- requestedRef: (0, import_mini58.optional)(import_mini58.z.string()),
18025
- resolvedRef: import_mini58.z.string(),
18026
- resolvedAt: (0, import_mini58.optional)(import_mini58.z.string()),
18027
- skills: import_mini58.z.record(import_mini58.z.string(), LockedSkillSchema)
18600
+ var LockedSourceSchema = import_mini60.z.object({
18601
+ requestedRef: (0, import_mini60.optional)(import_mini60.z.string()),
18602
+ resolvedRef: import_mini60.z.string(),
18603
+ resolvedAt: (0, import_mini60.optional)(import_mini60.z.string()),
18604
+ skills: import_mini60.z.record(import_mini60.z.string(), LockedSkillSchema)
18028
18605
  });
18029
- var SourcesLockSchema = import_mini58.z.object({
18030
- lockfileVersion: import_mini58.z.number(),
18031
- sources: import_mini58.z.record(import_mini58.z.string(), LockedSourceSchema)
18606
+ var SourcesLockSchema = import_mini60.z.object({
18607
+ lockfileVersion: import_mini60.z.number(),
18608
+ sources: import_mini60.z.record(import_mini60.z.string(), LockedSourceSchema)
18032
18609
  });
18033
- var LegacyLockedSourceSchema = import_mini58.z.object({
18034
- resolvedRef: import_mini58.z.string(),
18035
- skills: import_mini58.z.array(import_mini58.z.string())
18610
+ var LegacyLockedSourceSchema = import_mini60.z.object({
18611
+ resolvedRef: import_mini60.z.string(),
18612
+ skills: import_mini60.z.array(import_mini60.z.string())
18036
18613
  });
18037
- var LegacySourcesLockSchema = import_mini58.z.object({
18038
- sources: import_mini58.z.record(import_mini58.z.string(), LegacyLockedSourceSchema)
18614
+ var LegacySourcesLockSchema = import_mini60.z.object({
18615
+ sources: import_mini60.z.record(import_mini60.z.string(), LegacyLockedSourceSchema)
18039
18616
  });
18040
18617
  function migrateLegacyLock(legacy) {
18041
18618
  const sources = {};
@@ -18058,7 +18635,7 @@ function createEmptyLock() {
18058
18635
  return { lockfileVersion: LOCKFILE_VERSION, sources: {} };
18059
18636
  }
18060
18637
  async function readLockFile(params) {
18061
- const lockPath = (0, import_node_path119.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
18638
+ const lockPath = (0, import_node_path123.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
18062
18639
  if (!await fileExists(lockPath)) {
18063
18640
  logger.debug("No sources lockfile found, starting fresh.");
18064
18641
  return createEmptyLock();
@@ -18086,7 +18663,7 @@ async function readLockFile(params) {
18086
18663
  }
18087
18664
  }
18088
18665
  async function writeLockFile(params) {
18089
- const lockPath = (0, import_node_path119.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
18666
+ const lockPath = (0, import_node_path123.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
18090
18667
  const content = JSON.stringify(params.lock, null, 2) + "\n";
18091
18668
  await writeFileContent(lockPath, content);
18092
18669
  logger.debug(`Wrote sources lockfile to ${lockPath}`);
@@ -18192,15 +18769,30 @@ async function resolveAndFetchSources(params) {
18192
18769
  const allFetchedSkillNames = /* @__PURE__ */ new Set();
18193
18770
  for (const sourceEntry of sources) {
18194
18771
  try {
18195
- const { skillCount, fetchedSkillNames, updatedLock } = await fetchSource({
18196
- sourceEntry,
18197
- client,
18198
- baseDir,
18199
- lock,
18200
- localSkillNames,
18201
- alreadyFetchedSkillNames: allFetchedSkillNames,
18202
- updateSources: options.updateSources ?? false
18203
- });
18772
+ const transport = sourceEntry.transport ?? "github";
18773
+ let result;
18774
+ if (transport === "git") {
18775
+ result = await fetchSourceViaGit({
18776
+ sourceEntry,
18777
+ baseDir,
18778
+ lock,
18779
+ localSkillNames,
18780
+ alreadyFetchedSkillNames: allFetchedSkillNames,
18781
+ updateSources: options.updateSources ?? false,
18782
+ frozen: options.frozen ?? false
18783
+ });
18784
+ } else {
18785
+ result = await fetchSource({
18786
+ sourceEntry,
18787
+ client,
18788
+ baseDir,
18789
+ lock,
18790
+ localSkillNames,
18791
+ alreadyFetchedSkillNames: allFetchedSkillNames,
18792
+ updateSources: options.updateSources ?? false
18793
+ });
18794
+ }
18795
+ const { skillCount, fetchedSkillNames, updatedLock } = result;
18204
18796
  lock = updatedLock;
18205
18797
  totalSkillCount += skillCount;
18206
18798
  for (const name of fetchedSkillNames) {
@@ -18233,7 +18825,7 @@ async function resolveAndFetchSources(params) {
18233
18825
  async function checkLockedSkillsExist(curatedDir, skillNames) {
18234
18826
  if (skillNames.length === 0) return true;
18235
18827
  for (const name of skillNames) {
18236
- if (!await directoryExists((0, import_node_path120.join)(curatedDir, name))) {
18828
+ if (!await directoryExists((0, import_node_path124.join)(curatedDir, name))) {
18237
18829
  return false;
18238
18830
  }
18239
18831
  }
@@ -18264,7 +18856,7 @@ async function fetchSource(params) {
18264
18856
  ref = resolvedSha;
18265
18857
  logger.debug(`Resolved ${sourceKey} ref "${requestedRef}" to SHA: ${resolvedSha}`);
18266
18858
  }
18267
- const curatedDir = (0, import_node_path120.join)(baseDir, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
18859
+ const curatedDir = (0, import_node_path124.join)(baseDir, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
18268
18860
  if (locked && resolvedSha === locked.resolvedRef && !updateSources) {
18269
18861
  const allExist = await checkLockedSkillsExist(curatedDir, lockedSkillNames);
18270
18862
  if (allExist) {
@@ -18294,10 +18886,10 @@ async function fetchSource(params) {
18294
18886
  const semaphore = new import_promise2.Semaphore(FETCH_CONCURRENCY_LIMIT);
18295
18887
  const fetchedSkills = {};
18296
18888
  if (locked) {
18297
- const resolvedCuratedDir = (0, import_node_path120.resolve)(curatedDir);
18889
+ const resolvedCuratedDir = (0, import_node_path124.resolve)(curatedDir);
18298
18890
  for (const prevSkill of lockedSkillNames) {
18299
- const prevDir = (0, import_node_path120.join)(curatedDir, prevSkill);
18300
- if (!(0, import_node_path120.resolve)(prevDir).startsWith(resolvedCuratedDir + import_node_path120.sep)) {
18891
+ const prevDir = (0, import_node_path124.join)(curatedDir, prevSkill);
18892
+ if (!(0, import_node_path124.resolve)(prevDir).startsWith(resolvedCuratedDir + import_node_path124.sep)) {
18301
18893
  logger.warn(
18302
18894
  `Skipping removal of "${prevSkill}": resolved path is outside the curated directory.`
18303
18895
  );
@@ -18347,10 +18939,10 @@ async function fetchSource(params) {
18347
18939
  const skillFiles = [];
18348
18940
  for (const file of files) {
18349
18941
  const relativeToSkill = file.path.substring(skillDir.path.length + 1);
18350
- const localFilePath = (0, import_node_path120.join)(curatedDir, skillDir.name, relativeToSkill);
18942
+ const localFilePath = (0, import_node_path124.join)(curatedDir, skillDir.name, relativeToSkill);
18351
18943
  checkPathTraversal({
18352
18944
  relativePath: relativeToSkill,
18353
- intendedRootDir: (0, import_node_path120.join)(curatedDir, skillDir.name)
18945
+ intendedRootDir: (0, import_node_path124.join)(curatedDir, skillDir.name)
18354
18946
  });
18355
18947
  const content = await withSemaphore(
18356
18948
  semaphore,
@@ -18393,6 +18985,127 @@ async function fetchSource(params) {
18393
18985
  updatedLock: lock
18394
18986
  };
18395
18987
  }
18988
+ async function fetchSourceViaGit(params) {
18989
+ const { sourceEntry, baseDir, localSkillNames, alreadyFetchedSkillNames, updateSources, frozen } = params;
18990
+ let { lock } = params;
18991
+ const url = sourceEntry.source;
18992
+ const locked = getLockedSource(lock, url);
18993
+ const lockedSkillNames = locked ? getLockedSkillNames(locked) : [];
18994
+ let resolvedSha;
18995
+ let requestedRef;
18996
+ if (locked && !updateSources) {
18997
+ resolvedSha = locked.resolvedRef;
18998
+ requestedRef = locked.requestedRef;
18999
+ if (requestedRef) {
19000
+ validateRef(requestedRef);
19001
+ }
19002
+ } else if (sourceEntry.ref) {
19003
+ requestedRef = sourceEntry.ref;
19004
+ resolvedSha = await resolveRefToSha(url, requestedRef);
19005
+ } else {
19006
+ const def = await resolveDefaultRef(url);
19007
+ requestedRef = def.ref;
19008
+ resolvedSha = def.sha;
19009
+ }
19010
+ const curatedDir = (0, import_node_path124.join)(baseDir, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
19011
+ if (locked && resolvedSha === locked.resolvedRef && !updateSources) {
19012
+ if (await checkLockedSkillsExist(curatedDir, lockedSkillNames)) {
19013
+ return { skillCount: 0, fetchedSkillNames: lockedSkillNames, updatedLock: lock };
19014
+ }
19015
+ }
19016
+ if (!requestedRef) {
19017
+ if (frozen) {
19018
+ throw new Error(
19019
+ `Frozen install failed: lockfile entry for "${url}" is missing requestedRef. Run 'rulesync install' to update the lockfile.`
19020
+ );
19021
+ }
19022
+ const def = await resolveDefaultRef(url);
19023
+ requestedRef = def.ref;
19024
+ resolvedSha = def.sha;
19025
+ }
19026
+ const skillFilter = sourceEntry.skills ?? ["*"];
19027
+ const isWildcard = skillFilter.length === 1 && skillFilter[0] === "*";
19028
+ const remoteFiles = await fetchSkillFiles({
19029
+ url,
19030
+ ref: requestedRef,
19031
+ skillsPath: sourceEntry.path ?? "skills"
19032
+ });
19033
+ const skillFileMap = /* @__PURE__ */ new Map();
19034
+ for (const file of remoteFiles) {
19035
+ const idx = file.relativePath.indexOf("/");
19036
+ if (idx === -1) continue;
19037
+ const name = file.relativePath.substring(0, idx);
19038
+ const inner = file.relativePath.substring(idx + 1);
19039
+ const arr = skillFileMap.get(name) ?? [];
19040
+ arr.push({ relativePath: inner, content: file.content });
19041
+ skillFileMap.set(name, arr);
19042
+ }
19043
+ const allNames = [...skillFileMap.keys()];
19044
+ const filteredNames = isWildcard ? allNames : allNames.filter((n) => skillFilter.includes(n));
19045
+ if (locked) {
19046
+ const base = (0, import_node_path124.resolve)(curatedDir);
19047
+ for (const prev of lockedSkillNames) {
19048
+ const dir = (0, import_node_path124.join)(curatedDir, prev);
19049
+ if ((0, import_node_path124.resolve)(dir).startsWith(base + import_node_path124.sep) && await directoryExists(dir)) {
19050
+ await removeDirectory(dir);
19051
+ }
19052
+ }
19053
+ }
19054
+ const fetchedSkills = {};
19055
+ for (const skillName of filteredNames) {
19056
+ if (skillName.includes("..") || skillName.includes("/") || skillName.includes("\\")) {
19057
+ logger.warn(
19058
+ `Skipping skill with invalid name "${skillName}" from ${url}: contains path traversal characters.`
19059
+ );
19060
+ continue;
19061
+ }
19062
+ if (localSkillNames.has(skillName)) {
19063
+ logger.debug(
19064
+ `Skipping remote skill "${skillName}" from ${url}: local skill takes precedence.`
19065
+ );
19066
+ continue;
19067
+ }
19068
+ if (alreadyFetchedSkillNames.has(skillName)) {
19069
+ logger.warn(
19070
+ `Skipping duplicate skill "${skillName}" from ${url}: already fetched from another source.`
19071
+ );
19072
+ continue;
19073
+ }
19074
+ const files = skillFileMap.get(skillName) ?? [];
19075
+ const written = [];
19076
+ for (const file of files) {
19077
+ checkPathTraversal({
19078
+ relativePath: file.relativePath,
19079
+ intendedRootDir: (0, import_node_path124.join)(curatedDir, skillName)
19080
+ });
19081
+ await writeFileContent((0, import_node_path124.join)(curatedDir, skillName, file.relativePath), file.content);
19082
+ written.push({ path: file.relativePath, content: file.content });
19083
+ }
19084
+ const integrity = computeSkillIntegrity(written);
19085
+ const lockedSkillEntry = locked?.skills[skillName];
19086
+ if (lockedSkillEntry?.integrity && lockedSkillEntry.integrity !== integrity && resolvedSha === locked?.resolvedRef) {
19087
+ logger.warn(`Integrity mismatch for skill "${skillName}" from ${url}.`);
19088
+ }
19089
+ fetchedSkills[skillName] = { integrity };
19090
+ }
19091
+ const fetchedNames = Object.keys(fetchedSkills);
19092
+ const mergedSkills = { ...fetchedSkills };
19093
+ if (locked) {
19094
+ for (const [k, v] of Object.entries(locked.skills)) {
19095
+ if (!(k in mergedSkills)) mergedSkills[k] = v;
19096
+ }
19097
+ }
19098
+ lock = setLockedSource(lock, url, {
19099
+ requestedRef,
19100
+ resolvedRef: resolvedSha,
19101
+ resolvedAt: (/* @__PURE__ */ new Date()).toISOString(),
19102
+ skills: mergedSkills
19103
+ });
19104
+ logger.info(
19105
+ `Fetched ${fetchedNames.length} skill(s) from ${url}: ${fetchedNames.join(", ") || "(none)"}`
19106
+ );
19107
+ return { skillCount: fetchedNames.length, fetchedSkillNames: fetchedNames, updatedLock: lock };
19108
+ }
18396
19109
 
18397
19110
  // src/cli/commands/install.ts
18398
19111
  async function installCommand(options) {
@@ -18433,15 +19146,15 @@ async function installCommand(options) {
18433
19146
  var import_fastmcp = require("fastmcp");
18434
19147
 
18435
19148
  // src/mcp/tools.ts
18436
- var import_mini67 = require("zod/mini");
19149
+ var import_mini69 = require("zod/mini");
18437
19150
 
18438
19151
  // src/mcp/commands.ts
18439
- var import_node_path121 = require("path");
18440
- var import_mini59 = require("zod/mini");
19152
+ var import_node_path125 = require("path");
19153
+ var import_mini61 = require("zod/mini");
18441
19154
  var maxCommandSizeBytes = 1024 * 1024;
18442
19155
  var maxCommandsCount = 1e3;
18443
19156
  async function listCommands() {
18444
- const commandsDir = (0, import_node_path121.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
19157
+ const commandsDir = (0, import_node_path125.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
18445
19158
  try {
18446
19159
  const files = await listDirectoryFiles(commandsDir);
18447
19160
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -18457,7 +19170,7 @@ async function listCommands() {
18457
19170
  });
18458
19171
  const frontmatter = command.getFrontmatter();
18459
19172
  return {
18460
- relativePathFromCwd: (0, import_node_path121.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
19173
+ relativePathFromCwd: (0, import_node_path125.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
18461
19174
  frontmatter
18462
19175
  };
18463
19176
  } catch (error) {
@@ -18479,13 +19192,13 @@ async function getCommand({ relativePathFromCwd }) {
18479
19192
  relativePath: relativePathFromCwd,
18480
19193
  intendedRootDir: process.cwd()
18481
19194
  });
18482
- const filename = (0, import_node_path121.basename)(relativePathFromCwd);
19195
+ const filename = (0, import_node_path125.basename)(relativePathFromCwd);
18483
19196
  try {
18484
19197
  const command = await RulesyncCommand.fromFile({
18485
19198
  relativeFilePath: filename
18486
19199
  });
18487
19200
  return {
18488
- relativePathFromCwd: (0, import_node_path121.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
19201
+ relativePathFromCwd: (0, import_node_path125.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
18489
19202
  frontmatter: command.getFrontmatter(),
18490
19203
  body: command.getBody()
18491
19204
  };
@@ -18504,7 +19217,7 @@ async function putCommand({
18504
19217
  relativePath: relativePathFromCwd,
18505
19218
  intendedRootDir: process.cwd()
18506
19219
  });
18507
- const filename = (0, import_node_path121.basename)(relativePathFromCwd);
19220
+ const filename = (0, import_node_path125.basename)(relativePathFromCwd);
18508
19221
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
18509
19222
  if (estimatedSize > maxCommandSizeBytes) {
18510
19223
  throw new Error(
@@ -18514,7 +19227,7 @@ async function putCommand({
18514
19227
  try {
18515
19228
  const existingCommands = await listCommands();
18516
19229
  const isUpdate = existingCommands.some(
18517
- (command2) => command2.relativePathFromCwd === (0, import_node_path121.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
19230
+ (command2) => command2.relativePathFromCwd === (0, import_node_path125.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
18518
19231
  );
18519
19232
  if (!isUpdate && existingCommands.length >= maxCommandsCount) {
18520
19233
  throw new Error(
@@ -18531,11 +19244,11 @@ async function putCommand({
18531
19244
  fileContent,
18532
19245
  validate: true
18533
19246
  });
18534
- const commandsDir = (0, import_node_path121.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
19247
+ const commandsDir = (0, import_node_path125.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
18535
19248
  await ensureDir(commandsDir);
18536
19249
  await writeFileContent(command.getFilePath(), command.getFileContent());
18537
19250
  return {
18538
- relativePathFromCwd: (0, import_node_path121.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
19251
+ relativePathFromCwd: (0, import_node_path125.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
18539
19252
  frontmatter: command.getFrontmatter(),
18540
19253
  body: command.getBody()
18541
19254
  };
@@ -18550,12 +19263,12 @@ async function deleteCommand({ relativePathFromCwd }) {
18550
19263
  relativePath: relativePathFromCwd,
18551
19264
  intendedRootDir: process.cwd()
18552
19265
  });
18553
- const filename = (0, import_node_path121.basename)(relativePathFromCwd);
18554
- const fullPath = (0, import_node_path121.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
19266
+ const filename = (0, import_node_path125.basename)(relativePathFromCwd);
19267
+ const fullPath = (0, import_node_path125.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
18555
19268
  try {
18556
19269
  await removeFile(fullPath);
18557
19270
  return {
18558
- relativePathFromCwd: (0, import_node_path121.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
19271
+ relativePathFromCwd: (0, import_node_path125.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
18559
19272
  };
18560
19273
  } catch (error) {
18561
19274
  throw new Error(`Failed to delete command file ${relativePathFromCwd}: ${formatError(error)}`, {
@@ -18564,23 +19277,23 @@ async function deleteCommand({ relativePathFromCwd }) {
18564
19277
  }
18565
19278
  }
18566
19279
  var commandToolSchemas = {
18567
- listCommands: import_mini59.z.object({}),
18568
- getCommand: import_mini59.z.object({
18569
- relativePathFromCwd: import_mini59.z.string()
19280
+ listCommands: import_mini61.z.object({}),
19281
+ getCommand: import_mini61.z.object({
19282
+ relativePathFromCwd: import_mini61.z.string()
18570
19283
  }),
18571
- putCommand: import_mini59.z.object({
18572
- relativePathFromCwd: import_mini59.z.string(),
19284
+ putCommand: import_mini61.z.object({
19285
+ relativePathFromCwd: import_mini61.z.string(),
18573
19286
  frontmatter: RulesyncCommandFrontmatterSchema,
18574
- body: import_mini59.z.string()
19287
+ body: import_mini61.z.string()
18575
19288
  }),
18576
- deleteCommand: import_mini59.z.object({
18577
- relativePathFromCwd: import_mini59.z.string()
19289
+ deleteCommand: import_mini61.z.object({
19290
+ relativePathFromCwd: import_mini61.z.string()
18578
19291
  })
18579
19292
  };
18580
19293
  var commandTools = {
18581
19294
  listCommands: {
18582
19295
  name: "listCommands",
18583
- description: `List all commands from ${(0, import_node_path121.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
19296
+ description: `List all commands from ${(0, import_node_path125.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
18584
19297
  parameters: commandToolSchemas.listCommands,
18585
19298
  execute: async () => {
18586
19299
  const commands = await listCommands();
@@ -18622,15 +19335,15 @@ var commandTools = {
18622
19335
  };
18623
19336
 
18624
19337
  // src/mcp/generate.ts
18625
- var import_mini60 = require("zod/mini");
18626
- var generateOptionsSchema = import_mini60.z.object({
18627
- targets: import_mini60.z.optional(import_mini60.z.array(import_mini60.z.string())),
18628
- features: import_mini60.z.optional(import_mini60.z.array(import_mini60.z.string())),
18629
- delete: import_mini60.z.optional(import_mini60.z.boolean()),
18630
- global: import_mini60.z.optional(import_mini60.z.boolean()),
18631
- simulateCommands: import_mini60.z.optional(import_mini60.z.boolean()),
18632
- simulateSubagents: import_mini60.z.optional(import_mini60.z.boolean()),
18633
- simulateSkills: import_mini60.z.optional(import_mini60.z.boolean())
19338
+ var import_mini62 = require("zod/mini");
19339
+ var generateOptionsSchema = import_mini62.z.object({
19340
+ targets: import_mini62.z.optional(import_mini62.z.array(import_mini62.z.string())),
19341
+ features: import_mini62.z.optional(import_mini62.z.array(import_mini62.z.string())),
19342
+ delete: import_mini62.z.optional(import_mini62.z.boolean()),
19343
+ global: import_mini62.z.optional(import_mini62.z.boolean()),
19344
+ simulateCommands: import_mini62.z.optional(import_mini62.z.boolean()),
19345
+ simulateSubagents: import_mini62.z.optional(import_mini62.z.boolean()),
19346
+ simulateSkills: import_mini62.z.optional(import_mini62.z.boolean())
18634
19347
  });
18635
19348
  async function executeGenerate(options = {}) {
18636
19349
  try {
@@ -18707,11 +19420,11 @@ var generateTools = {
18707
19420
  };
18708
19421
 
18709
19422
  // src/mcp/ignore.ts
18710
- var import_node_path122 = require("path");
18711
- var import_mini61 = require("zod/mini");
19423
+ var import_node_path126 = require("path");
19424
+ var import_mini63 = require("zod/mini");
18712
19425
  var maxIgnoreFileSizeBytes = 100 * 1024;
18713
19426
  async function getIgnoreFile() {
18714
- const ignoreFilePath = (0, import_node_path122.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
19427
+ const ignoreFilePath = (0, import_node_path126.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
18715
19428
  try {
18716
19429
  const content = await readFileContent(ignoreFilePath);
18717
19430
  return {
@@ -18728,7 +19441,7 @@ async function getIgnoreFile() {
18728
19441
  }
18729
19442
  }
18730
19443
  async function putIgnoreFile({ content }) {
18731
- const ignoreFilePath = (0, import_node_path122.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
19444
+ const ignoreFilePath = (0, import_node_path126.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
18732
19445
  const contentSizeBytes = Buffer.byteLength(content, "utf8");
18733
19446
  if (contentSizeBytes > maxIgnoreFileSizeBytes) {
18734
19447
  throw new Error(
@@ -18752,8 +19465,8 @@ async function putIgnoreFile({ content }) {
18752
19465
  }
18753
19466
  }
18754
19467
  async function deleteIgnoreFile() {
18755
- const aiignorePath = (0, import_node_path122.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
18756
- const legacyIgnorePath = (0, import_node_path122.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
19468
+ const aiignorePath = (0, import_node_path126.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
19469
+ const legacyIgnorePath = (0, import_node_path126.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
18757
19470
  try {
18758
19471
  await Promise.all([removeFile(aiignorePath), removeFile(legacyIgnorePath)]);
18759
19472
  return {
@@ -18771,11 +19484,11 @@ async function deleteIgnoreFile() {
18771
19484
  }
18772
19485
  }
18773
19486
  var ignoreToolSchemas = {
18774
- getIgnoreFile: import_mini61.z.object({}),
18775
- putIgnoreFile: import_mini61.z.object({
18776
- content: import_mini61.z.string()
19487
+ getIgnoreFile: import_mini63.z.object({}),
19488
+ putIgnoreFile: import_mini63.z.object({
19489
+ content: import_mini63.z.string()
18777
19490
  }),
18778
- deleteIgnoreFile: import_mini61.z.object({})
19491
+ deleteIgnoreFile: import_mini63.z.object({})
18779
19492
  };
18780
19493
  var ignoreTools = {
18781
19494
  getIgnoreFile: {
@@ -18808,11 +19521,11 @@ var ignoreTools = {
18808
19521
  };
18809
19522
 
18810
19523
  // src/mcp/import.ts
18811
- var import_mini62 = require("zod/mini");
18812
- var importOptionsSchema = import_mini62.z.object({
18813
- target: import_mini62.z.string(),
18814
- features: import_mini62.z.optional(import_mini62.z.array(import_mini62.z.string())),
18815
- global: import_mini62.z.optional(import_mini62.z.boolean())
19524
+ var import_mini64 = require("zod/mini");
19525
+ var importOptionsSchema = import_mini64.z.object({
19526
+ target: import_mini64.z.string(),
19527
+ features: import_mini64.z.optional(import_mini64.z.array(import_mini64.z.string())),
19528
+ global: import_mini64.z.optional(import_mini64.z.boolean())
18816
19529
  });
18817
19530
  async function executeImport(options) {
18818
19531
  try {
@@ -18881,15 +19594,15 @@ var importTools = {
18881
19594
  };
18882
19595
 
18883
19596
  // src/mcp/mcp.ts
18884
- var import_node_path123 = require("path");
18885
- var import_mini63 = require("zod/mini");
19597
+ var import_node_path127 = require("path");
19598
+ var import_mini65 = require("zod/mini");
18886
19599
  var maxMcpSizeBytes = 1024 * 1024;
18887
19600
  async function getMcpFile() {
18888
19601
  try {
18889
19602
  const rulesyncMcp = await RulesyncMcp.fromFile({
18890
19603
  validate: true
18891
19604
  });
18892
- const relativePathFromCwd = (0, import_node_path123.join)(
19605
+ const relativePathFromCwd = (0, import_node_path127.join)(
18893
19606
  rulesyncMcp.getRelativeDirPath(),
18894
19607
  rulesyncMcp.getRelativeFilePath()
18895
19608
  );
@@ -18927,7 +19640,7 @@ async function putMcpFile({ content }) {
18927
19640
  const paths = RulesyncMcp.getSettablePaths();
18928
19641
  const relativeDirPath = paths.recommended.relativeDirPath;
18929
19642
  const relativeFilePath = paths.recommended.relativeFilePath;
18930
- const fullPath = (0, import_node_path123.join)(baseDir, relativeDirPath, relativeFilePath);
19643
+ const fullPath = (0, import_node_path127.join)(baseDir, relativeDirPath, relativeFilePath);
18931
19644
  const rulesyncMcp = new RulesyncMcp({
18932
19645
  baseDir,
18933
19646
  relativeDirPath,
@@ -18935,9 +19648,9 @@ async function putMcpFile({ content }) {
18935
19648
  fileContent: content,
18936
19649
  validate: true
18937
19650
  });
18938
- await ensureDir((0, import_node_path123.join)(baseDir, relativeDirPath));
19651
+ await ensureDir((0, import_node_path127.join)(baseDir, relativeDirPath));
18939
19652
  await writeFileContent(fullPath, content);
18940
- const relativePathFromCwd = (0, import_node_path123.join)(relativeDirPath, relativeFilePath);
19653
+ const relativePathFromCwd = (0, import_node_path127.join)(relativeDirPath, relativeFilePath);
18941
19654
  return {
18942
19655
  relativePathFromCwd,
18943
19656
  content: rulesyncMcp.getFileContent()
@@ -18955,15 +19668,15 @@ async function deleteMcpFile() {
18955
19668
  try {
18956
19669
  const baseDir = process.cwd();
18957
19670
  const paths = RulesyncMcp.getSettablePaths();
18958
- const recommendedPath = (0, import_node_path123.join)(
19671
+ const recommendedPath = (0, import_node_path127.join)(
18959
19672
  baseDir,
18960
19673
  paths.recommended.relativeDirPath,
18961
19674
  paths.recommended.relativeFilePath
18962
19675
  );
18963
- const legacyPath = (0, import_node_path123.join)(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
19676
+ const legacyPath = (0, import_node_path127.join)(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
18964
19677
  await removeFile(recommendedPath);
18965
19678
  await removeFile(legacyPath);
18966
- const relativePathFromCwd = (0, import_node_path123.join)(
19679
+ const relativePathFromCwd = (0, import_node_path127.join)(
18967
19680
  paths.recommended.relativeDirPath,
18968
19681
  paths.recommended.relativeFilePath
18969
19682
  );
@@ -18980,11 +19693,11 @@ async function deleteMcpFile() {
18980
19693
  }
18981
19694
  }
18982
19695
  var mcpToolSchemas = {
18983
- getMcpFile: import_mini63.z.object({}),
18984
- putMcpFile: import_mini63.z.object({
18985
- content: import_mini63.z.string()
19696
+ getMcpFile: import_mini65.z.object({}),
19697
+ putMcpFile: import_mini65.z.object({
19698
+ content: import_mini65.z.string()
18986
19699
  }),
18987
- deleteMcpFile: import_mini63.z.object({})
19700
+ deleteMcpFile: import_mini65.z.object({})
18988
19701
  };
18989
19702
  var mcpTools = {
18990
19703
  getMcpFile: {
@@ -19017,12 +19730,12 @@ var mcpTools = {
19017
19730
  };
19018
19731
 
19019
19732
  // src/mcp/rules.ts
19020
- var import_node_path124 = require("path");
19021
- var import_mini64 = require("zod/mini");
19733
+ var import_node_path128 = require("path");
19734
+ var import_mini66 = require("zod/mini");
19022
19735
  var maxRuleSizeBytes = 1024 * 1024;
19023
19736
  var maxRulesCount = 1e3;
19024
19737
  async function listRules() {
19025
- const rulesDir = (0, import_node_path124.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
19738
+ const rulesDir = (0, import_node_path128.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
19026
19739
  try {
19027
19740
  const files = await listDirectoryFiles(rulesDir);
19028
19741
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -19035,7 +19748,7 @@ async function listRules() {
19035
19748
  });
19036
19749
  const frontmatter = rule.getFrontmatter();
19037
19750
  return {
19038
- relativePathFromCwd: (0, import_node_path124.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
19751
+ relativePathFromCwd: (0, import_node_path128.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
19039
19752
  frontmatter
19040
19753
  };
19041
19754
  } catch (error) {
@@ -19057,14 +19770,14 @@ async function getRule({ relativePathFromCwd }) {
19057
19770
  relativePath: relativePathFromCwd,
19058
19771
  intendedRootDir: process.cwd()
19059
19772
  });
19060
- const filename = (0, import_node_path124.basename)(relativePathFromCwd);
19773
+ const filename = (0, import_node_path128.basename)(relativePathFromCwd);
19061
19774
  try {
19062
19775
  const rule = await RulesyncRule.fromFile({
19063
19776
  relativeFilePath: filename,
19064
19777
  validate: true
19065
19778
  });
19066
19779
  return {
19067
- relativePathFromCwd: (0, import_node_path124.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
19780
+ relativePathFromCwd: (0, import_node_path128.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
19068
19781
  frontmatter: rule.getFrontmatter(),
19069
19782
  body: rule.getBody()
19070
19783
  };
@@ -19083,7 +19796,7 @@ async function putRule({
19083
19796
  relativePath: relativePathFromCwd,
19084
19797
  intendedRootDir: process.cwd()
19085
19798
  });
19086
- const filename = (0, import_node_path124.basename)(relativePathFromCwd);
19799
+ const filename = (0, import_node_path128.basename)(relativePathFromCwd);
19087
19800
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
19088
19801
  if (estimatedSize > maxRuleSizeBytes) {
19089
19802
  throw new Error(
@@ -19093,7 +19806,7 @@ async function putRule({
19093
19806
  try {
19094
19807
  const existingRules = await listRules();
19095
19808
  const isUpdate = existingRules.some(
19096
- (rule2) => rule2.relativePathFromCwd === (0, import_node_path124.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
19809
+ (rule2) => rule2.relativePathFromCwd === (0, import_node_path128.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
19097
19810
  );
19098
19811
  if (!isUpdate && existingRules.length >= maxRulesCount) {
19099
19812
  throw new Error(
@@ -19108,11 +19821,11 @@ async function putRule({
19108
19821
  body,
19109
19822
  validate: true
19110
19823
  });
19111
- const rulesDir = (0, import_node_path124.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
19824
+ const rulesDir = (0, import_node_path128.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
19112
19825
  await ensureDir(rulesDir);
19113
19826
  await writeFileContent(rule.getFilePath(), rule.getFileContent());
19114
19827
  return {
19115
- relativePathFromCwd: (0, import_node_path124.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
19828
+ relativePathFromCwd: (0, import_node_path128.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
19116
19829
  frontmatter: rule.getFrontmatter(),
19117
19830
  body: rule.getBody()
19118
19831
  };
@@ -19127,12 +19840,12 @@ async function deleteRule({ relativePathFromCwd }) {
19127
19840
  relativePath: relativePathFromCwd,
19128
19841
  intendedRootDir: process.cwd()
19129
19842
  });
19130
- const filename = (0, import_node_path124.basename)(relativePathFromCwd);
19131
- const fullPath = (0, import_node_path124.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
19843
+ const filename = (0, import_node_path128.basename)(relativePathFromCwd);
19844
+ const fullPath = (0, import_node_path128.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
19132
19845
  try {
19133
19846
  await removeFile(fullPath);
19134
19847
  return {
19135
- relativePathFromCwd: (0, import_node_path124.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
19848
+ relativePathFromCwd: (0, import_node_path128.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
19136
19849
  };
19137
19850
  } catch (error) {
19138
19851
  throw new Error(`Failed to delete rule file ${relativePathFromCwd}: ${formatError(error)}`, {
@@ -19141,23 +19854,23 @@ async function deleteRule({ relativePathFromCwd }) {
19141
19854
  }
19142
19855
  }
19143
19856
  var ruleToolSchemas = {
19144
- listRules: import_mini64.z.object({}),
19145
- getRule: import_mini64.z.object({
19146
- relativePathFromCwd: import_mini64.z.string()
19857
+ listRules: import_mini66.z.object({}),
19858
+ getRule: import_mini66.z.object({
19859
+ relativePathFromCwd: import_mini66.z.string()
19147
19860
  }),
19148
- putRule: import_mini64.z.object({
19149
- relativePathFromCwd: import_mini64.z.string(),
19861
+ putRule: import_mini66.z.object({
19862
+ relativePathFromCwd: import_mini66.z.string(),
19150
19863
  frontmatter: RulesyncRuleFrontmatterSchema,
19151
- body: import_mini64.z.string()
19864
+ body: import_mini66.z.string()
19152
19865
  }),
19153
- deleteRule: import_mini64.z.object({
19154
- relativePathFromCwd: import_mini64.z.string()
19866
+ deleteRule: import_mini66.z.object({
19867
+ relativePathFromCwd: import_mini66.z.string()
19155
19868
  })
19156
19869
  };
19157
19870
  var ruleTools = {
19158
19871
  listRules: {
19159
19872
  name: "listRules",
19160
- description: `List all rules from ${(0, import_node_path124.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
19873
+ description: `List all rules from ${(0, import_node_path128.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
19161
19874
  parameters: ruleToolSchemas.listRules,
19162
19875
  execute: async () => {
19163
19876
  const rules = await listRules();
@@ -19199,8 +19912,8 @@ var ruleTools = {
19199
19912
  };
19200
19913
 
19201
19914
  // src/mcp/skills.ts
19202
- var import_node_path125 = require("path");
19203
- var import_mini65 = require("zod/mini");
19915
+ var import_node_path129 = require("path");
19916
+ var import_mini67 = require("zod/mini");
19204
19917
  var maxSkillSizeBytes = 1024 * 1024;
19205
19918
  var maxSkillsCount = 1e3;
19206
19919
  function aiDirFileToMcpSkillFile(file) {
@@ -19216,19 +19929,19 @@ function mcpSkillFileToAiDirFile(file) {
19216
19929
  };
19217
19930
  }
19218
19931
  function extractDirName(relativeDirPathFromCwd) {
19219
- const dirName = (0, import_node_path125.basename)(relativeDirPathFromCwd);
19932
+ const dirName = (0, import_node_path129.basename)(relativeDirPathFromCwd);
19220
19933
  if (!dirName) {
19221
19934
  throw new Error(`Invalid path: ${relativeDirPathFromCwd}`);
19222
19935
  }
19223
19936
  return dirName;
19224
19937
  }
19225
19938
  async function listSkills() {
19226
- const skillsDir = (0, import_node_path125.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH);
19939
+ const skillsDir = (0, import_node_path129.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH);
19227
19940
  try {
19228
- const skillDirPaths = await findFilesByGlobs((0, import_node_path125.join)(skillsDir, "*"), { type: "dir" });
19941
+ const skillDirPaths = await findFilesByGlobs((0, import_node_path129.join)(skillsDir, "*"), { type: "dir" });
19229
19942
  const skills = await Promise.all(
19230
19943
  skillDirPaths.map(async (dirPath) => {
19231
- const dirName = (0, import_node_path125.basename)(dirPath);
19944
+ const dirName = (0, import_node_path129.basename)(dirPath);
19232
19945
  if (!dirName) return null;
19233
19946
  try {
19234
19947
  const skill = await RulesyncSkill.fromDir({
@@ -19236,7 +19949,7 @@ async function listSkills() {
19236
19949
  });
19237
19950
  const frontmatter = skill.getFrontmatter();
19238
19951
  return {
19239
- relativeDirPathFromCwd: (0, import_node_path125.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
19952
+ relativeDirPathFromCwd: (0, import_node_path129.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
19240
19953
  frontmatter
19241
19954
  };
19242
19955
  } catch (error) {
@@ -19264,7 +19977,7 @@ async function getSkill({ relativeDirPathFromCwd }) {
19264
19977
  dirName
19265
19978
  });
19266
19979
  return {
19267
- relativeDirPathFromCwd: (0, import_node_path125.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
19980
+ relativeDirPathFromCwd: (0, import_node_path129.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
19268
19981
  frontmatter: skill.getFrontmatter(),
19269
19982
  body: skill.getBody(),
19270
19983
  otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
@@ -19298,7 +20011,7 @@ async function putSkill({
19298
20011
  try {
19299
20012
  const existingSkills = await listSkills();
19300
20013
  const isUpdate = existingSkills.some(
19301
- (skill2) => skill2.relativeDirPathFromCwd === (0, import_node_path125.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
20014
+ (skill2) => skill2.relativeDirPathFromCwd === (0, import_node_path129.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
19302
20015
  );
19303
20016
  if (!isUpdate && existingSkills.length >= maxSkillsCount) {
19304
20017
  throw new Error(
@@ -19315,9 +20028,9 @@ async function putSkill({
19315
20028
  otherFiles: aiDirFiles,
19316
20029
  validate: true
19317
20030
  });
19318
- const skillDirPath = (0, import_node_path125.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
20031
+ const skillDirPath = (0, import_node_path129.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
19319
20032
  await ensureDir(skillDirPath);
19320
- const skillFilePath = (0, import_node_path125.join)(skillDirPath, SKILL_FILE_NAME);
20033
+ const skillFilePath = (0, import_node_path129.join)(skillDirPath, SKILL_FILE_NAME);
19321
20034
  const skillFileContent = stringifyFrontmatter(body, frontmatter);
19322
20035
  await writeFileContent(skillFilePath, skillFileContent);
19323
20036
  for (const file of otherFiles) {
@@ -19325,15 +20038,15 @@ async function putSkill({
19325
20038
  relativePath: file.name,
19326
20039
  intendedRootDir: skillDirPath
19327
20040
  });
19328
- const filePath = (0, import_node_path125.join)(skillDirPath, file.name);
19329
- const fileDir = (0, import_node_path125.join)(skillDirPath, (0, import_node_path125.dirname)(file.name));
20041
+ const filePath = (0, import_node_path129.join)(skillDirPath, file.name);
20042
+ const fileDir = (0, import_node_path129.join)(skillDirPath, (0, import_node_path129.dirname)(file.name));
19330
20043
  if (fileDir !== skillDirPath) {
19331
20044
  await ensureDir(fileDir);
19332
20045
  }
19333
20046
  await writeFileContent(filePath, file.body);
19334
20047
  }
19335
20048
  return {
19336
- relativeDirPathFromCwd: (0, import_node_path125.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
20049
+ relativeDirPathFromCwd: (0, import_node_path129.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
19337
20050
  frontmatter: skill.getFrontmatter(),
19338
20051
  body: skill.getBody(),
19339
20052
  otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
@@ -19355,13 +20068,13 @@ async function deleteSkill({
19355
20068
  intendedRootDir: process.cwd()
19356
20069
  });
19357
20070
  const dirName = extractDirName(relativeDirPathFromCwd);
19358
- const skillDirPath = (0, import_node_path125.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
20071
+ const skillDirPath = (0, import_node_path129.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
19359
20072
  try {
19360
20073
  if (await directoryExists(skillDirPath)) {
19361
20074
  await removeDirectory(skillDirPath);
19362
20075
  }
19363
20076
  return {
19364
- relativeDirPathFromCwd: (0, import_node_path125.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
20077
+ relativeDirPathFromCwd: (0, import_node_path129.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
19365
20078
  };
19366
20079
  } catch (error) {
19367
20080
  throw new Error(
@@ -19372,29 +20085,29 @@ async function deleteSkill({
19372
20085
  );
19373
20086
  }
19374
20087
  }
19375
- var McpSkillFileSchema = import_mini65.z.object({
19376
- name: import_mini65.z.string(),
19377
- body: import_mini65.z.string()
20088
+ var McpSkillFileSchema = import_mini67.z.object({
20089
+ name: import_mini67.z.string(),
20090
+ body: import_mini67.z.string()
19378
20091
  });
19379
20092
  var skillToolSchemas = {
19380
- listSkills: import_mini65.z.object({}),
19381
- getSkill: import_mini65.z.object({
19382
- relativeDirPathFromCwd: import_mini65.z.string()
20093
+ listSkills: import_mini67.z.object({}),
20094
+ getSkill: import_mini67.z.object({
20095
+ relativeDirPathFromCwd: import_mini67.z.string()
19383
20096
  }),
19384
- putSkill: import_mini65.z.object({
19385
- relativeDirPathFromCwd: import_mini65.z.string(),
20097
+ putSkill: import_mini67.z.object({
20098
+ relativeDirPathFromCwd: import_mini67.z.string(),
19386
20099
  frontmatter: RulesyncSkillFrontmatterSchema,
19387
- body: import_mini65.z.string(),
19388
- otherFiles: import_mini65.z.optional(import_mini65.z.array(McpSkillFileSchema))
20100
+ body: import_mini67.z.string(),
20101
+ otherFiles: import_mini67.z.optional(import_mini67.z.array(McpSkillFileSchema))
19389
20102
  }),
19390
- deleteSkill: import_mini65.z.object({
19391
- relativeDirPathFromCwd: import_mini65.z.string()
20103
+ deleteSkill: import_mini67.z.object({
20104
+ relativeDirPathFromCwd: import_mini67.z.string()
19392
20105
  })
19393
20106
  };
19394
20107
  var skillTools = {
19395
20108
  listSkills: {
19396
20109
  name: "listSkills",
19397
- description: `List all skills from ${(0, import_node_path125.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "*", SKILL_FILE_NAME)} with their frontmatter.`,
20110
+ description: `List all skills from ${(0, import_node_path129.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "*", SKILL_FILE_NAME)} with their frontmatter.`,
19398
20111
  parameters: skillToolSchemas.listSkills,
19399
20112
  execute: async () => {
19400
20113
  const skills = await listSkills();
@@ -19437,12 +20150,12 @@ var skillTools = {
19437
20150
  };
19438
20151
 
19439
20152
  // src/mcp/subagents.ts
19440
- var import_node_path126 = require("path");
19441
- var import_mini66 = require("zod/mini");
20153
+ var import_node_path130 = require("path");
20154
+ var import_mini68 = require("zod/mini");
19442
20155
  var maxSubagentSizeBytes = 1024 * 1024;
19443
20156
  var maxSubagentsCount = 1e3;
19444
20157
  async function listSubagents() {
19445
- const subagentsDir = (0, import_node_path126.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
20158
+ const subagentsDir = (0, import_node_path130.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
19446
20159
  try {
19447
20160
  const files = await listDirectoryFiles(subagentsDir);
19448
20161
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -19455,7 +20168,7 @@ async function listSubagents() {
19455
20168
  });
19456
20169
  const frontmatter = subagent.getFrontmatter();
19457
20170
  return {
19458
- relativePathFromCwd: (0, import_node_path126.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
20171
+ relativePathFromCwd: (0, import_node_path130.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
19459
20172
  frontmatter
19460
20173
  };
19461
20174
  } catch (error) {
@@ -19479,14 +20192,14 @@ async function getSubagent({ relativePathFromCwd }) {
19479
20192
  relativePath: relativePathFromCwd,
19480
20193
  intendedRootDir: process.cwd()
19481
20194
  });
19482
- const filename = (0, import_node_path126.basename)(relativePathFromCwd);
20195
+ const filename = (0, import_node_path130.basename)(relativePathFromCwd);
19483
20196
  try {
19484
20197
  const subagent = await RulesyncSubagent.fromFile({
19485
20198
  relativeFilePath: filename,
19486
20199
  validate: true
19487
20200
  });
19488
20201
  return {
19489
- relativePathFromCwd: (0, import_node_path126.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
20202
+ relativePathFromCwd: (0, import_node_path130.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
19490
20203
  frontmatter: subagent.getFrontmatter(),
19491
20204
  body: subagent.getBody()
19492
20205
  };
@@ -19505,7 +20218,7 @@ async function putSubagent({
19505
20218
  relativePath: relativePathFromCwd,
19506
20219
  intendedRootDir: process.cwd()
19507
20220
  });
19508
- const filename = (0, import_node_path126.basename)(relativePathFromCwd);
20221
+ const filename = (0, import_node_path130.basename)(relativePathFromCwd);
19509
20222
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
19510
20223
  if (estimatedSize > maxSubagentSizeBytes) {
19511
20224
  throw new Error(
@@ -19515,7 +20228,7 @@ async function putSubagent({
19515
20228
  try {
19516
20229
  const existingSubagents = await listSubagents();
19517
20230
  const isUpdate = existingSubagents.some(
19518
- (subagent2) => subagent2.relativePathFromCwd === (0, import_node_path126.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
20231
+ (subagent2) => subagent2.relativePathFromCwd === (0, import_node_path130.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
19519
20232
  );
19520
20233
  if (!isUpdate && existingSubagents.length >= maxSubagentsCount) {
19521
20234
  throw new Error(
@@ -19530,11 +20243,11 @@ async function putSubagent({
19530
20243
  body,
19531
20244
  validate: true
19532
20245
  });
19533
- const subagentsDir = (0, import_node_path126.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
20246
+ const subagentsDir = (0, import_node_path130.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
19534
20247
  await ensureDir(subagentsDir);
19535
20248
  await writeFileContent(subagent.getFilePath(), subagent.getFileContent());
19536
20249
  return {
19537
- relativePathFromCwd: (0, import_node_path126.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
20250
+ relativePathFromCwd: (0, import_node_path130.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
19538
20251
  frontmatter: subagent.getFrontmatter(),
19539
20252
  body: subagent.getBody()
19540
20253
  };
@@ -19549,12 +20262,12 @@ async function deleteSubagent({ relativePathFromCwd }) {
19549
20262
  relativePath: relativePathFromCwd,
19550
20263
  intendedRootDir: process.cwd()
19551
20264
  });
19552
- const filename = (0, import_node_path126.basename)(relativePathFromCwd);
19553
- const fullPath = (0, import_node_path126.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
20265
+ const filename = (0, import_node_path130.basename)(relativePathFromCwd);
20266
+ const fullPath = (0, import_node_path130.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
19554
20267
  try {
19555
20268
  await removeFile(fullPath);
19556
20269
  return {
19557
- relativePathFromCwd: (0, import_node_path126.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
20270
+ relativePathFromCwd: (0, import_node_path130.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
19558
20271
  };
19559
20272
  } catch (error) {
19560
20273
  throw new Error(
@@ -19566,23 +20279,23 @@ async function deleteSubagent({ relativePathFromCwd }) {
19566
20279
  }
19567
20280
  }
19568
20281
  var subagentToolSchemas = {
19569
- listSubagents: import_mini66.z.object({}),
19570
- getSubagent: import_mini66.z.object({
19571
- relativePathFromCwd: import_mini66.z.string()
20282
+ listSubagents: import_mini68.z.object({}),
20283
+ getSubagent: import_mini68.z.object({
20284
+ relativePathFromCwd: import_mini68.z.string()
19572
20285
  }),
19573
- putSubagent: import_mini66.z.object({
19574
- relativePathFromCwd: import_mini66.z.string(),
20286
+ putSubagent: import_mini68.z.object({
20287
+ relativePathFromCwd: import_mini68.z.string(),
19575
20288
  frontmatter: RulesyncSubagentFrontmatterSchema,
19576
- body: import_mini66.z.string()
20289
+ body: import_mini68.z.string()
19577
20290
  }),
19578
- deleteSubagent: import_mini66.z.object({
19579
- relativePathFromCwd: import_mini66.z.string()
20291
+ deleteSubagent: import_mini68.z.object({
20292
+ relativePathFromCwd: import_mini68.z.string()
19580
20293
  })
19581
20294
  };
19582
20295
  var subagentTools = {
19583
20296
  listSubagents: {
19584
20297
  name: "listSubagents",
19585
- description: `List all subagents from ${(0, import_node_path126.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
20298
+ description: `List all subagents from ${(0, import_node_path130.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
19586
20299
  parameters: subagentToolSchemas.listSubagents,
19587
20300
  execute: async () => {
19588
20301
  const subagents = await listSubagents();
@@ -19624,7 +20337,7 @@ var subagentTools = {
19624
20337
  };
19625
20338
 
19626
20339
  // src/mcp/tools.ts
19627
- var rulesyncFeatureSchema = import_mini67.z.enum([
20340
+ var rulesyncFeatureSchema = import_mini69.z.enum([
19628
20341
  "rule",
19629
20342
  "command",
19630
20343
  "subagent",
@@ -19634,21 +20347,21 @@ var rulesyncFeatureSchema = import_mini67.z.enum([
19634
20347
  "generate",
19635
20348
  "import"
19636
20349
  ]);
19637
- var rulesyncOperationSchema = import_mini67.z.enum(["list", "get", "put", "delete", "run"]);
19638
- var skillFileSchema = import_mini67.z.object({
19639
- name: import_mini67.z.string(),
19640
- body: import_mini67.z.string()
20350
+ var rulesyncOperationSchema = import_mini69.z.enum(["list", "get", "put", "delete", "run"]);
20351
+ var skillFileSchema = import_mini69.z.object({
20352
+ name: import_mini69.z.string(),
20353
+ body: import_mini69.z.string()
19641
20354
  });
19642
- var rulesyncToolSchema = import_mini67.z.object({
20355
+ var rulesyncToolSchema = import_mini69.z.object({
19643
20356
  feature: rulesyncFeatureSchema,
19644
20357
  operation: rulesyncOperationSchema,
19645
- targetPathFromCwd: import_mini67.z.optional(import_mini67.z.string()),
19646
- frontmatter: import_mini67.z.optional(import_mini67.z.unknown()),
19647
- body: import_mini67.z.optional(import_mini67.z.string()),
19648
- otherFiles: import_mini67.z.optional(import_mini67.z.array(skillFileSchema)),
19649
- content: import_mini67.z.optional(import_mini67.z.string()),
19650
- generateOptions: import_mini67.z.optional(generateOptionsSchema),
19651
- importOptions: import_mini67.z.optional(importOptionsSchema)
20358
+ targetPathFromCwd: import_mini69.z.optional(import_mini69.z.string()),
20359
+ frontmatter: import_mini69.z.optional(import_mini69.z.unknown()),
20360
+ body: import_mini69.z.optional(import_mini69.z.string()),
20361
+ otherFiles: import_mini69.z.optional(import_mini69.z.array(skillFileSchema)),
20362
+ content: import_mini69.z.optional(import_mini69.z.string()),
20363
+ generateOptions: import_mini69.z.optional(generateOptionsSchema),
20364
+ importOptions: import_mini69.z.optional(importOptionsSchema)
19652
20365
  });
19653
20366
  var supportedOperationsByFeature = {
19654
20367
  rule: ["list", "get", "put", "delete"],
@@ -20207,7 +20920,7 @@ async function updateCommand(currentVersion, options) {
20207
20920
  }
20208
20921
 
20209
20922
  // src/cli/index.ts
20210
- var getVersion = () => "7.13.0";
20923
+ var getVersion = () => "7.14.0";
20211
20924
  var main = async () => {
20212
20925
  const program = new import_commander.Command();
20213
20926
  const version = getVersion();