rulesync 3.31.0 → 3.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/dist/index.cjs +1292 -835
- package/dist/index.js +1283 -826
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -229,17 +229,18 @@ var ALL_TOOL_TARGETS = [
|
|
|
229
229
|
"antigravity",
|
|
230
230
|
"augmentcode",
|
|
231
231
|
"augmentcode-legacy",
|
|
232
|
-
"copilot",
|
|
233
|
-
"cursor",
|
|
234
|
-
"cline",
|
|
235
232
|
"claudecode",
|
|
233
|
+
"claudecode-legacy",
|
|
234
|
+
"cline",
|
|
236
235
|
"codexcli",
|
|
236
|
+
"copilot",
|
|
237
|
+
"cursor",
|
|
238
|
+
"geminicli",
|
|
239
|
+
"junie",
|
|
240
|
+
"kiro",
|
|
237
241
|
"opencode",
|
|
238
242
|
"qwencode",
|
|
239
243
|
"roo",
|
|
240
|
-
"geminicli",
|
|
241
|
-
"kiro",
|
|
242
|
-
"junie",
|
|
243
244
|
"warp",
|
|
244
245
|
"windsurf"
|
|
245
246
|
];
|
|
@@ -272,6 +273,11 @@ var ConfigFileSchema = z3.object({
|
|
|
272
273
|
...z3.partial(ConfigParamsSchema).shape
|
|
273
274
|
});
|
|
274
275
|
var RequiredConfigParamsSchema = z3.required(ConfigParamsSchema);
|
|
276
|
+
var CONFLICTING_TARGET_PAIRS = [
|
|
277
|
+
["augmentcode", "augmentcode-legacy"],
|
|
278
|
+
["claudecode", "claudecode-legacy"]
|
|
279
|
+
];
|
|
280
|
+
var LEGACY_TARGETS = ["augmentcode-legacy", "claudecode-legacy"];
|
|
275
281
|
var Config = class {
|
|
276
282
|
baseDirs;
|
|
277
283
|
targets;
|
|
@@ -298,6 +304,7 @@ var Config = class {
|
|
|
298
304
|
experimentalSimulateCommands,
|
|
299
305
|
experimentalSimulateSubagents
|
|
300
306
|
}) {
|
|
307
|
+
this.validateConflictingTargets(targets);
|
|
301
308
|
this.baseDirs = baseDirs;
|
|
302
309
|
this.targets = targets;
|
|
303
310
|
this.features = features;
|
|
@@ -309,12 +316,26 @@ var Config = class {
|
|
|
309
316
|
this.simulateSkills = simulateSkills ?? false;
|
|
310
317
|
this.modularMcp = modularMcp ?? false;
|
|
311
318
|
}
|
|
319
|
+
validateConflictingTargets(targets) {
|
|
320
|
+
for (const [target1, target2] of CONFLICTING_TARGET_PAIRS) {
|
|
321
|
+
const hasTarget1 = targets.includes(target1);
|
|
322
|
+
const hasTarget2 = targets.includes(target2);
|
|
323
|
+
if (hasTarget1 && hasTarget2) {
|
|
324
|
+
throw new Error(
|
|
325
|
+
`Conflicting targets: '${target1}' and '${target2}' cannot be used together. Please choose one.`
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
312
330
|
getBaseDirs() {
|
|
313
331
|
return this.baseDirs;
|
|
314
332
|
}
|
|
315
333
|
getTargets() {
|
|
316
334
|
if (this.targets.includes("*")) {
|
|
317
|
-
return
|
|
335
|
+
return ALL_TOOL_TARGETS.filter(
|
|
336
|
+
// eslint-disable-next-line no-type-assertion/no-type-assertion
|
|
337
|
+
(target) => !LEGACY_TARGETS.includes(target)
|
|
338
|
+
);
|
|
318
339
|
}
|
|
319
340
|
return this.targets.filter((target) => target !== "*");
|
|
320
341
|
}
|
|
@@ -3492,6 +3513,12 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
|
|
|
3492
3513
|
|
|
3493
3514
|
// src/features/mcp/copilot-mcp.ts
|
|
3494
3515
|
import { join as join33 } from "path";
|
|
3516
|
+
function convertToCopilotFormat(mcpServers) {
|
|
3517
|
+
return { servers: mcpServers };
|
|
3518
|
+
}
|
|
3519
|
+
function convertFromCopilotFormat(copilotConfig) {
|
|
3520
|
+
return copilotConfig.servers ?? {};
|
|
3521
|
+
}
|
|
3495
3522
|
var CopilotMcp = class _CopilotMcp extends ToolMcp {
|
|
3496
3523
|
json;
|
|
3497
3524
|
constructor(params) {
|
|
@@ -3531,16 +3558,20 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
|
|
|
3531
3558
|
rulesyncMcp,
|
|
3532
3559
|
validate = true
|
|
3533
3560
|
}) {
|
|
3561
|
+
const copilotConfig = convertToCopilotFormat(rulesyncMcp.getMcpServers());
|
|
3534
3562
|
return new _CopilotMcp({
|
|
3535
3563
|
baseDir,
|
|
3536
3564
|
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
3537
3565
|
relativeFilePath: this.getSettablePaths().relativeFilePath,
|
|
3538
|
-
fileContent:
|
|
3566
|
+
fileContent: JSON.stringify(copilotConfig, null, 2),
|
|
3539
3567
|
validate
|
|
3540
3568
|
});
|
|
3541
3569
|
}
|
|
3542
3570
|
toRulesyncMcp() {
|
|
3543
|
-
|
|
3571
|
+
const mcpServers = convertFromCopilotFormat(this.json);
|
|
3572
|
+
return this.toRulesyncMcpDefault({
|
|
3573
|
+
fileContent: JSON.stringify({ mcpServers }, null, 2)
|
|
3574
|
+
});
|
|
3544
3575
|
}
|
|
3545
3576
|
validate() {
|
|
3546
3577
|
return { success: true, error: null };
|
|
@@ -3924,6 +3955,37 @@ var OpencodeMcp = class _OpencodeMcp extends ToolMcp {
|
|
|
3924
3955
|
|
|
3925
3956
|
// src/features/mcp/roo-mcp.ts
|
|
3926
3957
|
import { join as join38 } from "path";
|
|
3958
|
+
function isRooMcpServers(value) {
|
|
3959
|
+
return value !== void 0 && value !== null && typeof value === "object";
|
|
3960
|
+
}
|
|
3961
|
+
function convertToRooFormat(mcpServers) {
|
|
3962
|
+
return Object.fromEntries(
|
|
3963
|
+
Object.entries(mcpServers).map(([serverName, serverConfig]) => {
|
|
3964
|
+
const converted = { ...serverConfig };
|
|
3965
|
+
if (serverConfig.type === "http") {
|
|
3966
|
+
converted.type = "streamable-http";
|
|
3967
|
+
}
|
|
3968
|
+
if (serverConfig.transport === "http") {
|
|
3969
|
+
converted.transport = "streamable-http";
|
|
3970
|
+
}
|
|
3971
|
+
return [serverName, converted];
|
|
3972
|
+
})
|
|
3973
|
+
);
|
|
3974
|
+
}
|
|
3975
|
+
function convertFromRooFormat(mcpServers) {
|
|
3976
|
+
return Object.fromEntries(
|
|
3977
|
+
Object.entries(mcpServers).map(([serverName, serverConfig]) => {
|
|
3978
|
+
const converted = { ...serverConfig };
|
|
3979
|
+
if (serverConfig.type === "streamable-http") {
|
|
3980
|
+
converted.type = "http";
|
|
3981
|
+
}
|
|
3982
|
+
if (serverConfig.transport === "streamable-http") {
|
|
3983
|
+
converted.transport = "http";
|
|
3984
|
+
}
|
|
3985
|
+
return [serverName, converted];
|
|
3986
|
+
})
|
|
3987
|
+
);
|
|
3988
|
+
}
|
|
3927
3989
|
var RooMcp = class _RooMcp extends ToolMcp {
|
|
3928
3990
|
json;
|
|
3929
3991
|
constructor(params) {
|
|
@@ -3963,7 +4025,9 @@ var RooMcp = class _RooMcp extends ToolMcp {
|
|
|
3963
4025
|
rulesyncMcp,
|
|
3964
4026
|
validate = true
|
|
3965
4027
|
}) {
|
|
3966
|
-
const
|
|
4028
|
+
const mcpServers = rulesyncMcp.getMcpServers();
|
|
4029
|
+
const convertedMcpServers = convertToRooFormat(mcpServers);
|
|
4030
|
+
const fileContent = JSON.stringify({ mcpServers: convertedMcpServers }, null, 2);
|
|
3967
4031
|
return new _RooMcp({
|
|
3968
4032
|
baseDir,
|
|
3969
4033
|
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
@@ -3973,7 +4037,11 @@ var RooMcp = class _RooMcp extends ToolMcp {
|
|
|
3973
4037
|
});
|
|
3974
4038
|
}
|
|
3975
4039
|
toRulesyncMcp() {
|
|
3976
|
-
|
|
4040
|
+
const rawMcpServers = isRooMcpServers(this.json.mcpServers) ? this.json.mcpServers : {};
|
|
4041
|
+
const convertedMcpServers = convertFromRooFormat(rawMcpServers);
|
|
4042
|
+
return this.toRulesyncMcpDefault({
|
|
4043
|
+
fileContent: JSON.stringify({ mcpServers: convertedMcpServers }, null, 2)
|
|
4044
|
+
});
|
|
3977
4045
|
}
|
|
3978
4046
|
validate() {
|
|
3979
4047
|
return { success: true, error: null };
|
|
@@ -4214,21 +4282,23 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
4214
4282
|
};
|
|
4215
4283
|
|
|
4216
4284
|
// src/features/rules/rules-processor.ts
|
|
4217
|
-
import { basename as basename21, join as
|
|
4285
|
+
import { basename as basename21, join as join82 } from "path";
|
|
4218
4286
|
import { encode } from "@toon-format/toon";
|
|
4219
|
-
import { z as
|
|
4220
|
-
|
|
4221
|
-
// src/features/skills/codexcli-skill.ts
|
|
4222
|
-
import { join as join42 } from "path";
|
|
4223
|
-
import { z as z20 } from "zod/mini";
|
|
4287
|
+
import { z as z33 } from "zod/mini";
|
|
4224
4288
|
|
|
4225
4289
|
// src/constants/general.ts
|
|
4226
4290
|
var SKILL_FILE_NAME = "SKILL.md";
|
|
4227
4291
|
|
|
4228
|
-
// src/features/skills/
|
|
4229
|
-
import { join as
|
|
4292
|
+
// src/features/skills/agentsmd-skill.ts
|
|
4293
|
+
import { join as join42 } from "path";
|
|
4294
|
+
|
|
4295
|
+
// src/features/skills/simulated-skill.ts
|
|
4296
|
+
import { join as join41 } from "path";
|
|
4230
4297
|
import { z as z19 } from "zod/mini";
|
|
4231
4298
|
|
|
4299
|
+
// src/features/skills/tool-skill.ts
|
|
4300
|
+
import { join as join40 } from "path";
|
|
4301
|
+
|
|
4232
4302
|
// src/types/ai-dir.ts
|
|
4233
4303
|
import path2, { basename as basename14, join as join39, relative as relative3, resolve as resolve4 } from "path";
|
|
4234
4304
|
var AiDir = class {
|
|
@@ -4341,113 +4411,7 @@ var AiDir = class {
|
|
|
4341
4411
|
}
|
|
4342
4412
|
};
|
|
4343
4413
|
|
|
4344
|
-
// src/features/skills/rulesync-skill.ts
|
|
4345
|
-
var RulesyncSkillFrontmatterSchemaInternal = z19.object({
|
|
4346
|
-
name: z19.string(),
|
|
4347
|
-
description: z19.string(),
|
|
4348
|
-
targets: z19._default(RulesyncTargetsSchema, ["*"]),
|
|
4349
|
-
claudecode: z19.optional(
|
|
4350
|
-
z19.object({
|
|
4351
|
-
"allowed-tools": z19.optional(z19.array(z19.string()))
|
|
4352
|
-
})
|
|
4353
|
-
)
|
|
4354
|
-
});
|
|
4355
|
-
var RulesyncSkillFrontmatterSchema = RulesyncSkillFrontmatterSchemaInternal;
|
|
4356
|
-
var RulesyncSkill = class _RulesyncSkill extends AiDir {
|
|
4357
|
-
constructor({
|
|
4358
|
-
baseDir = process.cwd(),
|
|
4359
|
-
relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
|
|
4360
|
-
dirName,
|
|
4361
|
-
frontmatter,
|
|
4362
|
-
body,
|
|
4363
|
-
otherFiles = [],
|
|
4364
|
-
validate = true,
|
|
4365
|
-
global = false
|
|
4366
|
-
}) {
|
|
4367
|
-
super({
|
|
4368
|
-
baseDir,
|
|
4369
|
-
relativeDirPath,
|
|
4370
|
-
dirName,
|
|
4371
|
-
mainFile: {
|
|
4372
|
-
name: SKILL_FILE_NAME,
|
|
4373
|
-
body,
|
|
4374
|
-
frontmatter: { ...frontmatter }
|
|
4375
|
-
},
|
|
4376
|
-
otherFiles,
|
|
4377
|
-
global
|
|
4378
|
-
});
|
|
4379
|
-
if (validate) {
|
|
4380
|
-
const result = this.validate();
|
|
4381
|
-
if (!result.success) {
|
|
4382
|
-
throw result.error;
|
|
4383
|
-
}
|
|
4384
|
-
}
|
|
4385
|
-
}
|
|
4386
|
-
static getSettablePaths() {
|
|
4387
|
-
return {
|
|
4388
|
-
relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH
|
|
4389
|
-
};
|
|
4390
|
-
}
|
|
4391
|
-
getFrontmatter() {
|
|
4392
|
-
if (!this.mainFile?.frontmatter) {
|
|
4393
|
-
throw new Error("Frontmatter is not defined");
|
|
4394
|
-
}
|
|
4395
|
-
const result = RulesyncSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
|
|
4396
|
-
return result;
|
|
4397
|
-
}
|
|
4398
|
-
getBody() {
|
|
4399
|
-
return this.mainFile?.body ?? "";
|
|
4400
|
-
}
|
|
4401
|
-
validate() {
|
|
4402
|
-
const result = RulesyncSkillFrontmatterSchema.safeParse(this.mainFile?.frontmatter);
|
|
4403
|
-
if (!result.success) {
|
|
4404
|
-
return {
|
|
4405
|
-
success: false,
|
|
4406
|
-
error: new Error(
|
|
4407
|
-
`Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
|
|
4408
|
-
)
|
|
4409
|
-
};
|
|
4410
|
-
}
|
|
4411
|
-
return { success: true, error: null };
|
|
4412
|
-
}
|
|
4413
|
-
static async fromDir({
|
|
4414
|
-
baseDir = process.cwd(),
|
|
4415
|
-
relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
|
|
4416
|
-
dirName,
|
|
4417
|
-
global = false
|
|
4418
|
-
}) {
|
|
4419
|
-
const skillDirPath = join40(baseDir, relativeDirPath, dirName);
|
|
4420
|
-
const skillFilePath = join40(skillDirPath, SKILL_FILE_NAME);
|
|
4421
|
-
if (!await fileExists(skillFilePath)) {
|
|
4422
|
-
throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
|
|
4423
|
-
}
|
|
4424
|
-
const fileContent = await readFileContent(skillFilePath);
|
|
4425
|
-
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4426
|
-
const result = RulesyncSkillFrontmatterSchema.safeParse(frontmatter);
|
|
4427
|
-
if (!result.success) {
|
|
4428
|
-
throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
|
|
4429
|
-
}
|
|
4430
|
-
const otherFiles = await this.collectOtherFiles(
|
|
4431
|
-
baseDir,
|
|
4432
|
-
relativeDirPath,
|
|
4433
|
-
dirName,
|
|
4434
|
-
SKILL_FILE_NAME
|
|
4435
|
-
);
|
|
4436
|
-
return new _RulesyncSkill({
|
|
4437
|
-
baseDir,
|
|
4438
|
-
relativeDirPath,
|
|
4439
|
-
dirName,
|
|
4440
|
-
frontmatter: result.data,
|
|
4441
|
-
body: content.trim(),
|
|
4442
|
-
otherFiles,
|
|
4443
|
-
validate: true,
|
|
4444
|
-
global
|
|
4445
|
-
});
|
|
4446
|
-
}
|
|
4447
|
-
};
|
|
4448
|
-
|
|
4449
4414
|
// src/features/skills/tool-skill.ts
|
|
4450
|
-
import { join as join41 } from "path";
|
|
4451
4415
|
var ToolSkill = class extends AiDir {
|
|
4452
4416
|
/**
|
|
4453
4417
|
* Get the settable paths for this tool's skill directories.
|
|
@@ -4521,8 +4485,8 @@ var ToolSkill = class extends AiDir {
|
|
|
4521
4485
|
}) {
|
|
4522
4486
|
const settablePaths = getSettablePaths({ global });
|
|
4523
4487
|
const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
|
|
4524
|
-
const skillDirPath =
|
|
4525
|
-
const skillFilePath =
|
|
4488
|
+
const skillDirPath = join40(baseDir, actualRelativeDirPath, dirName);
|
|
4489
|
+
const skillFilePath = join40(skillDirPath, SKILL_FILE_NAME);
|
|
4526
4490
|
if (!await fileExists(skillFilePath)) {
|
|
4527
4491
|
throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
|
|
4528
4492
|
}
|
|
@@ -4546,21 +4510,22 @@ var ToolSkill = class extends AiDir {
|
|
|
4546
4510
|
}
|
|
4547
4511
|
};
|
|
4548
4512
|
|
|
4549
|
-
// src/features/skills/
|
|
4550
|
-
var
|
|
4551
|
-
name:
|
|
4552
|
-
description:
|
|
4513
|
+
// src/features/skills/simulated-skill.ts
|
|
4514
|
+
var SimulatedSkillFrontmatterSchema = z19.object({
|
|
4515
|
+
name: z19.string(),
|
|
4516
|
+
description: z19.string()
|
|
4553
4517
|
});
|
|
4554
|
-
var
|
|
4518
|
+
var SimulatedSkill = class extends ToolSkill {
|
|
4519
|
+
frontmatter;
|
|
4520
|
+
body;
|
|
4555
4521
|
constructor({
|
|
4556
4522
|
baseDir = process.cwd(),
|
|
4557
|
-
relativeDirPath
|
|
4523
|
+
relativeDirPath,
|
|
4558
4524
|
dirName,
|
|
4559
4525
|
frontmatter,
|
|
4560
4526
|
body,
|
|
4561
4527
|
otherFiles = [],
|
|
4562
|
-
validate = true
|
|
4563
|
-
global = false
|
|
4528
|
+
validate = true
|
|
4564
4529
|
}) {
|
|
4565
4530
|
super({
|
|
4566
4531
|
baseDir,
|
|
@@ -4572,42 +4537,37 @@ var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
|
|
|
4572
4537
|
frontmatter: { ...frontmatter }
|
|
4573
4538
|
},
|
|
4574
4539
|
otherFiles,
|
|
4575
|
-
global
|
|
4540
|
+
global: false
|
|
4541
|
+
// Simulated skills are project mode only
|
|
4576
4542
|
});
|
|
4577
4543
|
if (validate) {
|
|
4578
|
-
const result =
|
|
4544
|
+
const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
|
|
4579
4545
|
if (!result.success) {
|
|
4580
|
-
throw
|
|
4546
|
+
throw new Error(
|
|
4547
|
+
`Invalid frontmatter in ${join41(relativeDirPath, dirName)}: ${formatError(result.error)}`
|
|
4548
|
+
);
|
|
4581
4549
|
}
|
|
4582
4550
|
}
|
|
4551
|
+
this.frontmatter = frontmatter;
|
|
4552
|
+
this.body = body;
|
|
4583
4553
|
}
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
throw new Error("CodexCliSkill only supports global mode. Please pass { global: true }.");
|
|
4587
|
-
}
|
|
4588
|
-
return {
|
|
4589
|
-
relativeDirPath: join42(".codex", "skills")
|
|
4590
|
-
};
|
|
4554
|
+
getBody() {
|
|
4555
|
+
return this.body;
|
|
4591
4556
|
}
|
|
4592
4557
|
getFrontmatter() {
|
|
4593
|
-
|
|
4594
|
-
throw new Error("Frontmatter is not defined");
|
|
4595
|
-
}
|
|
4596
|
-
const result = CodexCliSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
|
|
4597
|
-
return result;
|
|
4558
|
+
return this.frontmatter;
|
|
4598
4559
|
}
|
|
4599
|
-
|
|
4600
|
-
|
|
4560
|
+
toRulesyncSkill() {
|
|
4561
|
+
throw new Error("Not implemented because it is a SIMULATED skill.");
|
|
4601
4562
|
}
|
|
4602
4563
|
validate() {
|
|
4603
|
-
if (!this.
|
|
4604
|
-
return {
|
|
4605
|
-
success: false,
|
|
4606
|
-
error: new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
4607
|
-
};
|
|
4564
|
+
if (!this.frontmatter) {
|
|
4565
|
+
return { success: true, error: null };
|
|
4608
4566
|
}
|
|
4609
|
-
const result =
|
|
4610
|
-
if (
|
|
4567
|
+
const result = SimulatedSkillFrontmatterSchema.safeParse(this.frontmatter);
|
|
4568
|
+
if (result.success) {
|
|
4569
|
+
return { success: true, error: null };
|
|
4570
|
+
} else {
|
|
4611
4571
|
return {
|
|
4612
4572
|
success: false,
|
|
4613
4573
|
error: new Error(
|
|
@@ -4615,98 +4575,141 @@ var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
|
|
|
4615
4575
|
)
|
|
4616
4576
|
};
|
|
4617
4577
|
}
|
|
4618
|
-
return { success: true, error: null };
|
|
4619
|
-
}
|
|
4620
|
-
toRulesyncSkill() {
|
|
4621
|
-
const frontmatter = this.getFrontmatter();
|
|
4622
|
-
const rulesyncFrontmatter = {
|
|
4623
|
-
name: frontmatter.name,
|
|
4624
|
-
description: frontmatter.description,
|
|
4625
|
-
targets: ["*"]
|
|
4626
|
-
};
|
|
4627
|
-
return new RulesyncSkill({
|
|
4628
|
-
baseDir: this.baseDir,
|
|
4629
|
-
relativeDirPath: this.relativeDirPath,
|
|
4630
|
-
dirName: this.getDirName(),
|
|
4631
|
-
frontmatter: rulesyncFrontmatter,
|
|
4632
|
-
body: this.getBody(),
|
|
4633
|
-
otherFiles: this.getOtherFiles(),
|
|
4634
|
-
validate: true,
|
|
4635
|
-
global: this.global
|
|
4636
|
-
});
|
|
4637
4578
|
}
|
|
4638
|
-
static
|
|
4579
|
+
static fromRulesyncSkillDefault({
|
|
4639
4580
|
rulesyncSkill,
|
|
4640
|
-
validate = true
|
|
4641
|
-
global = false
|
|
4581
|
+
validate = true
|
|
4642
4582
|
}) {
|
|
4643
|
-
const settablePaths = _CodexCliSkill.getSettablePaths({ global });
|
|
4644
4583
|
const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
|
|
4645
|
-
const
|
|
4584
|
+
const simulatedFrontmatter = {
|
|
4646
4585
|
name: rulesyncFrontmatter.name,
|
|
4647
4586
|
description: rulesyncFrontmatter.description
|
|
4648
4587
|
};
|
|
4649
|
-
return
|
|
4588
|
+
return {
|
|
4650
4589
|
baseDir: rulesyncSkill.getBaseDir(),
|
|
4651
|
-
relativeDirPath:
|
|
4590
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
4652
4591
|
dirName: rulesyncSkill.getDirName(),
|
|
4653
|
-
frontmatter:
|
|
4592
|
+
frontmatter: simulatedFrontmatter,
|
|
4654
4593
|
body: rulesyncSkill.getBody(),
|
|
4655
4594
|
otherFiles: rulesyncSkill.getOtherFiles(),
|
|
4656
|
-
validate
|
|
4657
|
-
|
|
4658
|
-
});
|
|
4595
|
+
validate
|
|
4596
|
+
};
|
|
4659
4597
|
}
|
|
4660
|
-
static
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
const
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4598
|
+
static async fromDirDefault({
|
|
4599
|
+
baseDir = process.cwd(),
|
|
4600
|
+
relativeDirPath,
|
|
4601
|
+
dirName
|
|
4602
|
+
}) {
|
|
4603
|
+
const settablePaths = this.getSettablePaths();
|
|
4604
|
+
const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
|
|
4605
|
+
const skillDirPath = join41(baseDir, actualRelativeDirPath, dirName);
|
|
4606
|
+
const skillFilePath = join41(skillDirPath, SKILL_FILE_NAME);
|
|
4607
|
+
if (!await fileExists(skillFilePath)) {
|
|
4608
|
+
throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
|
|
4609
|
+
}
|
|
4610
|
+
const fileContent = await readFileContent(skillFilePath);
|
|
4611
|
+
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4612
|
+
const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
|
|
4670
4613
|
if (!result.success) {
|
|
4671
|
-
|
|
4672
|
-
throw new Error(
|
|
4673
|
-
`Invalid frontmatter in ${join42(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
|
|
4674
|
-
);
|
|
4614
|
+
throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
|
|
4675
4615
|
}
|
|
4676
|
-
|
|
4677
|
-
baseDir
|
|
4678
|
-
|
|
4679
|
-
dirName
|
|
4616
|
+
const otherFiles = await this.collectOtherFiles(
|
|
4617
|
+
baseDir,
|
|
4618
|
+
actualRelativeDirPath,
|
|
4619
|
+
dirName,
|
|
4620
|
+
SKILL_FILE_NAME
|
|
4621
|
+
);
|
|
4622
|
+
return {
|
|
4623
|
+
baseDir,
|
|
4624
|
+
relativeDirPath: actualRelativeDirPath,
|
|
4625
|
+
dirName,
|
|
4680
4626
|
frontmatter: result.data,
|
|
4681
|
-
body:
|
|
4682
|
-
otherFiles
|
|
4683
|
-
validate: true
|
|
4684
|
-
|
|
4627
|
+
body: content.trim(),
|
|
4628
|
+
otherFiles,
|
|
4629
|
+
validate: true
|
|
4630
|
+
};
|
|
4631
|
+
}
|
|
4632
|
+
/**
|
|
4633
|
+
* Check if a RulesyncSkill should be converted to this simulated skill type.
|
|
4634
|
+
* Uses the targets field in the RulesyncSkill frontmatter to determine targeting.
|
|
4635
|
+
*/
|
|
4636
|
+
static isTargetedByRulesyncSkillDefault({
|
|
4637
|
+
rulesyncSkill,
|
|
4638
|
+
toolTarget
|
|
4639
|
+
}) {
|
|
4640
|
+
const frontmatter = rulesyncSkill.getFrontmatter();
|
|
4641
|
+
const targets = frontmatter.targets;
|
|
4642
|
+
if (targets.includes("*")) {
|
|
4643
|
+
return true;
|
|
4644
|
+
}
|
|
4645
|
+
return targets.includes(toolTarget);
|
|
4646
|
+
}
|
|
4647
|
+
/**
|
|
4648
|
+
* Get the settable paths for this tool's skill directories.
|
|
4649
|
+
* Must be implemented by concrete subclasses.
|
|
4650
|
+
*/
|
|
4651
|
+
static getSettablePaths(_options) {
|
|
4652
|
+
throw new Error("Please implement this method in the subclass.");
|
|
4653
|
+
}
|
|
4654
|
+
};
|
|
4655
|
+
|
|
4656
|
+
// src/features/skills/agentsmd-skill.ts
|
|
4657
|
+
var AgentsmdSkill = class _AgentsmdSkill extends SimulatedSkill {
|
|
4658
|
+
static getSettablePaths(options) {
|
|
4659
|
+
if (options?.global) {
|
|
4660
|
+
throw new Error("AgentsmdSkill does not support global mode.");
|
|
4661
|
+
}
|
|
4662
|
+
return {
|
|
4663
|
+
relativeDirPath: join42(".agents", "skills")
|
|
4664
|
+
};
|
|
4665
|
+
}
|
|
4666
|
+
static async fromDir(params) {
|
|
4667
|
+
const baseParams = await this.fromDirDefault(params);
|
|
4668
|
+
return new _AgentsmdSkill(baseParams);
|
|
4669
|
+
}
|
|
4670
|
+
static fromRulesyncSkill(params) {
|
|
4671
|
+
const baseParams = {
|
|
4672
|
+
...this.fromRulesyncSkillDefault(params),
|
|
4673
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath
|
|
4674
|
+
};
|
|
4675
|
+
return new _AgentsmdSkill(baseParams);
|
|
4676
|
+
}
|
|
4677
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
4678
|
+
return this.isTargetedByRulesyncSkillDefault({
|
|
4679
|
+
rulesyncSkill,
|
|
4680
|
+
toolTarget: "agentsmd"
|
|
4685
4681
|
});
|
|
4686
4682
|
}
|
|
4687
4683
|
};
|
|
4688
4684
|
|
|
4689
|
-
// src/features/skills/
|
|
4685
|
+
// src/features/skills/codexcli-skill.ts
|
|
4690
4686
|
import { join as join44 } from "path";
|
|
4687
|
+
import { z as z21 } from "zod/mini";
|
|
4691
4688
|
|
|
4692
|
-
// src/features/skills/
|
|
4689
|
+
// src/features/skills/rulesync-skill.ts
|
|
4693
4690
|
import { join as join43 } from "path";
|
|
4694
|
-
import { z as
|
|
4695
|
-
var
|
|
4696
|
-
name:
|
|
4697
|
-
description:
|
|
4691
|
+
import { z as z20 } from "zod/mini";
|
|
4692
|
+
var RulesyncSkillFrontmatterSchemaInternal = z20.object({
|
|
4693
|
+
name: z20.string(),
|
|
4694
|
+
description: z20.string(),
|
|
4695
|
+
targets: z20._default(RulesyncTargetsSchema, ["*"]),
|
|
4696
|
+
claudecode: z20.optional(
|
|
4697
|
+
z20.object({
|
|
4698
|
+
"allowed-tools": z20.optional(z20.array(z20.string()))
|
|
4699
|
+
})
|
|
4700
|
+
)
|
|
4698
4701
|
});
|
|
4699
|
-
var
|
|
4700
|
-
|
|
4701
|
-
body;
|
|
4702
|
+
var RulesyncSkillFrontmatterSchema = RulesyncSkillFrontmatterSchemaInternal;
|
|
4703
|
+
var RulesyncSkill = class _RulesyncSkill extends AiDir {
|
|
4702
4704
|
constructor({
|
|
4703
4705
|
baseDir = process.cwd(),
|
|
4704
|
-
relativeDirPath,
|
|
4706
|
+
relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
|
|
4705
4707
|
dirName,
|
|
4706
4708
|
frontmatter,
|
|
4707
4709
|
body,
|
|
4708
4710
|
otherFiles = [],
|
|
4709
|
-
validate = true
|
|
4711
|
+
validate = true,
|
|
4712
|
+
global = false
|
|
4710
4713
|
}) {
|
|
4711
4714
|
super({
|
|
4712
4715
|
baseDir,
|
|
@@ -4718,37 +4721,33 @@ var SimulatedSkill = class extends ToolSkill {
|
|
|
4718
4721
|
frontmatter: { ...frontmatter }
|
|
4719
4722
|
},
|
|
4720
4723
|
otherFiles,
|
|
4721
|
-
global
|
|
4722
|
-
// Simulated skills are project mode only
|
|
4724
|
+
global
|
|
4723
4725
|
});
|
|
4724
4726
|
if (validate) {
|
|
4725
|
-
const result =
|
|
4727
|
+
const result = this.validate();
|
|
4726
4728
|
if (!result.success) {
|
|
4727
|
-
throw
|
|
4728
|
-
`Invalid frontmatter in ${join43(relativeDirPath, dirName)}: ${formatError(result.error)}`
|
|
4729
|
-
);
|
|
4729
|
+
throw result.error;
|
|
4730
4730
|
}
|
|
4731
4731
|
}
|
|
4732
|
-
this.frontmatter = frontmatter;
|
|
4733
|
-
this.body = body;
|
|
4734
4732
|
}
|
|
4735
|
-
|
|
4736
|
-
return
|
|
4733
|
+
static getSettablePaths() {
|
|
4734
|
+
return {
|
|
4735
|
+
relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH
|
|
4736
|
+
};
|
|
4737
4737
|
}
|
|
4738
4738
|
getFrontmatter() {
|
|
4739
|
-
|
|
4739
|
+
if (!this.mainFile?.frontmatter) {
|
|
4740
|
+
throw new Error("Frontmatter is not defined");
|
|
4741
|
+
}
|
|
4742
|
+
const result = RulesyncSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
|
|
4743
|
+
return result;
|
|
4740
4744
|
}
|
|
4741
|
-
|
|
4742
|
-
|
|
4745
|
+
getBody() {
|
|
4746
|
+
return this.mainFile?.body ?? "";
|
|
4743
4747
|
}
|
|
4744
4748
|
validate() {
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
}
|
|
4748
|
-
const result = SimulatedSkillFrontmatterSchema.safeParse(this.frontmatter);
|
|
4749
|
-
if (result.success) {
|
|
4750
|
-
return { success: true, error: null };
|
|
4751
|
-
} else {
|
|
4749
|
+
const result = RulesyncSkillFrontmatterSchema.safeParse(this.mainFile?.frontmatter);
|
|
4750
|
+
if (!result.success) {
|
|
4752
4751
|
return {
|
|
4753
4752
|
success: false,
|
|
4754
4753
|
error: new Error(
|
|
@@ -4756,139 +4755,270 @@ var SimulatedSkill = class extends ToolSkill {
|
|
|
4756
4755
|
)
|
|
4757
4756
|
};
|
|
4758
4757
|
}
|
|
4758
|
+
return { success: true, error: null };
|
|
4759
4759
|
}
|
|
4760
|
-
static
|
|
4761
|
-
rulesyncSkill,
|
|
4762
|
-
validate = true
|
|
4763
|
-
}) {
|
|
4764
|
-
const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
|
|
4765
|
-
const simulatedFrontmatter = {
|
|
4766
|
-
name: rulesyncFrontmatter.name,
|
|
4767
|
-
description: rulesyncFrontmatter.description
|
|
4768
|
-
};
|
|
4769
|
-
return {
|
|
4770
|
-
baseDir: rulesyncSkill.getBaseDir(),
|
|
4771
|
-
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
4772
|
-
dirName: rulesyncSkill.getDirName(),
|
|
4773
|
-
frontmatter: simulatedFrontmatter,
|
|
4774
|
-
body: rulesyncSkill.getBody(),
|
|
4775
|
-
otherFiles: rulesyncSkill.getOtherFiles(),
|
|
4776
|
-
validate
|
|
4777
|
-
};
|
|
4778
|
-
}
|
|
4779
|
-
static async fromDirDefault({
|
|
4760
|
+
static async fromDir({
|
|
4780
4761
|
baseDir = process.cwd(),
|
|
4781
|
-
relativeDirPath,
|
|
4782
|
-
dirName
|
|
4762
|
+
relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
|
|
4763
|
+
dirName,
|
|
4764
|
+
global = false
|
|
4783
4765
|
}) {
|
|
4784
|
-
const
|
|
4785
|
-
const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
|
|
4786
|
-
const skillDirPath = join43(baseDir, actualRelativeDirPath, dirName);
|
|
4766
|
+
const skillDirPath = join43(baseDir, relativeDirPath, dirName);
|
|
4787
4767
|
const skillFilePath = join43(skillDirPath, SKILL_FILE_NAME);
|
|
4788
4768
|
if (!await fileExists(skillFilePath)) {
|
|
4789
4769
|
throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
|
|
4790
4770
|
}
|
|
4791
4771
|
const fileContent = await readFileContent(skillFilePath);
|
|
4792
4772
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4793
|
-
const result =
|
|
4773
|
+
const result = RulesyncSkillFrontmatterSchema.safeParse(frontmatter);
|
|
4794
4774
|
if (!result.success) {
|
|
4795
4775
|
throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
|
|
4796
4776
|
}
|
|
4797
4777
|
const otherFiles = await this.collectOtherFiles(
|
|
4798
4778
|
baseDir,
|
|
4799
|
-
|
|
4779
|
+
relativeDirPath,
|
|
4800
4780
|
dirName,
|
|
4801
4781
|
SKILL_FILE_NAME
|
|
4802
4782
|
);
|
|
4803
|
-
return {
|
|
4783
|
+
return new _RulesyncSkill({
|
|
4804
4784
|
baseDir,
|
|
4805
|
-
relativeDirPath
|
|
4785
|
+
relativeDirPath,
|
|
4806
4786
|
dirName,
|
|
4807
4787
|
frontmatter: result.data,
|
|
4808
4788
|
body: content.trim(),
|
|
4809
4789
|
otherFiles,
|
|
4810
|
-
validate: true
|
|
4790
|
+
validate: true,
|
|
4791
|
+
global
|
|
4792
|
+
});
|
|
4793
|
+
}
|
|
4794
|
+
};
|
|
4795
|
+
|
|
4796
|
+
// src/features/skills/codexcli-skill.ts
|
|
4797
|
+
var CodexCliSkillFrontmatterSchema = z21.object({
|
|
4798
|
+
name: z21.string(),
|
|
4799
|
+
description: z21.string()
|
|
4800
|
+
});
|
|
4801
|
+
var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
|
|
4802
|
+
constructor({
|
|
4803
|
+
baseDir = process.cwd(),
|
|
4804
|
+
relativeDirPath = join44(".codex", "skills"),
|
|
4805
|
+
dirName,
|
|
4806
|
+
frontmatter,
|
|
4807
|
+
body,
|
|
4808
|
+
otherFiles = [],
|
|
4809
|
+
validate = true,
|
|
4810
|
+
global = false
|
|
4811
|
+
}) {
|
|
4812
|
+
super({
|
|
4813
|
+
baseDir,
|
|
4814
|
+
relativeDirPath,
|
|
4815
|
+
dirName,
|
|
4816
|
+
mainFile: {
|
|
4817
|
+
name: SKILL_FILE_NAME,
|
|
4818
|
+
body,
|
|
4819
|
+
frontmatter: { ...frontmatter }
|
|
4820
|
+
},
|
|
4821
|
+
otherFiles,
|
|
4822
|
+
global
|
|
4823
|
+
});
|
|
4824
|
+
if (validate) {
|
|
4825
|
+
const result = this.validate();
|
|
4826
|
+
if (!result.success) {
|
|
4827
|
+
throw result.error;
|
|
4828
|
+
}
|
|
4829
|
+
}
|
|
4830
|
+
}
|
|
4831
|
+
static getSettablePaths({ global = false } = {}) {
|
|
4832
|
+
if (!global) {
|
|
4833
|
+
throw new Error("CodexCliSkill only supports global mode. Please pass { global: true }.");
|
|
4834
|
+
}
|
|
4835
|
+
return {
|
|
4836
|
+
relativeDirPath: join44(".codex", "skills")
|
|
4811
4837
|
};
|
|
4812
4838
|
}
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4839
|
+
getFrontmatter() {
|
|
4840
|
+
if (!this.mainFile?.frontmatter) {
|
|
4841
|
+
throw new Error("Frontmatter is not defined");
|
|
4842
|
+
}
|
|
4843
|
+
const result = CodexCliSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
|
|
4844
|
+
return result;
|
|
4845
|
+
}
|
|
4846
|
+
getBody() {
|
|
4847
|
+
return this.mainFile?.body ?? "";
|
|
4848
|
+
}
|
|
4849
|
+
validate() {
|
|
4850
|
+
if (!this.mainFile) {
|
|
4851
|
+
return {
|
|
4852
|
+
success: false,
|
|
4853
|
+
error: new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
4854
|
+
};
|
|
4855
|
+
}
|
|
4856
|
+
const result = CodexCliSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
4857
|
+
if (!result.success) {
|
|
4858
|
+
return {
|
|
4859
|
+
success: false,
|
|
4860
|
+
error: new Error(
|
|
4861
|
+
`Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
|
|
4862
|
+
)
|
|
4863
|
+
};
|
|
4864
|
+
}
|
|
4865
|
+
return { success: true, error: null };
|
|
4866
|
+
}
|
|
4867
|
+
toRulesyncSkill() {
|
|
4868
|
+
const frontmatter = this.getFrontmatter();
|
|
4869
|
+
const rulesyncFrontmatter = {
|
|
4870
|
+
name: frontmatter.name,
|
|
4871
|
+
description: frontmatter.description,
|
|
4872
|
+
targets: ["*"]
|
|
4873
|
+
};
|
|
4874
|
+
return new RulesyncSkill({
|
|
4875
|
+
baseDir: this.baseDir,
|
|
4876
|
+
relativeDirPath: this.relativeDirPath,
|
|
4877
|
+
dirName: this.getDirName(),
|
|
4878
|
+
frontmatter: rulesyncFrontmatter,
|
|
4879
|
+
body: this.getBody(),
|
|
4880
|
+
otherFiles: this.getOtherFiles(),
|
|
4881
|
+
validate: true,
|
|
4882
|
+
global: this.global
|
|
4883
|
+
});
|
|
4884
|
+
}
|
|
4885
|
+
static fromRulesyncSkill({
|
|
4818
4886
|
rulesyncSkill,
|
|
4819
|
-
|
|
4887
|
+
validate = true,
|
|
4888
|
+
global = false
|
|
4820
4889
|
}) {
|
|
4821
|
-
const
|
|
4822
|
-
const
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4890
|
+
const settablePaths = _CodexCliSkill.getSettablePaths({ global });
|
|
4891
|
+
const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
|
|
4892
|
+
const codexFrontmatter = {
|
|
4893
|
+
name: rulesyncFrontmatter.name,
|
|
4894
|
+
description: rulesyncFrontmatter.description
|
|
4895
|
+
};
|
|
4896
|
+
return new _CodexCliSkill({
|
|
4897
|
+
baseDir: rulesyncSkill.getBaseDir(),
|
|
4898
|
+
relativeDirPath: settablePaths.relativeDirPath,
|
|
4899
|
+
dirName: rulesyncSkill.getDirName(),
|
|
4900
|
+
frontmatter: codexFrontmatter,
|
|
4901
|
+
body: rulesyncSkill.getBody(),
|
|
4902
|
+
otherFiles: rulesyncSkill.getOtherFiles(),
|
|
4903
|
+
validate,
|
|
4904
|
+
global
|
|
4905
|
+
});
|
|
4827
4906
|
}
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
static
|
|
4833
|
-
|
|
4907
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
4908
|
+
const targets = rulesyncSkill.getFrontmatter().targets;
|
|
4909
|
+
return targets.includes("*") || targets.includes("codexcli");
|
|
4910
|
+
}
|
|
4911
|
+
static async fromDir(params) {
|
|
4912
|
+
const loaded = await this.loadSkillDirContent({
|
|
4913
|
+
...params,
|
|
4914
|
+
getSettablePaths: _CodexCliSkill.getSettablePaths
|
|
4915
|
+
});
|
|
4916
|
+
const result = CodexCliSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
4917
|
+
if (!result.success) {
|
|
4918
|
+
const skillDirPath = join44(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
|
|
4919
|
+
throw new Error(
|
|
4920
|
+
`Invalid frontmatter in ${join44(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
|
|
4921
|
+
);
|
|
4922
|
+
}
|
|
4923
|
+
return new _CodexCliSkill({
|
|
4924
|
+
baseDir: loaded.baseDir,
|
|
4925
|
+
relativeDirPath: loaded.relativeDirPath,
|
|
4926
|
+
dirName: loaded.dirName,
|
|
4927
|
+
frontmatter: result.data,
|
|
4928
|
+
body: loaded.body,
|
|
4929
|
+
otherFiles: loaded.otherFiles,
|
|
4930
|
+
validate: true,
|
|
4931
|
+
global: loaded.global
|
|
4932
|
+
});
|
|
4834
4933
|
}
|
|
4835
4934
|
};
|
|
4836
4935
|
|
|
4837
4936
|
// src/features/skills/copilot-skill.ts
|
|
4937
|
+
import { join as join45 } from "path";
|
|
4838
4938
|
var CopilotSkill = class _CopilotSkill extends SimulatedSkill {
|
|
4839
4939
|
static getSettablePaths(options) {
|
|
4840
4940
|
if (options?.global) {
|
|
4841
4941
|
throw new Error("CopilotSkill does not support global mode.");
|
|
4842
4942
|
}
|
|
4843
4943
|
return {
|
|
4844
|
-
relativeDirPath:
|
|
4944
|
+
relativeDirPath: join45(".github", "skills")
|
|
4945
|
+
};
|
|
4946
|
+
}
|
|
4947
|
+
static async fromDir(params) {
|
|
4948
|
+
const baseParams = await this.fromDirDefault(params);
|
|
4949
|
+
return new _CopilotSkill(baseParams);
|
|
4950
|
+
}
|
|
4951
|
+
static fromRulesyncSkill(params) {
|
|
4952
|
+
const baseParams = {
|
|
4953
|
+
...this.fromRulesyncSkillDefault(params),
|
|
4954
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath
|
|
4955
|
+
};
|
|
4956
|
+
return new _CopilotSkill(baseParams);
|
|
4957
|
+
}
|
|
4958
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
4959
|
+
return this.isTargetedByRulesyncSkillDefault({
|
|
4960
|
+
rulesyncSkill,
|
|
4961
|
+
toolTarget: "copilot"
|
|
4962
|
+
});
|
|
4963
|
+
}
|
|
4964
|
+
};
|
|
4965
|
+
|
|
4966
|
+
// src/features/skills/cursor-skill.ts
|
|
4967
|
+
import { join as join46 } from "path";
|
|
4968
|
+
var CursorSkill = class _CursorSkill extends SimulatedSkill {
|
|
4969
|
+
static getSettablePaths(options) {
|
|
4970
|
+
if (options?.global) {
|
|
4971
|
+
throw new Error("CursorSkill does not support global mode.");
|
|
4972
|
+
}
|
|
4973
|
+
return {
|
|
4974
|
+
relativeDirPath: join46(".cursor", "skills")
|
|
4845
4975
|
};
|
|
4846
4976
|
}
|
|
4847
4977
|
static async fromDir(params) {
|
|
4848
4978
|
const baseParams = await this.fromDirDefault(params);
|
|
4849
|
-
return new
|
|
4979
|
+
return new _CursorSkill(baseParams);
|
|
4850
4980
|
}
|
|
4851
4981
|
static fromRulesyncSkill(params) {
|
|
4852
4982
|
const baseParams = {
|
|
4853
4983
|
...this.fromRulesyncSkillDefault(params),
|
|
4854
4984
|
relativeDirPath: this.getSettablePaths().relativeDirPath
|
|
4855
4985
|
};
|
|
4856
|
-
return new
|
|
4986
|
+
return new _CursorSkill(baseParams);
|
|
4857
4987
|
}
|
|
4858
4988
|
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
4859
4989
|
return this.isTargetedByRulesyncSkillDefault({
|
|
4860
4990
|
rulesyncSkill,
|
|
4861
|
-
toolTarget: "
|
|
4991
|
+
toolTarget: "cursor"
|
|
4862
4992
|
});
|
|
4863
4993
|
}
|
|
4864
4994
|
};
|
|
4865
4995
|
|
|
4866
|
-
// src/features/skills/
|
|
4867
|
-
import { join as
|
|
4868
|
-
var
|
|
4996
|
+
// src/features/skills/geminicli-skill.ts
|
|
4997
|
+
import { join as join47 } from "path";
|
|
4998
|
+
var GeminiCliSkill = class _GeminiCliSkill extends SimulatedSkill {
|
|
4869
4999
|
static getSettablePaths(options) {
|
|
4870
5000
|
if (options?.global) {
|
|
4871
|
-
throw new Error("
|
|
5001
|
+
throw new Error("GeminiCliSkill does not support global mode.");
|
|
4872
5002
|
}
|
|
4873
5003
|
return {
|
|
4874
|
-
relativeDirPath:
|
|
5004
|
+
relativeDirPath: join47(".gemini", "skills")
|
|
4875
5005
|
};
|
|
4876
5006
|
}
|
|
4877
5007
|
static async fromDir(params) {
|
|
4878
5008
|
const baseParams = await this.fromDirDefault(params);
|
|
4879
|
-
return new
|
|
5009
|
+
return new _GeminiCliSkill(baseParams);
|
|
4880
5010
|
}
|
|
4881
5011
|
static fromRulesyncSkill(params) {
|
|
4882
5012
|
const baseParams = {
|
|
4883
5013
|
...this.fromRulesyncSkillDefault(params),
|
|
4884
5014
|
relativeDirPath: this.getSettablePaths().relativeDirPath
|
|
4885
5015
|
};
|
|
4886
|
-
return new
|
|
5016
|
+
return new _GeminiCliSkill(baseParams);
|
|
4887
5017
|
}
|
|
4888
5018
|
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
4889
5019
|
return this.isTargetedByRulesyncSkillDefault({
|
|
4890
5020
|
rulesyncSkill,
|
|
4891
|
-
toolTarget: "
|
|
5021
|
+
toolTarget: "geminicli"
|
|
4892
5022
|
});
|
|
4893
5023
|
}
|
|
4894
5024
|
};
|
|
@@ -4898,7 +5028,7 @@ import { basename as basename15, join as join50 } from "path";
|
|
|
4898
5028
|
import { z as z23 } from "zod/mini";
|
|
4899
5029
|
|
|
4900
5030
|
// src/types/dir-feature-processor.ts
|
|
4901
|
-
import { join as
|
|
5031
|
+
import { join as join48 } from "path";
|
|
4902
5032
|
var DirFeatureProcessor = class {
|
|
4903
5033
|
baseDir;
|
|
4904
5034
|
constructor({ baseDir = process.cwd() }) {
|
|
@@ -4920,14 +5050,14 @@ var DirFeatureProcessor = class {
|
|
|
4920
5050
|
await ensureDir(dirPath);
|
|
4921
5051
|
const mainFile = aiDir.getMainFile();
|
|
4922
5052
|
if (mainFile) {
|
|
4923
|
-
const mainFilePath =
|
|
5053
|
+
const mainFilePath = join48(dirPath, mainFile.name);
|
|
4924
5054
|
const content = stringifyFrontmatter(mainFile.body, mainFile.frontmatter);
|
|
4925
5055
|
const contentWithNewline = addTrailingNewline(content);
|
|
4926
5056
|
await writeFileContent(mainFilePath, contentWithNewline);
|
|
4927
5057
|
}
|
|
4928
5058
|
const otherFiles = aiDir.getOtherFiles();
|
|
4929
5059
|
for (const file of otherFiles) {
|
|
4930
|
-
const filePath =
|
|
5060
|
+
const filePath = join48(dirPath, file.relativeFilePathToDirPath);
|
|
4931
5061
|
const contentWithNewline = addTrailingNewline(file.fileBuffer.toString("utf-8"));
|
|
4932
5062
|
await writeFileContent(filePath, contentWithNewline);
|
|
4933
5063
|
}
|
|
@@ -4941,38 +5071,8 @@ var DirFeatureProcessor = class {
|
|
|
4941
5071
|
}
|
|
4942
5072
|
};
|
|
4943
5073
|
|
|
4944
|
-
// src/features/skills/agentsmd-skill.ts
|
|
4945
|
-
import { join as join47 } from "path";
|
|
4946
|
-
var AgentsmdSkill = class _AgentsmdSkill extends SimulatedSkill {
|
|
4947
|
-
static getSettablePaths(options) {
|
|
4948
|
-
if (options?.global) {
|
|
4949
|
-
throw new Error("AgentsmdSkill does not support global mode.");
|
|
4950
|
-
}
|
|
4951
|
-
return {
|
|
4952
|
-
relativeDirPath: join47(".agents", "skills")
|
|
4953
|
-
};
|
|
4954
|
-
}
|
|
4955
|
-
static async fromDir(params) {
|
|
4956
|
-
const baseParams = await this.fromDirDefault(params);
|
|
4957
|
-
return new _AgentsmdSkill(baseParams);
|
|
4958
|
-
}
|
|
4959
|
-
static fromRulesyncSkill(params) {
|
|
4960
|
-
const baseParams = {
|
|
4961
|
-
...this.fromRulesyncSkillDefault(params),
|
|
4962
|
-
relativeDirPath: this.getSettablePaths().relativeDirPath
|
|
4963
|
-
};
|
|
4964
|
-
return new _AgentsmdSkill(baseParams);
|
|
4965
|
-
}
|
|
4966
|
-
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
4967
|
-
return this.isTargetedByRulesyncSkillDefault({
|
|
4968
|
-
rulesyncSkill,
|
|
4969
|
-
toolTarget: "agentsmd"
|
|
4970
|
-
});
|
|
4971
|
-
}
|
|
4972
|
-
};
|
|
4973
|
-
|
|
4974
5074
|
// src/features/skills/claudecode-skill.ts
|
|
4975
|
-
import { join as
|
|
5075
|
+
import { join as join49 } from "path";
|
|
4976
5076
|
import { z as z22 } from "zod/mini";
|
|
4977
5077
|
var ClaudecodeSkillFrontmatterSchema = z22.object({
|
|
4978
5078
|
name: z22.string(),
|
|
@@ -4982,7 +5082,7 @@ var ClaudecodeSkillFrontmatterSchema = z22.object({
|
|
|
4982
5082
|
var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
|
|
4983
5083
|
constructor({
|
|
4984
5084
|
baseDir = process.cwd(),
|
|
4985
|
-
relativeDirPath =
|
|
5085
|
+
relativeDirPath = join49(".claude", "skills"),
|
|
4986
5086
|
dirName,
|
|
4987
5087
|
frontmatter,
|
|
4988
5088
|
body,
|
|
@@ -5013,7 +5113,7 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
|
|
|
5013
5113
|
global: _global = false
|
|
5014
5114
|
} = {}) {
|
|
5015
5115
|
return {
|
|
5016
|
-
relativeDirPath:
|
|
5116
|
+
relativeDirPath: join49(".claude", "skills")
|
|
5017
5117
|
};
|
|
5018
5118
|
}
|
|
5019
5119
|
getFrontmatter() {
|
|
@@ -5100,9 +5200,9 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
|
|
|
5100
5200
|
});
|
|
5101
5201
|
const result = ClaudecodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
5102
5202
|
if (!result.success) {
|
|
5103
|
-
const skillDirPath =
|
|
5203
|
+
const skillDirPath = join49(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
|
|
5104
5204
|
throw new Error(
|
|
5105
|
-
`Invalid frontmatter in ${
|
|
5205
|
+
`Invalid frontmatter in ${join49(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
|
|
5106
5206
|
);
|
|
5107
5207
|
}
|
|
5108
5208
|
return new _ClaudecodeSkill({
|
|
@@ -5118,36 +5218,6 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
|
|
|
5118
5218
|
}
|
|
5119
5219
|
};
|
|
5120
5220
|
|
|
5121
|
-
// src/features/skills/geminicli-skill.ts
|
|
5122
|
-
import { join as join49 } from "path";
|
|
5123
|
-
var GeminiCliSkill = class _GeminiCliSkill extends SimulatedSkill {
|
|
5124
|
-
static getSettablePaths(options) {
|
|
5125
|
-
if (options?.global) {
|
|
5126
|
-
throw new Error("GeminiCliSkill does not support global mode.");
|
|
5127
|
-
}
|
|
5128
|
-
return {
|
|
5129
|
-
relativeDirPath: join49(".gemini", "skills")
|
|
5130
|
-
};
|
|
5131
|
-
}
|
|
5132
|
-
static async fromDir(params) {
|
|
5133
|
-
const baseParams = await this.fromDirDefault(params);
|
|
5134
|
-
return new _GeminiCliSkill(baseParams);
|
|
5135
|
-
}
|
|
5136
|
-
static fromRulesyncSkill(params) {
|
|
5137
|
-
const baseParams = {
|
|
5138
|
-
...this.fromRulesyncSkillDefault(params),
|
|
5139
|
-
relativeDirPath: this.getSettablePaths().relativeDirPath
|
|
5140
|
-
};
|
|
5141
|
-
return new _GeminiCliSkill(baseParams);
|
|
5142
|
-
}
|
|
5143
|
-
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
5144
|
-
return this.isTargetedByRulesyncSkillDefault({
|
|
5145
|
-
rulesyncSkill,
|
|
5146
|
-
toolTarget: "geminicli"
|
|
5147
|
-
});
|
|
5148
|
-
}
|
|
5149
|
-
};
|
|
5150
|
-
|
|
5151
5221
|
// src/features/skills/skills-processor.ts
|
|
5152
5222
|
var skillsProcessorToolTargetTuple = [
|
|
5153
5223
|
"agentsmd",
|
|
@@ -6062,6 +6132,13 @@ var RulesyncRuleFrontmatterSchema = z28.object({
|
|
|
6062
6132
|
subprojectPath: z28.optional(z28.string())
|
|
6063
6133
|
})
|
|
6064
6134
|
),
|
|
6135
|
+
claudecode: z28.optional(
|
|
6136
|
+
z28.object({
|
|
6137
|
+
// Glob patterns for conditional rules (takes precedence over globs)
|
|
6138
|
+
// @example "src/**/*.ts, tests/**/*.test.ts"
|
|
6139
|
+
paths: z28.optional(z28.string())
|
|
6140
|
+
})
|
|
6141
|
+
),
|
|
6065
6142
|
cursor: z28.optional(
|
|
6066
6143
|
z28.object({
|
|
6067
6144
|
alwaysApply: z28.optional(z28.boolean()),
|
|
@@ -6625,9 +6702,9 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
|
6625
6702
|
}
|
|
6626
6703
|
};
|
|
6627
6704
|
|
|
6628
|
-
// src/features/rules/claudecode-rule.ts
|
|
6705
|
+
// src/features/rules/claudecode-legacy-rule.ts
|
|
6629
6706
|
import { join as join68 } from "path";
|
|
6630
|
-
var
|
|
6707
|
+
var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
|
|
6631
6708
|
static getSettablePaths({
|
|
6632
6709
|
global
|
|
6633
6710
|
} = {}) {
|
|
@@ -6662,7 +6739,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
6662
6739
|
const fileContent2 = await readFileContent(
|
|
6663
6740
|
join68(baseDir, paths.root.relativeDirPath, relativePath2)
|
|
6664
6741
|
);
|
|
6665
|
-
return new
|
|
6742
|
+
return new _ClaudecodeLegacyRule({
|
|
6666
6743
|
baseDir,
|
|
6667
6744
|
relativeDirPath: paths.root.relativeDirPath,
|
|
6668
6745
|
relativeFilePath: paths.root.relativeFilePath,
|
|
@@ -6676,7 +6753,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
6676
6753
|
}
|
|
6677
6754
|
const relativePath = join68(paths.nonRoot.relativeDirPath, relativeFilePath);
|
|
6678
6755
|
const fileContent = await readFileContent(join68(baseDir, relativePath));
|
|
6679
|
-
return new
|
|
6756
|
+
return new _ClaudecodeLegacyRule({
|
|
6680
6757
|
baseDir,
|
|
6681
6758
|
relativeDirPath: paths.nonRoot.relativeDirPath,
|
|
6682
6759
|
relativeFilePath,
|
|
@@ -6692,7 +6769,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
6692
6769
|
global = false
|
|
6693
6770
|
}) {
|
|
6694
6771
|
const paths = this.getSettablePaths({ global });
|
|
6695
|
-
return new
|
|
6772
|
+
return new _ClaudecodeLegacyRule(
|
|
6696
6773
|
this.buildToolRuleParamsDefault({
|
|
6697
6774
|
baseDir,
|
|
6698
6775
|
rulesyncRule,
|
|
@@ -6711,16 +6788,208 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
6711
6788
|
static isTargetedByRulesyncRule(rulesyncRule) {
|
|
6712
6789
|
return this.isTargetedByRulesyncRuleDefault({
|
|
6713
6790
|
rulesyncRule,
|
|
6714
|
-
toolTarget: "claudecode"
|
|
6791
|
+
toolTarget: "claudecode-legacy"
|
|
6715
6792
|
});
|
|
6716
6793
|
}
|
|
6717
6794
|
};
|
|
6718
6795
|
|
|
6719
|
-
// src/features/rules/
|
|
6796
|
+
// src/features/rules/claudecode-rule.ts
|
|
6720
6797
|
import { join as join69 } from "path";
|
|
6721
6798
|
import { z as z29 } from "zod/mini";
|
|
6722
|
-
var
|
|
6723
|
-
|
|
6799
|
+
var ClaudecodeRuleFrontmatterSchema = z29.object({
|
|
6800
|
+
paths: z29.optional(z29.string())
|
|
6801
|
+
});
|
|
6802
|
+
var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
6803
|
+
frontmatter;
|
|
6804
|
+
body;
|
|
6805
|
+
static getSettablePaths({
|
|
6806
|
+
global
|
|
6807
|
+
} = {}) {
|
|
6808
|
+
if (global) {
|
|
6809
|
+
return {
|
|
6810
|
+
root: {
|
|
6811
|
+
relativeDirPath: ".claude",
|
|
6812
|
+
relativeFilePath: "CLAUDE.md"
|
|
6813
|
+
}
|
|
6814
|
+
};
|
|
6815
|
+
}
|
|
6816
|
+
return {
|
|
6817
|
+
root: {
|
|
6818
|
+
relativeDirPath: ".claude",
|
|
6819
|
+
relativeFilePath: "CLAUDE.md"
|
|
6820
|
+
},
|
|
6821
|
+
nonRoot: {
|
|
6822
|
+
relativeDirPath: join69(".claude", "rules")
|
|
6823
|
+
}
|
|
6824
|
+
};
|
|
6825
|
+
}
|
|
6826
|
+
constructor({ frontmatter, body, ...rest }) {
|
|
6827
|
+
if (rest.validate) {
|
|
6828
|
+
const result = ClaudecodeRuleFrontmatterSchema.safeParse(frontmatter);
|
|
6829
|
+
if (!result.success) {
|
|
6830
|
+
throw new Error(
|
|
6831
|
+
`Invalid frontmatter in ${join69(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
|
|
6832
|
+
);
|
|
6833
|
+
}
|
|
6834
|
+
}
|
|
6835
|
+
super({
|
|
6836
|
+
...rest,
|
|
6837
|
+
// Root file: no frontmatter; Non-root file: with optional paths frontmatter
|
|
6838
|
+
fileContent: rest.root ? body : _ClaudecodeRule.generateFileContent(body, frontmatter)
|
|
6839
|
+
});
|
|
6840
|
+
this.frontmatter = frontmatter;
|
|
6841
|
+
this.body = body;
|
|
6842
|
+
}
|
|
6843
|
+
static generateFileContent(body, frontmatter) {
|
|
6844
|
+
if (frontmatter.paths) {
|
|
6845
|
+
return stringifyFrontmatter(body, { paths: frontmatter.paths });
|
|
6846
|
+
}
|
|
6847
|
+
return body;
|
|
6848
|
+
}
|
|
6849
|
+
static async fromFile({
|
|
6850
|
+
baseDir = process.cwd(),
|
|
6851
|
+
relativeFilePath,
|
|
6852
|
+
validate = true,
|
|
6853
|
+
global = false
|
|
6854
|
+
}) {
|
|
6855
|
+
const paths = this.getSettablePaths({ global });
|
|
6856
|
+
const isRoot = relativeFilePath === paths.root.relativeFilePath;
|
|
6857
|
+
if (isRoot) {
|
|
6858
|
+
const fileContent2 = await readFileContent(
|
|
6859
|
+
join69(baseDir, paths.root.relativeDirPath, paths.root.relativeFilePath)
|
|
6860
|
+
);
|
|
6861
|
+
return new _ClaudecodeRule({
|
|
6862
|
+
baseDir,
|
|
6863
|
+
relativeDirPath: paths.root.relativeDirPath,
|
|
6864
|
+
relativeFilePath: paths.root.relativeFilePath,
|
|
6865
|
+
frontmatter: {},
|
|
6866
|
+
body: fileContent2.trim(),
|
|
6867
|
+
validate,
|
|
6868
|
+
root: true
|
|
6869
|
+
});
|
|
6870
|
+
}
|
|
6871
|
+
if (!paths.nonRoot) {
|
|
6872
|
+
throw new Error("nonRoot path is not set");
|
|
6873
|
+
}
|
|
6874
|
+
const relativePath = join69(paths.nonRoot.relativeDirPath, relativeFilePath);
|
|
6875
|
+
const fileContent = await readFileContent(join69(baseDir, relativePath));
|
|
6876
|
+
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
6877
|
+
const result = ClaudecodeRuleFrontmatterSchema.safeParse(frontmatter);
|
|
6878
|
+
if (!result.success) {
|
|
6879
|
+
throw new Error(
|
|
6880
|
+
`Invalid frontmatter in ${join69(baseDir, relativePath)}: ${formatError(result.error)}`
|
|
6881
|
+
);
|
|
6882
|
+
}
|
|
6883
|
+
return new _ClaudecodeRule({
|
|
6884
|
+
baseDir,
|
|
6885
|
+
relativeDirPath: paths.nonRoot.relativeDirPath,
|
|
6886
|
+
relativeFilePath,
|
|
6887
|
+
frontmatter: result.data,
|
|
6888
|
+
body: content.trim(),
|
|
6889
|
+
validate,
|
|
6890
|
+
root: false
|
|
6891
|
+
});
|
|
6892
|
+
}
|
|
6893
|
+
static fromRulesyncRule({
|
|
6894
|
+
baseDir = process.cwd(),
|
|
6895
|
+
rulesyncRule,
|
|
6896
|
+
validate = true,
|
|
6897
|
+
global = false
|
|
6898
|
+
}) {
|
|
6899
|
+
const rulesyncFrontmatter = rulesyncRule.getFrontmatter();
|
|
6900
|
+
const root = rulesyncFrontmatter.root ?? false;
|
|
6901
|
+
const paths = this.getSettablePaths({ global });
|
|
6902
|
+
const claudecodePaths = rulesyncFrontmatter.claudecode?.paths;
|
|
6903
|
+
const globs = rulesyncFrontmatter.globs;
|
|
6904
|
+
const pathsValue = claudecodePaths ?? (globs?.length ? globs.join(", ") : void 0);
|
|
6905
|
+
const claudecodeFrontmatter = {
|
|
6906
|
+
paths: root ? void 0 : pathsValue
|
|
6907
|
+
};
|
|
6908
|
+
const body = rulesyncRule.getBody();
|
|
6909
|
+
if (root) {
|
|
6910
|
+
return new _ClaudecodeRule({
|
|
6911
|
+
baseDir,
|
|
6912
|
+
frontmatter: claudecodeFrontmatter,
|
|
6913
|
+
body,
|
|
6914
|
+
relativeDirPath: paths.root.relativeDirPath,
|
|
6915
|
+
relativeFilePath: paths.root.relativeFilePath,
|
|
6916
|
+
validate,
|
|
6917
|
+
root
|
|
6918
|
+
});
|
|
6919
|
+
}
|
|
6920
|
+
if (!paths.nonRoot) {
|
|
6921
|
+
throw new Error("nonRoot path is not set");
|
|
6922
|
+
}
|
|
6923
|
+
return new _ClaudecodeRule({
|
|
6924
|
+
baseDir,
|
|
6925
|
+
frontmatter: claudecodeFrontmatter,
|
|
6926
|
+
body,
|
|
6927
|
+
relativeDirPath: paths.nonRoot.relativeDirPath,
|
|
6928
|
+
relativeFilePath: rulesyncRule.getRelativeFilePath(),
|
|
6929
|
+
validate,
|
|
6930
|
+
root
|
|
6931
|
+
});
|
|
6932
|
+
}
|
|
6933
|
+
toRulesyncRule() {
|
|
6934
|
+
let globs;
|
|
6935
|
+
if (this.isRoot()) {
|
|
6936
|
+
globs = ["**/*"];
|
|
6937
|
+
} else if (this.frontmatter.paths) {
|
|
6938
|
+
globs = this.frontmatter.paths.split(",").map((g) => g.trim());
|
|
6939
|
+
}
|
|
6940
|
+
const rulesyncFrontmatter = {
|
|
6941
|
+
targets: ["*"],
|
|
6942
|
+
root: this.isRoot(),
|
|
6943
|
+
description: this.description,
|
|
6944
|
+
globs,
|
|
6945
|
+
...this.frontmatter.paths && {
|
|
6946
|
+
claudecode: { paths: this.frontmatter.paths }
|
|
6947
|
+
}
|
|
6948
|
+
};
|
|
6949
|
+
return new RulesyncRule({
|
|
6950
|
+
baseDir: this.getBaseDir(),
|
|
6951
|
+
frontmatter: rulesyncFrontmatter,
|
|
6952
|
+
body: this.body,
|
|
6953
|
+
relativeDirPath: RULESYNC_RULES_RELATIVE_DIR_PATH,
|
|
6954
|
+
relativeFilePath: this.getRelativeFilePath(),
|
|
6955
|
+
validate: true
|
|
6956
|
+
});
|
|
6957
|
+
}
|
|
6958
|
+
validate() {
|
|
6959
|
+
if (!this.frontmatter) {
|
|
6960
|
+
return { success: true, error: null };
|
|
6961
|
+
}
|
|
6962
|
+
const result = ClaudecodeRuleFrontmatterSchema.safeParse(this.frontmatter);
|
|
6963
|
+
if (result.success) {
|
|
6964
|
+
return { success: true, error: null };
|
|
6965
|
+
} else {
|
|
6966
|
+
return {
|
|
6967
|
+
success: false,
|
|
6968
|
+
error: new Error(
|
|
6969
|
+
`Invalid frontmatter in ${join69(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
|
|
6970
|
+
)
|
|
6971
|
+
};
|
|
6972
|
+
}
|
|
6973
|
+
}
|
|
6974
|
+
getFrontmatter() {
|
|
6975
|
+
return this.frontmatter;
|
|
6976
|
+
}
|
|
6977
|
+
getBody() {
|
|
6978
|
+
return this.body;
|
|
6979
|
+
}
|
|
6980
|
+
static isTargetedByRulesyncRule(rulesyncRule) {
|
|
6981
|
+
return this.isTargetedByRulesyncRuleDefault({
|
|
6982
|
+
rulesyncRule,
|
|
6983
|
+
toolTarget: "claudecode"
|
|
6984
|
+
});
|
|
6985
|
+
}
|
|
6986
|
+
};
|
|
6987
|
+
|
|
6988
|
+
// src/features/rules/cline-rule.ts
|
|
6989
|
+
import { join as join70 } from "path";
|
|
6990
|
+
import { z as z30 } from "zod/mini";
|
|
6991
|
+
var ClineRuleFrontmatterSchema = z30.object({
|
|
6992
|
+
description: z30.string()
|
|
6724
6993
|
});
|
|
6725
6994
|
var ClineRule = class _ClineRule extends ToolRule {
|
|
6726
6995
|
static getSettablePaths() {
|
|
@@ -6762,7 +7031,7 @@ var ClineRule = class _ClineRule extends ToolRule {
|
|
|
6762
7031
|
validate = true
|
|
6763
7032
|
}) {
|
|
6764
7033
|
const fileContent = await readFileContent(
|
|
6765
|
-
|
|
7034
|
+
join70(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
6766
7035
|
);
|
|
6767
7036
|
return new _ClineRule({
|
|
6768
7037
|
baseDir,
|
|
@@ -6775,7 +7044,7 @@ var ClineRule = class _ClineRule extends ToolRule {
|
|
|
6775
7044
|
};
|
|
6776
7045
|
|
|
6777
7046
|
// src/features/rules/codexcli-rule.ts
|
|
6778
|
-
import { join as
|
|
7047
|
+
import { join as join71 } from "path";
|
|
6779
7048
|
var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
6780
7049
|
static getSettablePaths({
|
|
6781
7050
|
global
|
|
@@ -6794,7 +7063,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
6794
7063
|
relativeFilePath: "AGENTS.md"
|
|
6795
7064
|
},
|
|
6796
7065
|
nonRoot: {
|
|
6797
|
-
relativeDirPath:
|
|
7066
|
+
relativeDirPath: join71(".codex", "memories")
|
|
6798
7067
|
}
|
|
6799
7068
|
};
|
|
6800
7069
|
}
|
|
@@ -6809,7 +7078,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
6809
7078
|
if (isRoot) {
|
|
6810
7079
|
const relativePath2 = paths.root.relativeFilePath;
|
|
6811
7080
|
const fileContent2 = await readFileContent(
|
|
6812
|
-
|
|
7081
|
+
join71(baseDir, paths.root.relativeDirPath, relativePath2)
|
|
6813
7082
|
);
|
|
6814
7083
|
return new _CodexcliRule({
|
|
6815
7084
|
baseDir,
|
|
@@ -6823,8 +7092,8 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
6823
7092
|
if (!paths.nonRoot) {
|
|
6824
7093
|
throw new Error("nonRoot path is not set");
|
|
6825
7094
|
}
|
|
6826
|
-
const relativePath =
|
|
6827
|
-
const fileContent = await readFileContent(
|
|
7095
|
+
const relativePath = join71(paths.nonRoot.relativeDirPath, relativeFilePath);
|
|
7096
|
+
const fileContent = await readFileContent(join71(baseDir, relativePath));
|
|
6828
7097
|
return new _CodexcliRule({
|
|
6829
7098
|
baseDir,
|
|
6830
7099
|
relativeDirPath: paths.nonRoot.relativeDirPath,
|
|
@@ -6866,12 +7135,12 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
6866
7135
|
};
|
|
6867
7136
|
|
|
6868
7137
|
// src/features/rules/copilot-rule.ts
|
|
6869
|
-
import { join as
|
|
6870
|
-
import { z as
|
|
6871
|
-
var CopilotRuleFrontmatterSchema =
|
|
6872
|
-
description:
|
|
6873
|
-
applyTo:
|
|
6874
|
-
excludeAgent:
|
|
7138
|
+
import { join as join72 } from "path";
|
|
7139
|
+
import { z as z31 } from "zod/mini";
|
|
7140
|
+
var CopilotRuleFrontmatterSchema = z31.object({
|
|
7141
|
+
description: z31.optional(z31.string()),
|
|
7142
|
+
applyTo: z31.optional(z31.string()),
|
|
7143
|
+
excludeAgent: z31.optional(z31.union([z31.literal("code-review"), z31.literal("coding-agent")]))
|
|
6875
7144
|
});
|
|
6876
7145
|
var CopilotRule = class _CopilotRule extends ToolRule {
|
|
6877
7146
|
frontmatter;
|
|
@@ -6883,7 +7152,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
6883
7152
|
relativeFilePath: "copilot-instructions.md"
|
|
6884
7153
|
},
|
|
6885
7154
|
nonRoot: {
|
|
6886
|
-
relativeDirPath:
|
|
7155
|
+
relativeDirPath: join72(".github", "instructions")
|
|
6887
7156
|
}
|
|
6888
7157
|
};
|
|
6889
7158
|
}
|
|
@@ -6892,7 +7161,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
6892
7161
|
const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
|
|
6893
7162
|
if (!result.success) {
|
|
6894
7163
|
throw new Error(
|
|
6895
|
-
`Invalid frontmatter in ${
|
|
7164
|
+
`Invalid frontmatter in ${join72(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
|
|
6896
7165
|
);
|
|
6897
7166
|
}
|
|
6898
7167
|
}
|
|
@@ -6974,11 +7243,11 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
6974
7243
|
validate = true
|
|
6975
7244
|
}) {
|
|
6976
7245
|
const isRoot = relativeFilePath === "copilot-instructions.md";
|
|
6977
|
-
const relativePath = isRoot ?
|
|
7246
|
+
const relativePath = isRoot ? join72(
|
|
6978
7247
|
this.getSettablePaths().root.relativeDirPath,
|
|
6979
7248
|
this.getSettablePaths().root.relativeFilePath
|
|
6980
|
-
) :
|
|
6981
|
-
const fileContent = await readFileContent(
|
|
7249
|
+
) : join72(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
|
|
7250
|
+
const fileContent = await readFileContent(join72(baseDir, relativePath));
|
|
6982
7251
|
if (isRoot) {
|
|
6983
7252
|
return new _CopilotRule({
|
|
6984
7253
|
baseDir,
|
|
@@ -6994,7 +7263,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
6994
7263
|
const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
|
|
6995
7264
|
if (!result.success) {
|
|
6996
7265
|
throw new Error(
|
|
6997
|
-
`Invalid frontmatter in ${
|
|
7266
|
+
`Invalid frontmatter in ${join72(baseDir, relativeFilePath)}: ${formatError(result.error)}`
|
|
6998
7267
|
);
|
|
6999
7268
|
}
|
|
7000
7269
|
return new _CopilotRule({
|
|
@@ -7018,7 +7287,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
7018
7287
|
return {
|
|
7019
7288
|
success: false,
|
|
7020
7289
|
error: new Error(
|
|
7021
|
-
`Invalid frontmatter in ${
|
|
7290
|
+
`Invalid frontmatter in ${join72(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
|
|
7022
7291
|
)
|
|
7023
7292
|
};
|
|
7024
7293
|
}
|
|
@@ -7038,12 +7307,12 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
7038
7307
|
};
|
|
7039
7308
|
|
|
7040
7309
|
// src/features/rules/cursor-rule.ts
|
|
7041
|
-
import { basename as basename20, join as
|
|
7042
|
-
import { z as
|
|
7043
|
-
var CursorRuleFrontmatterSchema =
|
|
7044
|
-
description:
|
|
7045
|
-
globs:
|
|
7046
|
-
alwaysApply:
|
|
7310
|
+
import { basename as basename20, join as join73 } from "path";
|
|
7311
|
+
import { z as z32 } from "zod/mini";
|
|
7312
|
+
var CursorRuleFrontmatterSchema = z32.object({
|
|
7313
|
+
description: z32.optional(z32.string()),
|
|
7314
|
+
globs: z32.optional(z32.string()),
|
|
7315
|
+
alwaysApply: z32.optional(z32.boolean())
|
|
7047
7316
|
});
|
|
7048
7317
|
var CursorRule = class _CursorRule extends ToolRule {
|
|
7049
7318
|
frontmatter;
|
|
@@ -7051,7 +7320,7 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
7051
7320
|
static getSettablePaths() {
|
|
7052
7321
|
return {
|
|
7053
7322
|
nonRoot: {
|
|
7054
|
-
relativeDirPath:
|
|
7323
|
+
relativeDirPath: join73(".cursor", "rules")
|
|
7055
7324
|
}
|
|
7056
7325
|
};
|
|
7057
7326
|
}
|
|
@@ -7060,7 +7329,7 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
7060
7329
|
const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
|
|
7061
7330
|
if (!result.success) {
|
|
7062
7331
|
throw new Error(
|
|
7063
|
-
`Invalid frontmatter in ${
|
|
7332
|
+
`Invalid frontmatter in ${join73(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
|
|
7064
7333
|
);
|
|
7065
7334
|
}
|
|
7066
7335
|
}
|
|
@@ -7177,13 +7446,13 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
7177
7446
|
validate = true
|
|
7178
7447
|
}) {
|
|
7179
7448
|
const fileContent = await readFileContent(
|
|
7180
|
-
|
|
7449
|
+
join73(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
7181
7450
|
);
|
|
7182
7451
|
const { frontmatter, body: content } = _CursorRule.parseCursorFrontmatter(fileContent);
|
|
7183
7452
|
const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
|
|
7184
7453
|
if (!result.success) {
|
|
7185
7454
|
throw new Error(
|
|
7186
|
-
`Invalid frontmatter in ${
|
|
7455
|
+
`Invalid frontmatter in ${join73(baseDir, relativeFilePath)}: ${formatError(result.error)}`
|
|
7187
7456
|
);
|
|
7188
7457
|
}
|
|
7189
7458
|
return new _CursorRule({
|
|
@@ -7206,7 +7475,7 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
7206
7475
|
return {
|
|
7207
7476
|
success: false,
|
|
7208
7477
|
error: new Error(
|
|
7209
|
-
`Invalid frontmatter in ${
|
|
7478
|
+
`Invalid frontmatter in ${join73(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
|
|
7210
7479
|
)
|
|
7211
7480
|
};
|
|
7212
7481
|
}
|
|
@@ -7226,7 +7495,7 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
7226
7495
|
};
|
|
7227
7496
|
|
|
7228
7497
|
// src/features/rules/geminicli-rule.ts
|
|
7229
|
-
import { join as
|
|
7498
|
+
import { join as join74 } from "path";
|
|
7230
7499
|
var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
7231
7500
|
static getSettablePaths({
|
|
7232
7501
|
global
|
|
@@ -7245,7 +7514,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
7245
7514
|
relativeFilePath: "GEMINI.md"
|
|
7246
7515
|
},
|
|
7247
7516
|
nonRoot: {
|
|
7248
|
-
relativeDirPath:
|
|
7517
|
+
relativeDirPath: join74(".gemini", "memories")
|
|
7249
7518
|
}
|
|
7250
7519
|
};
|
|
7251
7520
|
}
|
|
@@ -7260,7 +7529,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
7260
7529
|
if (isRoot) {
|
|
7261
7530
|
const relativePath2 = paths.root.relativeFilePath;
|
|
7262
7531
|
const fileContent2 = await readFileContent(
|
|
7263
|
-
|
|
7532
|
+
join74(baseDir, paths.root.relativeDirPath, relativePath2)
|
|
7264
7533
|
);
|
|
7265
7534
|
return new _GeminiCliRule({
|
|
7266
7535
|
baseDir,
|
|
@@ -7274,8 +7543,8 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
7274
7543
|
if (!paths.nonRoot) {
|
|
7275
7544
|
throw new Error("nonRoot path is not set");
|
|
7276
7545
|
}
|
|
7277
|
-
const relativePath =
|
|
7278
|
-
const fileContent = await readFileContent(
|
|
7546
|
+
const relativePath = join74(paths.nonRoot.relativeDirPath, relativeFilePath);
|
|
7547
|
+
const fileContent = await readFileContent(join74(baseDir, relativePath));
|
|
7279
7548
|
return new _GeminiCliRule({
|
|
7280
7549
|
baseDir,
|
|
7281
7550
|
relativeDirPath: paths.nonRoot.relativeDirPath,
|
|
@@ -7317,7 +7586,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
7317
7586
|
};
|
|
7318
7587
|
|
|
7319
7588
|
// src/features/rules/junie-rule.ts
|
|
7320
|
-
import { join as
|
|
7589
|
+
import { join as join75 } from "path";
|
|
7321
7590
|
var JunieRule = class _JunieRule extends ToolRule {
|
|
7322
7591
|
static getSettablePaths() {
|
|
7323
7592
|
return {
|
|
@@ -7326,7 +7595,7 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
7326
7595
|
relativeFilePath: "guidelines.md"
|
|
7327
7596
|
},
|
|
7328
7597
|
nonRoot: {
|
|
7329
|
-
relativeDirPath:
|
|
7598
|
+
relativeDirPath: join75(".junie", "memories")
|
|
7330
7599
|
}
|
|
7331
7600
|
};
|
|
7332
7601
|
}
|
|
@@ -7336,8 +7605,8 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
7336
7605
|
validate = true
|
|
7337
7606
|
}) {
|
|
7338
7607
|
const isRoot = relativeFilePath === "guidelines.md";
|
|
7339
|
-
const relativePath = isRoot ? "guidelines.md" :
|
|
7340
|
-
const fileContent = await readFileContent(
|
|
7608
|
+
const relativePath = isRoot ? "guidelines.md" : join75(".junie", "memories", relativeFilePath);
|
|
7609
|
+
const fileContent = await readFileContent(join75(baseDir, relativePath));
|
|
7341
7610
|
return new _JunieRule({
|
|
7342
7611
|
baseDir,
|
|
7343
7612
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -7377,12 +7646,12 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
7377
7646
|
};
|
|
7378
7647
|
|
|
7379
7648
|
// src/features/rules/kiro-rule.ts
|
|
7380
|
-
import { join as
|
|
7649
|
+
import { join as join76 } from "path";
|
|
7381
7650
|
var KiroRule = class _KiroRule extends ToolRule {
|
|
7382
7651
|
static getSettablePaths() {
|
|
7383
7652
|
return {
|
|
7384
7653
|
nonRoot: {
|
|
7385
|
-
relativeDirPath:
|
|
7654
|
+
relativeDirPath: join76(".kiro", "steering")
|
|
7386
7655
|
}
|
|
7387
7656
|
};
|
|
7388
7657
|
}
|
|
@@ -7392,7 +7661,7 @@ var KiroRule = class _KiroRule extends ToolRule {
|
|
|
7392
7661
|
validate = true
|
|
7393
7662
|
}) {
|
|
7394
7663
|
const fileContent = await readFileContent(
|
|
7395
|
-
|
|
7664
|
+
join76(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
7396
7665
|
);
|
|
7397
7666
|
return new _KiroRule({
|
|
7398
7667
|
baseDir,
|
|
@@ -7432,7 +7701,7 @@ var KiroRule = class _KiroRule extends ToolRule {
|
|
|
7432
7701
|
};
|
|
7433
7702
|
|
|
7434
7703
|
// src/features/rules/opencode-rule.ts
|
|
7435
|
-
import { join as
|
|
7704
|
+
import { join as join77 } from "path";
|
|
7436
7705
|
var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
7437
7706
|
static getSettablePaths() {
|
|
7438
7707
|
return {
|
|
@@ -7441,7 +7710,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
|
7441
7710
|
relativeFilePath: "AGENTS.md"
|
|
7442
7711
|
},
|
|
7443
7712
|
nonRoot: {
|
|
7444
|
-
relativeDirPath:
|
|
7713
|
+
relativeDirPath: join77(".opencode", "memories")
|
|
7445
7714
|
}
|
|
7446
7715
|
};
|
|
7447
7716
|
}
|
|
@@ -7451,8 +7720,8 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
|
7451
7720
|
validate = true
|
|
7452
7721
|
}) {
|
|
7453
7722
|
const isRoot = relativeFilePath === "AGENTS.md";
|
|
7454
|
-
const relativePath = isRoot ? "AGENTS.md" :
|
|
7455
|
-
const fileContent = await readFileContent(
|
|
7723
|
+
const relativePath = isRoot ? "AGENTS.md" : join77(".opencode", "memories", relativeFilePath);
|
|
7724
|
+
const fileContent = await readFileContent(join77(baseDir, relativePath));
|
|
7456
7725
|
return new _OpenCodeRule({
|
|
7457
7726
|
baseDir,
|
|
7458
7727
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -7492,7 +7761,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
|
7492
7761
|
};
|
|
7493
7762
|
|
|
7494
7763
|
// src/features/rules/qwencode-rule.ts
|
|
7495
|
-
import { join as
|
|
7764
|
+
import { join as join78 } from "path";
|
|
7496
7765
|
var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
7497
7766
|
static getSettablePaths() {
|
|
7498
7767
|
return {
|
|
@@ -7501,7 +7770,7 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
|
7501
7770
|
relativeFilePath: "QWEN.md"
|
|
7502
7771
|
},
|
|
7503
7772
|
nonRoot: {
|
|
7504
|
-
relativeDirPath:
|
|
7773
|
+
relativeDirPath: join78(".qwen", "memories")
|
|
7505
7774
|
}
|
|
7506
7775
|
};
|
|
7507
7776
|
}
|
|
@@ -7511,8 +7780,8 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
|
7511
7780
|
validate = true
|
|
7512
7781
|
}) {
|
|
7513
7782
|
const isRoot = relativeFilePath === "QWEN.md";
|
|
7514
|
-
const relativePath = isRoot ? "QWEN.md" :
|
|
7515
|
-
const fileContent = await readFileContent(
|
|
7783
|
+
const relativePath = isRoot ? "QWEN.md" : join78(".qwen", "memories", relativeFilePath);
|
|
7784
|
+
const fileContent = await readFileContent(join78(baseDir, relativePath));
|
|
7516
7785
|
return new _QwencodeRule({
|
|
7517
7786
|
baseDir,
|
|
7518
7787
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -7549,12 +7818,12 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
|
7549
7818
|
};
|
|
7550
7819
|
|
|
7551
7820
|
// src/features/rules/roo-rule.ts
|
|
7552
|
-
import { join as
|
|
7821
|
+
import { join as join79 } from "path";
|
|
7553
7822
|
var RooRule = class _RooRule extends ToolRule {
|
|
7554
7823
|
static getSettablePaths() {
|
|
7555
7824
|
return {
|
|
7556
7825
|
nonRoot: {
|
|
7557
|
-
relativeDirPath:
|
|
7826
|
+
relativeDirPath: join79(".roo", "rules")
|
|
7558
7827
|
}
|
|
7559
7828
|
};
|
|
7560
7829
|
}
|
|
@@ -7564,7 +7833,7 @@ var RooRule = class _RooRule extends ToolRule {
|
|
|
7564
7833
|
validate = true
|
|
7565
7834
|
}) {
|
|
7566
7835
|
const fileContent = await readFileContent(
|
|
7567
|
-
|
|
7836
|
+
join79(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
7568
7837
|
);
|
|
7569
7838
|
return new _RooRule({
|
|
7570
7839
|
baseDir,
|
|
@@ -7619,7 +7888,7 @@ var RooRule = class _RooRule extends ToolRule {
|
|
|
7619
7888
|
};
|
|
7620
7889
|
|
|
7621
7890
|
// src/features/rules/warp-rule.ts
|
|
7622
|
-
import { join as
|
|
7891
|
+
import { join as join80 } from "path";
|
|
7623
7892
|
var WarpRule = class _WarpRule extends ToolRule {
|
|
7624
7893
|
constructor({ fileContent, root, ...rest }) {
|
|
7625
7894
|
super({
|
|
@@ -7635,7 +7904,7 @@ var WarpRule = class _WarpRule extends ToolRule {
|
|
|
7635
7904
|
relativeFilePath: "WARP.md"
|
|
7636
7905
|
},
|
|
7637
7906
|
nonRoot: {
|
|
7638
|
-
relativeDirPath:
|
|
7907
|
+
relativeDirPath: join80(".warp", "memories")
|
|
7639
7908
|
}
|
|
7640
7909
|
};
|
|
7641
7910
|
}
|
|
@@ -7645,8 +7914,8 @@ var WarpRule = class _WarpRule extends ToolRule {
|
|
|
7645
7914
|
validate = true
|
|
7646
7915
|
}) {
|
|
7647
7916
|
const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
|
|
7648
|
-
const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath :
|
|
7649
|
-
const fileContent = await readFileContent(
|
|
7917
|
+
const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join80(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
|
|
7918
|
+
const fileContent = await readFileContent(join80(baseDir, relativePath));
|
|
7650
7919
|
return new _WarpRule({
|
|
7651
7920
|
baseDir,
|
|
7652
7921
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : ".warp",
|
|
@@ -7686,12 +7955,12 @@ var WarpRule = class _WarpRule extends ToolRule {
|
|
|
7686
7955
|
};
|
|
7687
7956
|
|
|
7688
7957
|
// src/features/rules/windsurf-rule.ts
|
|
7689
|
-
import { join as
|
|
7958
|
+
import { join as join81 } from "path";
|
|
7690
7959
|
var WindsurfRule = class _WindsurfRule extends ToolRule {
|
|
7691
7960
|
static getSettablePaths() {
|
|
7692
7961
|
return {
|
|
7693
7962
|
nonRoot: {
|
|
7694
|
-
relativeDirPath:
|
|
7963
|
+
relativeDirPath: join81(".windsurf", "rules")
|
|
7695
7964
|
}
|
|
7696
7965
|
};
|
|
7697
7966
|
}
|
|
@@ -7701,7 +7970,7 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
|
|
|
7701
7970
|
validate = true
|
|
7702
7971
|
}) {
|
|
7703
7972
|
const fileContent = await readFileContent(
|
|
7704
|
-
|
|
7973
|
+
join81(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
7705
7974
|
);
|
|
7706
7975
|
return new _WindsurfRule({
|
|
7707
7976
|
baseDir,
|
|
@@ -7747,6 +8016,7 @@ var rulesProcessorToolTargets = [
|
|
|
7747
8016
|
"augmentcode",
|
|
7748
8017
|
"augmentcode-legacy",
|
|
7749
8018
|
"claudecode",
|
|
8019
|
+
"claudecode-legacy",
|
|
7750
8020
|
"cline",
|
|
7751
8021
|
"codexcli",
|
|
7752
8022
|
"copilot",
|
|
@@ -7760,32 +8030,197 @@ var rulesProcessorToolTargets = [
|
|
|
7760
8030
|
"warp",
|
|
7761
8031
|
"windsurf"
|
|
7762
8032
|
];
|
|
7763
|
-
var RulesProcessorToolTargetSchema =
|
|
7764
|
-
var rulesProcessorToolTargetsGlobal = [
|
|
7765
|
-
"claudecode",
|
|
7766
|
-
"codexcli",
|
|
7767
|
-
"geminicli"
|
|
7768
|
-
];
|
|
8033
|
+
var RulesProcessorToolTargetSchema = z33.enum(rulesProcessorToolTargets);
|
|
7769
8034
|
var toolRuleFactories = /* @__PURE__ */ new Map([
|
|
7770
|
-
[
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
7778
|
-
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
7783
|
-
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
[
|
|
7787
|
-
|
|
8035
|
+
[
|
|
8036
|
+
"agentsmd",
|
|
8037
|
+
{
|
|
8038
|
+
class: AgentsMdRule,
|
|
8039
|
+
meta: {
|
|
8040
|
+
extension: "md",
|
|
8041
|
+
supportsGlobal: false,
|
|
8042
|
+
ruleDiscoveryMode: "toon",
|
|
8043
|
+
additionalConventions: {
|
|
8044
|
+
commands: { commandClass: AgentsmdCommand },
|
|
8045
|
+
subagents: { subagentClass: AgentsmdSubagent },
|
|
8046
|
+
skills: { skillClass: AgentsmdSkill }
|
|
8047
|
+
}
|
|
8048
|
+
}
|
|
8049
|
+
}
|
|
8050
|
+
],
|
|
8051
|
+
[
|
|
8052
|
+
"amazonqcli",
|
|
8053
|
+
{
|
|
8054
|
+
class: AmazonQCliRule,
|
|
8055
|
+
meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
|
|
8056
|
+
}
|
|
8057
|
+
],
|
|
8058
|
+
[
|
|
8059
|
+
"antigravity",
|
|
8060
|
+
{
|
|
8061
|
+
class: AntigravityRule,
|
|
8062
|
+
meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
|
|
8063
|
+
}
|
|
8064
|
+
],
|
|
8065
|
+
[
|
|
8066
|
+
"augmentcode",
|
|
8067
|
+
{
|
|
8068
|
+
class: AugmentcodeRule,
|
|
8069
|
+
meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
|
|
8070
|
+
}
|
|
8071
|
+
],
|
|
8072
|
+
[
|
|
8073
|
+
"augmentcode-legacy",
|
|
8074
|
+
{
|
|
8075
|
+
class: AugmentcodeLegacyRule,
|
|
8076
|
+
meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
|
|
8077
|
+
}
|
|
8078
|
+
],
|
|
8079
|
+
[
|
|
8080
|
+
"claudecode",
|
|
8081
|
+
{
|
|
8082
|
+
class: ClaudecodeRule,
|
|
8083
|
+
meta: { extension: "md", supportsGlobal: true, ruleDiscoveryMode: "auto" }
|
|
8084
|
+
}
|
|
8085
|
+
],
|
|
8086
|
+
[
|
|
8087
|
+
"claudecode-legacy",
|
|
8088
|
+
{
|
|
8089
|
+
class: ClaudecodeLegacyRule,
|
|
8090
|
+
meta: { extension: "md", supportsGlobal: true, ruleDiscoveryMode: "claudecode-legacy" }
|
|
8091
|
+
}
|
|
8092
|
+
],
|
|
8093
|
+
[
|
|
8094
|
+
"cline",
|
|
8095
|
+
{
|
|
8096
|
+
class: ClineRule,
|
|
8097
|
+
meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
|
|
8098
|
+
}
|
|
8099
|
+
],
|
|
8100
|
+
[
|
|
8101
|
+
"codexcli",
|
|
8102
|
+
{
|
|
8103
|
+
class: CodexcliRule,
|
|
8104
|
+
meta: {
|
|
8105
|
+
extension: "md",
|
|
8106
|
+
supportsGlobal: true,
|
|
8107
|
+
ruleDiscoveryMode: "toon",
|
|
8108
|
+
additionalConventions: {
|
|
8109
|
+
subagents: { subagentClass: CodexCliSubagent },
|
|
8110
|
+
skills: { skillClass: CodexCliSkill, globalOnly: true }
|
|
8111
|
+
}
|
|
8112
|
+
}
|
|
8113
|
+
}
|
|
8114
|
+
],
|
|
8115
|
+
[
|
|
8116
|
+
"copilot",
|
|
8117
|
+
{
|
|
8118
|
+
class: CopilotRule,
|
|
8119
|
+
meta: {
|
|
8120
|
+
extension: "md",
|
|
8121
|
+
supportsGlobal: false,
|
|
8122
|
+
ruleDiscoveryMode: "auto",
|
|
8123
|
+
additionalConventions: {
|
|
8124
|
+
commands: { commandClass: CopilotCommand },
|
|
8125
|
+
subagents: { subagentClass: CopilotSubagent },
|
|
8126
|
+
skills: { skillClass: CopilotSkill }
|
|
8127
|
+
}
|
|
8128
|
+
}
|
|
8129
|
+
}
|
|
8130
|
+
],
|
|
8131
|
+
[
|
|
8132
|
+
"cursor",
|
|
8133
|
+
{
|
|
8134
|
+
class: CursorRule,
|
|
8135
|
+
meta: {
|
|
8136
|
+
extension: "mdc",
|
|
8137
|
+
supportsGlobal: false,
|
|
8138
|
+
ruleDiscoveryMode: "auto",
|
|
8139
|
+
additionalConventions: {
|
|
8140
|
+
commands: { commandClass: CursorCommand },
|
|
8141
|
+
subagents: { subagentClass: CursorSubagent },
|
|
8142
|
+
skills: { skillClass: CursorSkill }
|
|
8143
|
+
},
|
|
8144
|
+
createsSeparateConventionsRule: true
|
|
8145
|
+
}
|
|
8146
|
+
}
|
|
8147
|
+
],
|
|
8148
|
+
[
|
|
8149
|
+
"geminicli",
|
|
8150
|
+
{
|
|
8151
|
+
class: GeminiCliRule,
|
|
8152
|
+
meta: {
|
|
8153
|
+
extension: "md",
|
|
8154
|
+
supportsGlobal: true,
|
|
8155
|
+
ruleDiscoveryMode: "toon",
|
|
8156
|
+
additionalConventions: {
|
|
8157
|
+
commands: { commandClass: GeminiCliCommand },
|
|
8158
|
+
subagents: { subagentClass: GeminiCliSubagent },
|
|
8159
|
+
skills: { skillClass: GeminiCliSkill }
|
|
8160
|
+
}
|
|
8161
|
+
}
|
|
8162
|
+
}
|
|
8163
|
+
],
|
|
8164
|
+
[
|
|
8165
|
+
"junie",
|
|
8166
|
+
{
|
|
8167
|
+
class: JunieRule,
|
|
8168
|
+
meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
|
|
8169
|
+
}
|
|
8170
|
+
],
|
|
8171
|
+
[
|
|
8172
|
+
"kiro",
|
|
8173
|
+
{
|
|
8174
|
+
class: KiroRule,
|
|
8175
|
+
meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
|
|
8176
|
+
}
|
|
8177
|
+
],
|
|
8178
|
+
[
|
|
8179
|
+
"opencode",
|
|
8180
|
+
{
|
|
8181
|
+
class: OpenCodeRule,
|
|
8182
|
+
meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
|
|
8183
|
+
}
|
|
8184
|
+
],
|
|
8185
|
+
[
|
|
8186
|
+
"qwencode",
|
|
8187
|
+
{
|
|
8188
|
+
class: QwencodeRule,
|
|
8189
|
+
meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
|
|
8190
|
+
}
|
|
8191
|
+
],
|
|
8192
|
+
[
|
|
8193
|
+
"roo",
|
|
8194
|
+
{
|
|
8195
|
+
class: RooRule,
|
|
8196
|
+
meta: {
|
|
8197
|
+
extension: "md",
|
|
8198
|
+
supportsGlobal: false,
|
|
8199
|
+
ruleDiscoveryMode: "auto",
|
|
8200
|
+
additionalConventions: {
|
|
8201
|
+
commands: { commandClass: RooCommand },
|
|
8202
|
+
subagents: { subagentClass: RooSubagent }
|
|
8203
|
+
},
|
|
8204
|
+
createsSeparateConventionsRule: true
|
|
8205
|
+
}
|
|
8206
|
+
}
|
|
8207
|
+
],
|
|
8208
|
+
[
|
|
8209
|
+
"warp",
|
|
8210
|
+
{
|
|
8211
|
+
class: WarpRule,
|
|
8212
|
+
meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
|
|
8213
|
+
}
|
|
8214
|
+
],
|
|
8215
|
+
[
|
|
8216
|
+
"windsurf",
|
|
8217
|
+
{
|
|
8218
|
+
class: WindsurfRule,
|
|
8219
|
+
meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
|
|
8220
|
+
}
|
|
8221
|
+
]
|
|
7788
8222
|
]);
|
|
8223
|
+
var rulesProcessorToolTargetsGlobal = Array.from(toolRuleFactories.entries()).filter(([_, factory]) => factory.meta.supportsGlobal).map(([target]) => target);
|
|
7789
8224
|
var defaultGetFactory6 = (target) => {
|
|
7790
8225
|
const factory = toolRuleFactories.get(target);
|
|
7791
8226
|
if (!factory) {
|
|
@@ -7800,6 +8235,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
7800
8235
|
simulateSkills;
|
|
7801
8236
|
global;
|
|
7802
8237
|
getFactory;
|
|
8238
|
+
skills;
|
|
7803
8239
|
constructor({
|
|
7804
8240
|
baseDir = process.cwd(),
|
|
7805
8241
|
toolTarget,
|
|
@@ -7807,7 +8243,8 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
7807
8243
|
simulateSubagents = false,
|
|
7808
8244
|
simulateSkills = false,
|
|
7809
8245
|
global = false,
|
|
7810
|
-
getFactory = defaultGetFactory6
|
|
8246
|
+
getFactory = defaultGetFactory6,
|
|
8247
|
+
skills
|
|
7811
8248
|
}) {
|
|
7812
8249
|
super({ baseDir });
|
|
7813
8250
|
const result = RulesProcessorToolTargetSchema.safeParse(toolTarget);
|
|
@@ -7822,12 +8259,14 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
7822
8259
|
this.simulateSubagents = simulateSubagents;
|
|
7823
8260
|
this.simulateSkills = simulateSkills;
|
|
7824
8261
|
this.getFactory = getFactory;
|
|
8262
|
+
this.skills = skills;
|
|
7825
8263
|
}
|
|
7826
8264
|
async convertRulesyncFilesToToolFiles(rulesyncFiles) {
|
|
7827
8265
|
const rulesyncRules = rulesyncFiles.filter(
|
|
7828
8266
|
(file) => file instanceof RulesyncRule
|
|
7829
8267
|
);
|
|
7830
8268
|
const factory = this.getFactory(this.toolTarget);
|
|
8269
|
+
const { meta } = factory;
|
|
7831
8270
|
const toolRules = rulesyncRules.map((rulesyncRule) => {
|
|
7832
8271
|
if (!factory.class.isTargetedByRulesyncRule(rulesyncRule)) {
|
|
7833
8272
|
return null;
|
|
@@ -7840,150 +8279,105 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
7840
8279
|
});
|
|
7841
8280
|
}).filter((rule) => rule !== null);
|
|
7842
8281
|
const isSimulated = this.simulateCommands || this.simulateSubagents || this.simulateSkills;
|
|
7843
|
-
if (isSimulated &&
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
relativeDirPath:
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
toolRules.push(
|
|
7867
|
-
new RooRule({
|
|
7868
|
-
baseDir: this.baseDir,
|
|
7869
|
-
relativeDirPath: RooRule.getSettablePaths().nonRoot.relativeDirPath,
|
|
7870
|
-
relativeFilePath: "additional-conventions.md",
|
|
7871
|
-
fileContent: this.generateAdditionalConventionsSection({
|
|
7872
|
-
commands: { relativeDirPath: RooCommand.getSettablePaths().relativeDirPath },
|
|
7873
|
-
subagents: {
|
|
7874
|
-
relativeDirPath: RooSubagent.getSettablePaths().relativeDirPath
|
|
7875
|
-
}
|
|
7876
|
-
}),
|
|
7877
|
-
validate: true
|
|
7878
|
-
})
|
|
7879
|
-
);
|
|
8282
|
+
if (isSimulated && meta.createsSeparateConventionsRule && meta.additionalConventions) {
|
|
8283
|
+
const conventionsContent = this.generateAdditionalConventionsSectionFromMeta(meta);
|
|
8284
|
+
const settablePaths = factory.class.getSettablePaths();
|
|
8285
|
+
const nonRootPath = "nonRoot" in settablePaths ? settablePaths.nonRoot : null;
|
|
8286
|
+
if (nonRootPath) {
|
|
8287
|
+
toolRules.push(
|
|
8288
|
+
factory.class.fromRulesyncRule({
|
|
8289
|
+
baseDir: this.baseDir,
|
|
8290
|
+
rulesyncRule: new RulesyncRule({
|
|
8291
|
+
baseDir: this.baseDir,
|
|
8292
|
+
relativeDirPath: nonRootPath.relativeDirPath,
|
|
8293
|
+
relativeFilePath: "additional-conventions.md",
|
|
8294
|
+
frontmatter: {
|
|
8295
|
+
root: false,
|
|
8296
|
+
targets: [this.toolTarget]
|
|
8297
|
+
},
|
|
8298
|
+
body: conventionsContent
|
|
8299
|
+
}),
|
|
8300
|
+
validate: true,
|
|
8301
|
+
global: this.global
|
|
8302
|
+
})
|
|
8303
|
+
);
|
|
8304
|
+
}
|
|
7880
8305
|
}
|
|
7881
8306
|
const rootRuleIndex = toolRules.findIndex((rule) => rule.isRoot());
|
|
7882
8307
|
if (rootRuleIndex === -1) {
|
|
7883
8308
|
return toolRules;
|
|
7884
8309
|
}
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
...this.global && {
|
|
7921
|
-
skills: {
|
|
7922
|
-
relativeDirPath: CodexCliSkill.getSettablePaths({ global: this.global }).relativeDirPath
|
|
7923
|
-
}
|
|
7924
|
-
}
|
|
7925
|
-
}) + rootRule.getFileContent()
|
|
7926
|
-
);
|
|
7927
|
-
return toolRules;
|
|
7928
|
-
}
|
|
7929
|
-
case "copilot": {
|
|
7930
|
-
const rootRule = toolRules[rootRuleIndex];
|
|
7931
|
-
rootRule?.setFileContent(
|
|
7932
|
-
this.generateAdditionalConventionsSection({
|
|
7933
|
-
commands: { relativeDirPath: CopilotCommand.getSettablePaths().relativeDirPath },
|
|
7934
|
-
subagents: {
|
|
7935
|
-
relativeDirPath: CopilotSubagent.getSettablePaths().relativeDirPath
|
|
7936
|
-
},
|
|
7937
|
-
skills: {
|
|
7938
|
-
relativeDirPath: CopilotSkill.getSettablePaths().relativeDirPath
|
|
7939
|
-
}
|
|
7940
|
-
}) + rootRule.getFileContent()
|
|
7941
|
-
);
|
|
7942
|
-
return toolRules;
|
|
7943
|
-
}
|
|
7944
|
-
case "geminicli": {
|
|
7945
|
-
const rootRule = toolRules[rootRuleIndex];
|
|
7946
|
-
rootRule?.setFileContent(
|
|
7947
|
-
this.generateToonReferencesSection(toolRules) + this.generateAdditionalConventionsSection({
|
|
7948
|
-
commands: { relativeDirPath: GeminiCliCommand.getSettablePaths().relativeDirPath },
|
|
7949
|
-
subagents: {
|
|
7950
|
-
relativeDirPath: GeminiCliSubagent.getSettablePaths().relativeDirPath
|
|
7951
|
-
}
|
|
7952
|
-
}) + rootRule.getFileContent()
|
|
7953
|
-
);
|
|
7954
|
-
return toolRules;
|
|
7955
|
-
}
|
|
7956
|
-
case "kiro": {
|
|
7957
|
-
const rootRule = toolRules[rootRuleIndex];
|
|
7958
|
-
rootRule?.setFileContent(
|
|
7959
|
-
this.generateToonReferencesSection(toolRules) + rootRule.getFileContent()
|
|
7960
|
-
);
|
|
7961
|
-
return toolRules;
|
|
7962
|
-
}
|
|
7963
|
-
case "opencode": {
|
|
7964
|
-
const rootRule = toolRules[rootRuleIndex];
|
|
7965
|
-
rootRule?.setFileContent(
|
|
7966
|
-
this.generateToonReferencesSection(toolRules) + rootRule.getFileContent()
|
|
7967
|
-
);
|
|
7968
|
-
return toolRules;
|
|
7969
|
-
}
|
|
7970
|
-
case "qwencode": {
|
|
7971
|
-
const rootRule = toolRules[rootRuleIndex];
|
|
7972
|
-
rootRule?.setFileContent(
|
|
7973
|
-
this.generateToonReferencesSection(toolRules) + rootRule.getFileContent()
|
|
7974
|
-
);
|
|
7975
|
-
return toolRules;
|
|
7976
|
-
}
|
|
7977
|
-
case "warp": {
|
|
7978
|
-
const rootRule = toolRules[rootRuleIndex];
|
|
7979
|
-
rootRule?.setFileContent(
|
|
7980
|
-
this.generateToonReferencesSection(toolRules) + rootRule.getFileContent()
|
|
7981
|
-
);
|
|
7982
|
-
return toolRules;
|
|
7983
|
-
}
|
|
8310
|
+
const rootRule = toolRules[rootRuleIndex];
|
|
8311
|
+
if (!rootRule) {
|
|
8312
|
+
return toolRules;
|
|
8313
|
+
}
|
|
8314
|
+
const referenceSection = this.generateReferenceSectionFromMeta(meta, toolRules);
|
|
8315
|
+
const conventionsSection = !meta.createsSeparateConventionsRule && meta.additionalConventions ? this.generateAdditionalConventionsSectionFromMeta(meta) : "";
|
|
8316
|
+
const newContent = referenceSection + conventionsSection + rootRule.getFileContent();
|
|
8317
|
+
rootRule.setFileContent(newContent);
|
|
8318
|
+
return toolRules;
|
|
8319
|
+
}
|
|
8320
|
+
buildSkillList(skillClass) {
|
|
8321
|
+
if (!this.skills) return [];
|
|
8322
|
+
const toolRelativeDirPath = skillClass.getSettablePaths({
|
|
8323
|
+
global: this.global
|
|
8324
|
+
}).relativeDirPath;
|
|
8325
|
+
return this.skills.filter((skill) => skillClass.isTargetedByRulesyncSkill(skill)).map((skill) => {
|
|
8326
|
+
const frontmatter = skill.getFrontmatter();
|
|
8327
|
+
const relativePath = join82(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME);
|
|
8328
|
+
return {
|
|
8329
|
+
name: frontmatter.name,
|
|
8330
|
+
description: frontmatter.description,
|
|
8331
|
+
path: relativePath
|
|
8332
|
+
};
|
|
8333
|
+
});
|
|
8334
|
+
}
|
|
8335
|
+
/**
|
|
8336
|
+
* Generate reference section based on meta configuration.
|
|
8337
|
+
*/
|
|
8338
|
+
generateReferenceSectionFromMeta(meta, toolRules) {
|
|
8339
|
+
switch (meta.ruleDiscoveryMode) {
|
|
8340
|
+
case "toon":
|
|
8341
|
+
return this.generateToonReferencesSection(toolRules);
|
|
8342
|
+
case "claudecode-legacy":
|
|
8343
|
+
return this.generateReferencesSection(toolRules);
|
|
8344
|
+
case "auto":
|
|
7984
8345
|
default:
|
|
7985
|
-
return
|
|
8346
|
+
return "";
|
|
8347
|
+
}
|
|
8348
|
+
}
|
|
8349
|
+
/**
|
|
8350
|
+
* Generate additional conventions section based on meta configuration.
|
|
8351
|
+
*/
|
|
8352
|
+
generateAdditionalConventionsSectionFromMeta(meta) {
|
|
8353
|
+
const { additionalConventions } = meta;
|
|
8354
|
+
if (!additionalConventions) {
|
|
8355
|
+
return "";
|
|
8356
|
+
}
|
|
8357
|
+
const conventions = {};
|
|
8358
|
+
if (additionalConventions.commands) {
|
|
8359
|
+
const { commandClass } = additionalConventions.commands;
|
|
8360
|
+
const relativeDirPath = commandClass.getSettablePaths({
|
|
8361
|
+
global: this.global
|
|
8362
|
+
}).relativeDirPath;
|
|
8363
|
+
conventions.commands = { relativeDirPath };
|
|
8364
|
+
}
|
|
8365
|
+
if (additionalConventions.subagents) {
|
|
8366
|
+
const { subagentClass } = additionalConventions.subagents;
|
|
8367
|
+
const relativeDirPath = subagentClass.getSettablePaths({
|
|
8368
|
+
global: this.global
|
|
8369
|
+
}).relativeDirPath;
|
|
8370
|
+
conventions.subagents = { relativeDirPath };
|
|
7986
8371
|
}
|
|
8372
|
+
if (additionalConventions.skills) {
|
|
8373
|
+
const { skillClass, globalOnly } = additionalConventions.skills;
|
|
8374
|
+
if (!globalOnly || this.global) {
|
|
8375
|
+
conventions.skills = {
|
|
8376
|
+
skillList: this.buildSkillList(skillClass)
|
|
8377
|
+
};
|
|
8378
|
+
}
|
|
8379
|
+
}
|
|
8380
|
+
return this.generateAdditionalConventionsSection(conventions);
|
|
7987
8381
|
}
|
|
7988
8382
|
async convertToolFilesToRulesyncFiles(toolFiles) {
|
|
7989
8383
|
const toolRules = toolFiles.filter((file) => file instanceof ToolRule);
|
|
@@ -7997,7 +8391,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
7997
8391
|
* Load and parse rulesync rule files from .rulesync/rules/ directory
|
|
7998
8392
|
*/
|
|
7999
8393
|
async loadRulesyncFiles() {
|
|
8000
|
-
const files = await findFilesByGlobs(
|
|
8394
|
+
const files = await findFilesByGlobs(join82(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md"));
|
|
8001
8395
|
logger.debug(`Found ${files.length} rulesync files`);
|
|
8002
8396
|
const rulesyncRules = await Promise.all(
|
|
8003
8397
|
files.map((file) => RulesyncRule.fromFile({ relativeFilePath: basename21(file) }))
|
|
@@ -8018,7 +8412,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
8018
8412
|
return rulesyncRules;
|
|
8019
8413
|
}
|
|
8020
8414
|
async loadRulesyncFilesLegacy() {
|
|
8021
|
-
const legacyFiles = await findFilesByGlobs(
|
|
8415
|
+
const legacyFiles = await findFilesByGlobs(join82(RULESYNC_RELATIVE_DIR_PATH, "*.md"));
|
|
8022
8416
|
logger.debug(`Found ${legacyFiles.length} legacy rulesync files`);
|
|
8023
8417
|
return Promise.all(
|
|
8024
8418
|
legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath: basename21(file) }))
|
|
@@ -8039,7 +8433,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
8039
8433
|
return [];
|
|
8040
8434
|
}
|
|
8041
8435
|
const rootFilePaths = await findFilesByGlobs(
|
|
8042
|
-
|
|
8436
|
+
join82(
|
|
8043
8437
|
this.baseDir,
|
|
8044
8438
|
settablePaths.root.relativeDirPath ?? ".",
|
|
8045
8439
|
settablePaths.root.relativeFilePath
|
|
@@ -8061,7 +8455,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
8061
8455
|
return [];
|
|
8062
8456
|
}
|
|
8063
8457
|
const nonRootFilePaths = await findFilesByGlobs(
|
|
8064
|
-
|
|
8458
|
+
join82(this.baseDir, settablePaths.nonRoot.relativeDirPath, `*.${factory.meta.extension}`)
|
|
8065
8459
|
);
|
|
8066
8460
|
return await Promise.all(
|
|
8067
8461
|
nonRootFilePaths.map(
|
|
@@ -8160,23 +8554,15 @@ s/<command> [arguments]
|
|
|
8160
8554
|
This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
|
|
8161
8555
|
The \`s\` in \`s/\` stands for *simulate*. Because custom slash commands are not built-in, this syntax provides a pseudo way to invoke them.
|
|
8162
8556
|
|
|
8163
|
-
When users call a custom slash command, you have to look for the markdown file, \`${
|
|
8557
|
+
When users call a custom slash command, you have to look for the markdown file, \`${join82(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
|
|
8164
8558
|
const subagentsSection = subagents ? `## Simulated Subagents
|
|
8165
8559
|
|
|
8166
8560
|
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.
|
|
8167
8561
|
|
|
8168
|
-
When users call a simulated subagent, it will look for the corresponding markdown file, \`${
|
|
8169
|
-
|
|
8170
|
-
For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join81(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
|
|
8171
|
-
const skillsSection = skills ? `## Simulated Skills
|
|
8562
|
+
When users call a simulated subagent, it will look for the corresponding markdown file, \`${join82(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "{subagent}.md")}\`, and execute its contents as the block of operations.
|
|
8172
8563
|
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
When users invoke a simulated skill, look for the corresponding SKILL.md file in \`${join81(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "{skill}/SKILL.md")}\` and execute its contents as the block of operations.
|
|
8176
|
-
|
|
8177
|
-
For example, if the user instructs \`Use the skill example-skill to achieve something\`, look for \`${join81(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "example-skill/SKILL.md")}\` and execute its contents.
|
|
8178
|
-
|
|
8179
|
-
Additionally, you should proactively consider using available skills when they would help accomplish a task more effectively, even if the user doesn't explicitly request them.` : "";
|
|
8564
|
+
For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join82(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
|
|
8565
|
+
const skillsSection = skills ? this.generateSkillsSection(skills) : "";
|
|
8180
8566
|
const result = [
|
|
8181
8567
|
overview,
|
|
8182
8568
|
...this.simulateCommands && CommandsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [commandsSection] : [],
|
|
@@ -8185,6 +8571,21 @@ Additionally, you should proactively consider using available skills when they w
|
|
|
8185
8571
|
].join("\n\n") + "\n\n";
|
|
8186
8572
|
return result;
|
|
8187
8573
|
}
|
|
8574
|
+
generateSkillsSection(skills) {
|
|
8575
|
+
if (!skills.skillList || skills.skillList.length === 0) {
|
|
8576
|
+
return "";
|
|
8577
|
+
}
|
|
8578
|
+
const skillListWithAtPrefix = skills.skillList.map((skill) => ({
|
|
8579
|
+
...skill,
|
|
8580
|
+
path: `@${skill.path}`
|
|
8581
|
+
}));
|
|
8582
|
+
const toonContent = encode({ skillList: skillListWithAtPrefix });
|
|
8583
|
+
return `## Simulated Skills
|
|
8584
|
+
|
|
8585
|
+
Simulated skills are specialized capabilities that can be invoked to handle specific types of tasks. When you determine that a skill would be helpful for the current task, read the corresponding SKILL.md file and execute its instructions.
|
|
8586
|
+
|
|
8587
|
+
${toonContent}`;
|
|
8588
|
+
}
|
|
8188
8589
|
};
|
|
8189
8590
|
|
|
8190
8591
|
// src/cli/commands/generate.ts
|
|
@@ -8197,13 +8598,15 @@ async function generateCommand(options) {
|
|
|
8197
8598
|
process.exit(1);
|
|
8198
8599
|
}
|
|
8199
8600
|
logger.info(`Base directories: ${config.getBaseDirs().join(", ")}`);
|
|
8200
|
-
const totalRulesOutputs = await generateRules(config);
|
|
8201
8601
|
const totalIgnoreOutputs = await generateIgnore(config);
|
|
8202
8602
|
const totalMcpOutputs = await generateMcp(config);
|
|
8203
8603
|
const totalCommandOutputs = await generateCommands(config);
|
|
8204
8604
|
const totalSubagentOutputs = await generateSubagents(config);
|
|
8205
|
-
const
|
|
8206
|
-
const
|
|
8605
|
+
const skillsResult = await generateSkills(config);
|
|
8606
|
+
const totalRulesOutputs = await generateRules(config, {
|
|
8607
|
+
skills: skillsResult.skills
|
|
8608
|
+
});
|
|
8609
|
+
const totalGenerated = totalRulesOutputs + totalMcpOutputs + totalCommandOutputs + totalIgnoreOutputs + totalSubagentOutputs + skillsResult.totalOutputs;
|
|
8207
8610
|
if (totalGenerated === 0) {
|
|
8208
8611
|
const enabledFeatures = config.getFeatures().join(", ");
|
|
8209
8612
|
logger.warn(`\u26A0\uFE0F No files generated for enabled features: ${enabledFeatures}`);
|
|
@@ -8216,11 +8619,11 @@ async function generateCommand(options) {
|
|
|
8216
8619
|
if (totalMcpOutputs > 0) parts.push(`${totalMcpOutputs} MCP files`);
|
|
8217
8620
|
if (totalCommandOutputs > 0) parts.push(`${totalCommandOutputs} commands`);
|
|
8218
8621
|
if (totalSubagentOutputs > 0) parts.push(`${totalSubagentOutputs} subagents`);
|
|
8219
|
-
if (
|
|
8622
|
+
if (skillsResult.totalOutputs > 0) parts.push(`${skillsResult.totalOutputs} skills`);
|
|
8220
8623
|
logger.success(`\u{1F389} All done! Generated ${totalGenerated} file(s) total (${parts.join(" + ")})`);
|
|
8221
8624
|
}
|
|
8222
8625
|
}
|
|
8223
|
-
async function generateRules(config) {
|
|
8626
|
+
async function generateRules(config, options) {
|
|
8224
8627
|
if (!config.getFeatures().includes("rules")) {
|
|
8225
8628
|
logger.debug("Skipping rule generation (not in --features)");
|
|
8226
8629
|
return 0;
|
|
@@ -8239,7 +8642,8 @@ async function generateRules(config) {
|
|
|
8239
8642
|
global: config.getGlobal(),
|
|
8240
8643
|
simulateCommands: config.getSimulateCommands(),
|
|
8241
8644
|
simulateSubagents: config.getSimulateSubagents(),
|
|
8242
|
-
simulateSkills: config.getSimulateSkills()
|
|
8645
|
+
simulateSkills: config.getSimulateSkills(),
|
|
8646
|
+
skills: options?.skills
|
|
8243
8647
|
});
|
|
8244
8648
|
if (config.getDelete()) {
|
|
8245
8649
|
const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
|
|
@@ -8403,9 +8807,10 @@ async function generateSubagents(config) {
|
|
|
8403
8807
|
async function generateSkills(config) {
|
|
8404
8808
|
if (!config.getFeatures().includes("skills")) {
|
|
8405
8809
|
logger.debug("Skipping skill generation (not in --features)");
|
|
8406
|
-
return 0;
|
|
8810
|
+
return { totalOutputs: 0, skills: [] };
|
|
8407
8811
|
}
|
|
8408
8812
|
let totalSkillOutputs = 0;
|
|
8813
|
+
const allSkills = [];
|
|
8409
8814
|
logger.info("Generating skill files...");
|
|
8410
8815
|
const toolTargets = intersection(
|
|
8411
8816
|
config.getTargets(),
|
|
@@ -8426,112 +8831,164 @@ async function generateSkills(config) {
|
|
|
8426
8831
|
await processor.removeAiDirs(oldToolDirs);
|
|
8427
8832
|
}
|
|
8428
8833
|
const rulesyncDirs = await processor.loadRulesyncDirs();
|
|
8834
|
+
for (const rulesyncDir of rulesyncDirs) {
|
|
8835
|
+
if (rulesyncDir instanceof RulesyncSkill) {
|
|
8836
|
+
allSkills.push(rulesyncDir);
|
|
8837
|
+
}
|
|
8838
|
+
}
|
|
8429
8839
|
const toolDirs = await processor.convertRulesyncDirsToToolDirs(rulesyncDirs);
|
|
8430
8840
|
const writtenCount = await processor.writeAiDirs(toolDirs);
|
|
8431
8841
|
totalSkillOutputs += writtenCount;
|
|
8432
8842
|
logger.success(`Generated ${writtenCount} ${toolTarget} skill(s) in ${baseDir}`);
|
|
8433
8843
|
}
|
|
8434
8844
|
}
|
|
8435
|
-
return totalSkillOutputs;
|
|
8845
|
+
return { totalOutputs: totalSkillOutputs, skills: allSkills };
|
|
8436
8846
|
}
|
|
8437
8847
|
|
|
8438
8848
|
// src/cli/commands/gitignore.ts
|
|
8439
|
-
import { join as
|
|
8849
|
+
import { join as join83 } from "path";
|
|
8850
|
+
var RULESYNC_HEADER = "# Generated by Rulesync";
|
|
8851
|
+
var LEGACY_RULESYNC_HEADER = "# Generated by rulesync - AI tool configuration files";
|
|
8852
|
+
var RULESYNC_IGNORE_ENTRIES = [
|
|
8853
|
+
// AGENTS.md
|
|
8854
|
+
"**/AGENTS.md",
|
|
8855
|
+
"**/.agents/",
|
|
8856
|
+
// Amazon Q
|
|
8857
|
+
"**/.amazonq/",
|
|
8858
|
+
// Augment
|
|
8859
|
+
"**/.augmentignore",
|
|
8860
|
+
"**/.augment/rules/",
|
|
8861
|
+
"**/.augment-guidelines",
|
|
8862
|
+
// Claude Code
|
|
8863
|
+
"**/CLAUDE.md",
|
|
8864
|
+
"**/.claude/CLAUDE.md",
|
|
8865
|
+
"**/.claude/memories/",
|
|
8866
|
+
"**/.claude/rules/",
|
|
8867
|
+
"**/.claude/commands/",
|
|
8868
|
+
"**/.claude/agents/",
|
|
8869
|
+
"**/.claude/skills/",
|
|
8870
|
+
"**/.claude/settings.local.json",
|
|
8871
|
+
"**/.mcp.json",
|
|
8872
|
+
// Cline
|
|
8873
|
+
"**/.clinerules/",
|
|
8874
|
+
"**/.clineignore",
|
|
8875
|
+
"**/.cline/mcp.json",
|
|
8876
|
+
// Codex
|
|
8877
|
+
"**/.codexignore",
|
|
8878
|
+
"**/.codex/",
|
|
8879
|
+
"**/.codex/skills/",
|
|
8880
|
+
// Cursor
|
|
8881
|
+
"**/.cursor/",
|
|
8882
|
+
"**/.cursorignore",
|
|
8883
|
+
// Gemini
|
|
8884
|
+
"**/GEMINI.md",
|
|
8885
|
+
"**/.gemini/memories/",
|
|
8886
|
+
"**/.gemini/commands/",
|
|
8887
|
+
"**/.gemini/subagents/",
|
|
8888
|
+
"**/.gemini/skills/",
|
|
8889
|
+
"**/.geminiignore",
|
|
8890
|
+
// GitHub Copilot
|
|
8891
|
+
"**/.github/copilot-instructions.md",
|
|
8892
|
+
"**/.github/instructions/",
|
|
8893
|
+
"**/.github/prompts/",
|
|
8894
|
+
"**/.github/subagents/",
|
|
8895
|
+
"**/.github/skills/",
|
|
8896
|
+
"**/.vscode/mcp.json",
|
|
8897
|
+
// Junie
|
|
8898
|
+
"**/.junie/guidelines.md",
|
|
8899
|
+
"**/.junie/mcp.json",
|
|
8900
|
+
// Kiro
|
|
8901
|
+
"**/.kiro/steering/",
|
|
8902
|
+
"**/.aiignore",
|
|
8903
|
+
// OpenCode
|
|
8904
|
+
"**/.opencode/memories/",
|
|
8905
|
+
"**/.opencode/command/",
|
|
8906
|
+
"**/opencode.json",
|
|
8907
|
+
// Qwen
|
|
8908
|
+
"**/QWEN.md",
|
|
8909
|
+
"**/.qwen/memories/",
|
|
8910
|
+
// Roo
|
|
8911
|
+
"**/.roo/rules/",
|
|
8912
|
+
"**/.rooignore",
|
|
8913
|
+
"**/.roo/mcp.json",
|
|
8914
|
+
"**/.roo/subagents/",
|
|
8915
|
+
// Warp
|
|
8916
|
+
"**/.warp/",
|
|
8917
|
+
"**/WARP.md",
|
|
8918
|
+
// Others
|
|
8919
|
+
"**/modular-mcp.json",
|
|
8920
|
+
"!.rulesync/.aiignore"
|
|
8921
|
+
];
|
|
8922
|
+
var isRulesyncHeader = (line) => {
|
|
8923
|
+
const trimmed = line.trim();
|
|
8924
|
+
return trimmed === RULESYNC_HEADER || trimmed === LEGACY_RULESYNC_HEADER;
|
|
8925
|
+
};
|
|
8926
|
+
var isRulesyncEntry = (line) => {
|
|
8927
|
+
const trimmed = line.trim();
|
|
8928
|
+
if (trimmed === "" || isRulesyncHeader(line)) {
|
|
8929
|
+
return false;
|
|
8930
|
+
}
|
|
8931
|
+
return RULESYNC_IGNORE_ENTRIES.includes(trimmed);
|
|
8932
|
+
};
|
|
8933
|
+
var removeExistingRulesyncEntries = (content) => {
|
|
8934
|
+
const lines = content.split("\n");
|
|
8935
|
+
const filteredLines = [];
|
|
8936
|
+
let inRulesyncBlock = false;
|
|
8937
|
+
let consecutiveEmptyLines = 0;
|
|
8938
|
+
for (const line of lines) {
|
|
8939
|
+
const trimmed = line.trim();
|
|
8940
|
+
if (isRulesyncHeader(line)) {
|
|
8941
|
+
inRulesyncBlock = true;
|
|
8942
|
+
continue;
|
|
8943
|
+
}
|
|
8944
|
+
if (inRulesyncBlock) {
|
|
8945
|
+
if (trimmed === "") {
|
|
8946
|
+
consecutiveEmptyLines++;
|
|
8947
|
+
if (consecutiveEmptyLines >= 2) {
|
|
8948
|
+
inRulesyncBlock = false;
|
|
8949
|
+
consecutiveEmptyLines = 0;
|
|
8950
|
+
}
|
|
8951
|
+
continue;
|
|
8952
|
+
}
|
|
8953
|
+
if (isRulesyncEntry(line)) {
|
|
8954
|
+
consecutiveEmptyLines = 0;
|
|
8955
|
+
continue;
|
|
8956
|
+
}
|
|
8957
|
+
inRulesyncBlock = false;
|
|
8958
|
+
consecutiveEmptyLines = 0;
|
|
8959
|
+
}
|
|
8960
|
+
if (isRulesyncEntry(line)) {
|
|
8961
|
+
continue;
|
|
8962
|
+
}
|
|
8963
|
+
filteredLines.push(line);
|
|
8964
|
+
}
|
|
8965
|
+
let result = filteredLines.join("\n");
|
|
8966
|
+
while (result.endsWith("\n\n")) {
|
|
8967
|
+
result = result.slice(0, -1);
|
|
8968
|
+
}
|
|
8969
|
+
return result;
|
|
8970
|
+
};
|
|
8440
8971
|
var gitignoreCommand = async () => {
|
|
8441
|
-
const gitignorePath =
|
|
8442
|
-
const rulesFilesToIgnore = [
|
|
8443
|
-
"# Generated by rulesync - AI tool configuration files",
|
|
8444
|
-
// AGENTS.md
|
|
8445
|
-
"**/AGENTS.md",
|
|
8446
|
-
"**/.agents/",
|
|
8447
|
-
// Amazon Q
|
|
8448
|
-
"**/.amazonq/",
|
|
8449
|
-
// Augment
|
|
8450
|
-
"**/.augmentignore",
|
|
8451
|
-
"**/.augment/rules/",
|
|
8452
|
-
"**/.augment-guidelines",
|
|
8453
|
-
// Claude Code
|
|
8454
|
-
"**/CLAUDE.md",
|
|
8455
|
-
"**/.claude/memories/",
|
|
8456
|
-
"**/.claude/commands/",
|
|
8457
|
-
"**/.claude/agents/",
|
|
8458
|
-
"**/.claude/skills/",
|
|
8459
|
-
"**/.claude/settings.local.json",
|
|
8460
|
-
"**/.mcp.json",
|
|
8461
|
-
// Cline
|
|
8462
|
-
"**/.clinerules/",
|
|
8463
|
-
"**/.clineignore",
|
|
8464
|
-
"**/.cline/mcp.json",
|
|
8465
|
-
// Codex
|
|
8466
|
-
"**/.codexignore",
|
|
8467
|
-
"**/.codex/",
|
|
8468
|
-
"**/.codex/skills/",
|
|
8469
|
-
// Cursor
|
|
8470
|
-
"**/.cursor/",
|
|
8471
|
-
"**/.cursorignore",
|
|
8472
|
-
// Gemini
|
|
8473
|
-
"**/GEMINI.md",
|
|
8474
|
-
"**/.gemini/memories/",
|
|
8475
|
-
"**/.gemini/commands/",
|
|
8476
|
-
"**/.gemini/subagents/",
|
|
8477
|
-
"**/.gemini/skills/",
|
|
8478
|
-
// GitHub Copilot
|
|
8479
|
-
"**/.github/copilot-instructions.md",
|
|
8480
|
-
"**/.github/instructions/",
|
|
8481
|
-
"**/.github/prompts/",
|
|
8482
|
-
"**/.github/subagents/",
|
|
8483
|
-
"**/.github/skills/",
|
|
8484
|
-
"**/.vscode/mcp.json",
|
|
8485
|
-
// Junie
|
|
8486
|
-
"**/.junie/guidelines.md",
|
|
8487
|
-
"**/.junie/mcp.json",
|
|
8488
|
-
// Kiro
|
|
8489
|
-
"**/.kiro/steering/",
|
|
8490
|
-
"**/.aiignore",
|
|
8491
|
-
// OpenCode
|
|
8492
|
-
"**/.opencode/memories/",
|
|
8493
|
-
"**/.opencode/command/",
|
|
8494
|
-
"**/opencode.json",
|
|
8495
|
-
// Qwen
|
|
8496
|
-
"**/QWEN.md",
|
|
8497
|
-
"**/.qwen/memories/",
|
|
8498
|
-
// Roo
|
|
8499
|
-
"**/.roo/rules/",
|
|
8500
|
-
"**/.rooignore",
|
|
8501
|
-
"**/.roo/mcp.json",
|
|
8502
|
-
"**/.roo/subagents/",
|
|
8503
|
-
// Warp
|
|
8504
|
-
"**/.warp/",
|
|
8505
|
-
"**/WARP.md",
|
|
8506
|
-
// Others
|
|
8507
|
-
"**/modular-mcp.json",
|
|
8508
|
-
"!.rulesync/.aiignore"
|
|
8509
|
-
];
|
|
8972
|
+
const gitignorePath = join83(process.cwd(), ".gitignore");
|
|
8510
8973
|
let gitignoreContent = "";
|
|
8511
8974
|
if (await fileExists(gitignorePath)) {
|
|
8512
8975
|
gitignoreContent = await readFileContent(gitignorePath);
|
|
8513
8976
|
}
|
|
8514
|
-
const
|
|
8515
|
-
|
|
8516
|
-
|
|
8517
|
-
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8977
|
+
const cleanedContent = removeExistingRulesyncEntries(gitignoreContent);
|
|
8978
|
+
const rulesyncBlock = [RULESYNC_HEADER, ...RULESYNC_IGNORE_ENTRIES].join("\n");
|
|
8979
|
+
const newContent = cleanedContent.trim() ? `${cleanedContent.trimEnd()}
|
|
8980
|
+
|
|
8981
|
+
${rulesyncBlock}
|
|
8982
|
+
` : `${rulesyncBlock}
|
|
8983
|
+
`;
|
|
8984
|
+
if (gitignoreContent === newContent) {
|
|
8521
8985
|
logger.success(".gitignore is already up to date");
|
|
8522
8986
|
return;
|
|
8523
8987
|
}
|
|
8524
|
-
const newContent = gitignoreContent ? `${gitignoreContent.trimEnd()}
|
|
8525
|
-
|
|
8526
|
-
${linesToAdd.join("\n")}
|
|
8527
|
-
` : `${linesToAdd.join("\n")}
|
|
8528
|
-
`;
|
|
8529
8988
|
await writeFileContent(gitignorePath, newContent);
|
|
8530
|
-
logger.success(
|
|
8531
|
-
for (const
|
|
8532
|
-
|
|
8533
|
-
logger.info(` ${line}`);
|
|
8534
|
-
}
|
|
8989
|
+
logger.success("Updated .gitignore with rulesync entries:");
|
|
8990
|
+
for (const entry of RULESYNC_IGNORE_ENTRIES) {
|
|
8991
|
+
logger.info(` ${entry}`);
|
|
8535
8992
|
}
|
|
8536
8993
|
};
|
|
8537
8994
|
|
|
@@ -8711,7 +9168,7 @@ async function importSkills(config, tool) {
|
|
|
8711
9168
|
}
|
|
8712
9169
|
|
|
8713
9170
|
// src/cli/commands/init.ts
|
|
8714
|
-
import { join as
|
|
9171
|
+
import { join as join84 } from "path";
|
|
8715
9172
|
async function initCommand() {
|
|
8716
9173
|
logger.info("Initializing rulesync...");
|
|
8717
9174
|
await ensureDir(RULESYNC_RELATIVE_DIR_PATH);
|
|
@@ -8874,14 +9331,14 @@ Attention, again, you are just the planner, so though you can read any files and
|
|
|
8874
9331
|
await ensureDir(commandPaths.relativeDirPath);
|
|
8875
9332
|
await ensureDir(subagentPaths.relativeDirPath);
|
|
8876
9333
|
await ensureDir(ignorePaths.recommended.relativeDirPath);
|
|
8877
|
-
const ruleFilepath =
|
|
9334
|
+
const ruleFilepath = join84(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
|
|
8878
9335
|
if (!await fileExists(ruleFilepath)) {
|
|
8879
9336
|
await writeFileContent(ruleFilepath, sampleRuleFile.content);
|
|
8880
9337
|
logger.success(`Created ${ruleFilepath}`);
|
|
8881
9338
|
} else {
|
|
8882
9339
|
logger.info(`Skipped ${ruleFilepath} (already exists)`);
|
|
8883
9340
|
}
|
|
8884
|
-
const mcpFilepath =
|
|
9341
|
+
const mcpFilepath = join84(
|
|
8885
9342
|
mcpPaths.recommended.relativeDirPath,
|
|
8886
9343
|
mcpPaths.recommended.relativeFilePath
|
|
8887
9344
|
);
|
|
@@ -8891,21 +9348,21 @@ Attention, again, you are just the planner, so though you can read any files and
|
|
|
8891
9348
|
} else {
|
|
8892
9349
|
logger.info(`Skipped ${mcpFilepath} (already exists)`);
|
|
8893
9350
|
}
|
|
8894
|
-
const commandFilepath =
|
|
9351
|
+
const commandFilepath = join84(commandPaths.relativeDirPath, sampleCommandFile.filename);
|
|
8895
9352
|
if (!await fileExists(commandFilepath)) {
|
|
8896
9353
|
await writeFileContent(commandFilepath, sampleCommandFile.content);
|
|
8897
9354
|
logger.success(`Created ${commandFilepath}`);
|
|
8898
9355
|
} else {
|
|
8899
9356
|
logger.info(`Skipped ${commandFilepath} (already exists)`);
|
|
8900
9357
|
}
|
|
8901
|
-
const subagentFilepath =
|
|
9358
|
+
const subagentFilepath = join84(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
|
|
8902
9359
|
if (!await fileExists(subagentFilepath)) {
|
|
8903
9360
|
await writeFileContent(subagentFilepath, sampleSubagentFile.content);
|
|
8904
9361
|
logger.success(`Created ${subagentFilepath}`);
|
|
8905
9362
|
} else {
|
|
8906
9363
|
logger.info(`Skipped ${subagentFilepath} (already exists)`);
|
|
8907
9364
|
}
|
|
8908
|
-
const ignoreFilepath =
|
|
9365
|
+
const ignoreFilepath = join84(
|
|
8909
9366
|
ignorePaths.recommended.relativeDirPath,
|
|
8910
9367
|
ignorePaths.recommended.relativeFilePath
|
|
8911
9368
|
);
|
|
@@ -8921,12 +9378,12 @@ Attention, again, you are just the planner, so though you can read any files and
|
|
|
8921
9378
|
import { FastMCP } from "fastmcp";
|
|
8922
9379
|
|
|
8923
9380
|
// src/mcp/commands.ts
|
|
8924
|
-
import { basename as basename22, join as
|
|
8925
|
-
import { z as
|
|
9381
|
+
import { basename as basename22, join as join85 } from "path";
|
|
9382
|
+
import { z as z34 } from "zod/mini";
|
|
8926
9383
|
var maxCommandSizeBytes = 1024 * 1024;
|
|
8927
9384
|
var maxCommandsCount = 1e3;
|
|
8928
9385
|
async function listCommands() {
|
|
8929
|
-
const commandsDir =
|
|
9386
|
+
const commandsDir = join85(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
|
|
8930
9387
|
try {
|
|
8931
9388
|
const files = await listDirectoryFiles(commandsDir);
|
|
8932
9389
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -8938,7 +9395,7 @@ async function listCommands() {
|
|
|
8938
9395
|
});
|
|
8939
9396
|
const frontmatter = command.getFrontmatter();
|
|
8940
9397
|
return {
|
|
8941
|
-
relativePathFromCwd:
|
|
9398
|
+
relativePathFromCwd: join85(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
|
|
8942
9399
|
frontmatter
|
|
8943
9400
|
};
|
|
8944
9401
|
} catch (error) {
|
|
@@ -8964,7 +9421,7 @@ async function getCommand({ relativePathFromCwd }) {
|
|
|
8964
9421
|
relativeFilePath: filename
|
|
8965
9422
|
});
|
|
8966
9423
|
return {
|
|
8967
|
-
relativePathFromCwd:
|
|
9424
|
+
relativePathFromCwd: join85(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
|
|
8968
9425
|
frontmatter: command.getFrontmatter(),
|
|
8969
9426
|
body: command.getBody()
|
|
8970
9427
|
};
|
|
@@ -8993,7 +9450,7 @@ async function putCommand({
|
|
|
8993
9450
|
try {
|
|
8994
9451
|
const existingCommands = await listCommands();
|
|
8995
9452
|
const isUpdate = existingCommands.some(
|
|
8996
|
-
(command2) => command2.relativePathFromCwd ===
|
|
9453
|
+
(command2) => command2.relativePathFromCwd === join85(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
|
|
8997
9454
|
);
|
|
8998
9455
|
if (!isUpdate && existingCommands.length >= maxCommandsCount) {
|
|
8999
9456
|
throw new Error(`Maximum number of commands (${maxCommandsCount}) reached`);
|
|
@@ -9008,11 +9465,11 @@ async function putCommand({
|
|
|
9008
9465
|
fileContent,
|
|
9009
9466
|
validate: true
|
|
9010
9467
|
});
|
|
9011
|
-
const commandsDir =
|
|
9468
|
+
const commandsDir = join85(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
|
|
9012
9469
|
await ensureDir(commandsDir);
|
|
9013
9470
|
await writeFileContent(command.getFilePath(), command.getFileContent());
|
|
9014
9471
|
return {
|
|
9015
|
-
relativePathFromCwd:
|
|
9472
|
+
relativePathFromCwd: join85(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
|
|
9016
9473
|
frontmatter: command.getFrontmatter(),
|
|
9017
9474
|
body: command.getBody()
|
|
9018
9475
|
};
|
|
@@ -9028,11 +9485,11 @@ async function deleteCommand({ relativePathFromCwd }) {
|
|
|
9028
9485
|
intendedRootDir: process.cwd()
|
|
9029
9486
|
});
|
|
9030
9487
|
const filename = basename22(relativePathFromCwd);
|
|
9031
|
-
const fullPath =
|
|
9488
|
+
const fullPath = join85(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
|
|
9032
9489
|
try {
|
|
9033
9490
|
await removeFile(fullPath);
|
|
9034
9491
|
return {
|
|
9035
|
-
relativePathFromCwd:
|
|
9492
|
+
relativePathFromCwd: join85(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
|
|
9036
9493
|
};
|
|
9037
9494
|
} catch (error) {
|
|
9038
9495
|
throw new Error(`Failed to delete command file ${relativePathFromCwd}: ${formatError(error)}`, {
|
|
@@ -9041,23 +9498,23 @@ async function deleteCommand({ relativePathFromCwd }) {
|
|
|
9041
9498
|
}
|
|
9042
9499
|
}
|
|
9043
9500
|
var commandToolSchemas = {
|
|
9044
|
-
listCommands:
|
|
9045
|
-
getCommand:
|
|
9046
|
-
relativePathFromCwd:
|
|
9501
|
+
listCommands: z34.object({}),
|
|
9502
|
+
getCommand: z34.object({
|
|
9503
|
+
relativePathFromCwd: z34.string()
|
|
9047
9504
|
}),
|
|
9048
|
-
putCommand:
|
|
9049
|
-
relativePathFromCwd:
|
|
9505
|
+
putCommand: z34.object({
|
|
9506
|
+
relativePathFromCwd: z34.string(),
|
|
9050
9507
|
frontmatter: RulesyncCommandFrontmatterSchema,
|
|
9051
|
-
body:
|
|
9508
|
+
body: z34.string()
|
|
9052
9509
|
}),
|
|
9053
|
-
deleteCommand:
|
|
9054
|
-
relativePathFromCwd:
|
|
9510
|
+
deleteCommand: z34.object({
|
|
9511
|
+
relativePathFromCwd: z34.string()
|
|
9055
9512
|
})
|
|
9056
9513
|
};
|
|
9057
9514
|
var commandTools = {
|
|
9058
9515
|
listCommands: {
|
|
9059
9516
|
name: "listCommands",
|
|
9060
|
-
description: `List all commands from ${
|
|
9517
|
+
description: `List all commands from ${join85(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
9061
9518
|
parameters: commandToolSchemas.listCommands,
|
|
9062
9519
|
execute: async () => {
|
|
9063
9520
|
const commands = await listCommands();
|
|
@@ -9099,11 +9556,11 @@ var commandTools = {
|
|
|
9099
9556
|
};
|
|
9100
9557
|
|
|
9101
9558
|
// src/mcp/ignore.ts
|
|
9102
|
-
import { join as
|
|
9103
|
-
import { z as
|
|
9559
|
+
import { join as join86 } from "path";
|
|
9560
|
+
import { z as z35 } from "zod/mini";
|
|
9104
9561
|
var maxIgnoreFileSizeBytes = 100 * 1024;
|
|
9105
9562
|
async function getIgnoreFile() {
|
|
9106
|
-
const ignoreFilePath =
|
|
9563
|
+
const ignoreFilePath = join86(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
9107
9564
|
try {
|
|
9108
9565
|
const content = await readFileContent(ignoreFilePath);
|
|
9109
9566
|
return {
|
|
@@ -9117,7 +9574,7 @@ async function getIgnoreFile() {
|
|
|
9117
9574
|
}
|
|
9118
9575
|
}
|
|
9119
9576
|
async function putIgnoreFile({ content }) {
|
|
9120
|
-
const ignoreFilePath =
|
|
9577
|
+
const ignoreFilePath = join86(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
9121
9578
|
const contentSizeBytes = Buffer.byteLength(content, "utf8");
|
|
9122
9579
|
if (contentSizeBytes > maxIgnoreFileSizeBytes) {
|
|
9123
9580
|
throw new Error(
|
|
@@ -9138,8 +9595,8 @@ async function putIgnoreFile({ content }) {
|
|
|
9138
9595
|
}
|
|
9139
9596
|
}
|
|
9140
9597
|
async function deleteIgnoreFile() {
|
|
9141
|
-
const aiignorePath =
|
|
9142
|
-
const legacyIgnorePath =
|
|
9598
|
+
const aiignorePath = join86(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
9599
|
+
const legacyIgnorePath = join86(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
|
|
9143
9600
|
try {
|
|
9144
9601
|
await Promise.all([removeFile(aiignorePath), removeFile(legacyIgnorePath)]);
|
|
9145
9602
|
return {
|
|
@@ -9157,11 +9614,11 @@ async function deleteIgnoreFile() {
|
|
|
9157
9614
|
}
|
|
9158
9615
|
}
|
|
9159
9616
|
var ignoreToolSchemas = {
|
|
9160
|
-
getIgnoreFile:
|
|
9161
|
-
putIgnoreFile:
|
|
9162
|
-
content:
|
|
9617
|
+
getIgnoreFile: z35.object({}),
|
|
9618
|
+
putIgnoreFile: z35.object({
|
|
9619
|
+
content: z35.string()
|
|
9163
9620
|
}),
|
|
9164
|
-
deleteIgnoreFile:
|
|
9621
|
+
deleteIgnoreFile: z35.object({})
|
|
9165
9622
|
};
|
|
9166
9623
|
var ignoreTools = {
|
|
9167
9624
|
getIgnoreFile: {
|
|
@@ -9194,8 +9651,8 @@ var ignoreTools = {
|
|
|
9194
9651
|
};
|
|
9195
9652
|
|
|
9196
9653
|
// src/mcp/mcp.ts
|
|
9197
|
-
import { join as
|
|
9198
|
-
import { z as
|
|
9654
|
+
import { join as join87 } from "path";
|
|
9655
|
+
import { z as z36 } from "zod/mini";
|
|
9199
9656
|
var maxMcpSizeBytes = 1024 * 1024;
|
|
9200
9657
|
async function getMcpFile() {
|
|
9201
9658
|
const config = await ConfigResolver.resolve({});
|
|
@@ -9204,7 +9661,7 @@ async function getMcpFile() {
|
|
|
9204
9661
|
validate: true,
|
|
9205
9662
|
modularMcp: config.getModularMcp()
|
|
9206
9663
|
});
|
|
9207
|
-
const relativePathFromCwd =
|
|
9664
|
+
const relativePathFromCwd = join87(
|
|
9208
9665
|
rulesyncMcp.getRelativeDirPath(),
|
|
9209
9666
|
rulesyncMcp.getRelativeFilePath()
|
|
9210
9667
|
);
|
|
@@ -9237,7 +9694,7 @@ async function putMcpFile({ content }) {
|
|
|
9237
9694
|
const paths = RulesyncMcp.getSettablePaths();
|
|
9238
9695
|
const relativeDirPath = paths.recommended.relativeDirPath;
|
|
9239
9696
|
const relativeFilePath = paths.recommended.relativeFilePath;
|
|
9240
|
-
const fullPath =
|
|
9697
|
+
const fullPath = join87(baseDir, relativeDirPath, relativeFilePath);
|
|
9241
9698
|
const rulesyncMcp = new RulesyncMcp({
|
|
9242
9699
|
baseDir,
|
|
9243
9700
|
relativeDirPath,
|
|
@@ -9246,9 +9703,9 @@ async function putMcpFile({ content }) {
|
|
|
9246
9703
|
validate: true,
|
|
9247
9704
|
modularMcp: config.getModularMcp()
|
|
9248
9705
|
});
|
|
9249
|
-
await ensureDir(
|
|
9706
|
+
await ensureDir(join87(baseDir, relativeDirPath));
|
|
9250
9707
|
await writeFileContent(fullPath, content);
|
|
9251
|
-
const relativePathFromCwd =
|
|
9708
|
+
const relativePathFromCwd = join87(relativeDirPath, relativeFilePath);
|
|
9252
9709
|
return {
|
|
9253
9710
|
relativePathFromCwd,
|
|
9254
9711
|
content: rulesyncMcp.getFileContent()
|
|
@@ -9263,15 +9720,15 @@ async function deleteMcpFile() {
|
|
|
9263
9720
|
try {
|
|
9264
9721
|
const baseDir = process.cwd();
|
|
9265
9722
|
const paths = RulesyncMcp.getSettablePaths();
|
|
9266
|
-
const recommendedPath =
|
|
9723
|
+
const recommendedPath = join87(
|
|
9267
9724
|
baseDir,
|
|
9268
9725
|
paths.recommended.relativeDirPath,
|
|
9269
9726
|
paths.recommended.relativeFilePath
|
|
9270
9727
|
);
|
|
9271
|
-
const legacyPath =
|
|
9728
|
+
const legacyPath = join87(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
|
|
9272
9729
|
await removeFile(recommendedPath);
|
|
9273
9730
|
await removeFile(legacyPath);
|
|
9274
|
-
const relativePathFromCwd =
|
|
9731
|
+
const relativePathFromCwd = join87(
|
|
9275
9732
|
paths.recommended.relativeDirPath,
|
|
9276
9733
|
paths.recommended.relativeFilePath
|
|
9277
9734
|
);
|
|
@@ -9285,11 +9742,11 @@ async function deleteMcpFile() {
|
|
|
9285
9742
|
}
|
|
9286
9743
|
}
|
|
9287
9744
|
var mcpToolSchemas = {
|
|
9288
|
-
getMcpFile:
|
|
9289
|
-
putMcpFile:
|
|
9290
|
-
content:
|
|
9745
|
+
getMcpFile: z36.object({}),
|
|
9746
|
+
putMcpFile: z36.object({
|
|
9747
|
+
content: z36.string()
|
|
9291
9748
|
}),
|
|
9292
|
-
deleteMcpFile:
|
|
9749
|
+
deleteMcpFile: z36.object({})
|
|
9293
9750
|
};
|
|
9294
9751
|
var mcpTools = {
|
|
9295
9752
|
getMcpFile: {
|
|
@@ -9322,12 +9779,12 @@ var mcpTools = {
|
|
|
9322
9779
|
};
|
|
9323
9780
|
|
|
9324
9781
|
// src/mcp/rules.ts
|
|
9325
|
-
import { basename as basename23, join as
|
|
9326
|
-
import { z as
|
|
9782
|
+
import { basename as basename23, join as join88 } from "path";
|
|
9783
|
+
import { z as z37 } from "zod/mini";
|
|
9327
9784
|
var maxRuleSizeBytes = 1024 * 1024;
|
|
9328
9785
|
var maxRulesCount = 1e3;
|
|
9329
9786
|
async function listRules() {
|
|
9330
|
-
const rulesDir =
|
|
9787
|
+
const rulesDir = join88(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
|
|
9331
9788
|
try {
|
|
9332
9789
|
const files = await listDirectoryFiles(rulesDir);
|
|
9333
9790
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -9340,7 +9797,7 @@ async function listRules() {
|
|
|
9340
9797
|
});
|
|
9341
9798
|
const frontmatter = rule.getFrontmatter();
|
|
9342
9799
|
return {
|
|
9343
|
-
relativePathFromCwd:
|
|
9800
|
+
relativePathFromCwd: join88(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
|
|
9344
9801
|
frontmatter
|
|
9345
9802
|
};
|
|
9346
9803
|
} catch (error) {
|
|
@@ -9367,7 +9824,7 @@ async function getRule({ relativePathFromCwd }) {
|
|
|
9367
9824
|
validate: true
|
|
9368
9825
|
});
|
|
9369
9826
|
return {
|
|
9370
|
-
relativePathFromCwd:
|
|
9827
|
+
relativePathFromCwd: join88(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
|
|
9371
9828
|
frontmatter: rule.getFrontmatter(),
|
|
9372
9829
|
body: rule.getBody()
|
|
9373
9830
|
};
|
|
@@ -9396,7 +9853,7 @@ async function putRule({
|
|
|
9396
9853
|
try {
|
|
9397
9854
|
const existingRules = await listRules();
|
|
9398
9855
|
const isUpdate = existingRules.some(
|
|
9399
|
-
(rule2) => rule2.relativePathFromCwd ===
|
|
9856
|
+
(rule2) => rule2.relativePathFromCwd === join88(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
|
|
9400
9857
|
);
|
|
9401
9858
|
if (!isUpdate && existingRules.length >= maxRulesCount) {
|
|
9402
9859
|
throw new Error(`Maximum number of rules (${maxRulesCount}) reached`);
|
|
@@ -9409,11 +9866,11 @@ async function putRule({
|
|
|
9409
9866
|
body,
|
|
9410
9867
|
validate: true
|
|
9411
9868
|
});
|
|
9412
|
-
const rulesDir =
|
|
9869
|
+
const rulesDir = join88(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
|
|
9413
9870
|
await ensureDir(rulesDir);
|
|
9414
9871
|
await writeFileContent(rule.getFilePath(), rule.getFileContent());
|
|
9415
9872
|
return {
|
|
9416
|
-
relativePathFromCwd:
|
|
9873
|
+
relativePathFromCwd: join88(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
|
|
9417
9874
|
frontmatter: rule.getFrontmatter(),
|
|
9418
9875
|
body: rule.getBody()
|
|
9419
9876
|
};
|
|
@@ -9429,11 +9886,11 @@ async function deleteRule({ relativePathFromCwd }) {
|
|
|
9429
9886
|
intendedRootDir: process.cwd()
|
|
9430
9887
|
});
|
|
9431
9888
|
const filename = basename23(relativePathFromCwd);
|
|
9432
|
-
const fullPath =
|
|
9889
|
+
const fullPath = join88(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
|
|
9433
9890
|
try {
|
|
9434
9891
|
await removeFile(fullPath);
|
|
9435
9892
|
return {
|
|
9436
|
-
relativePathFromCwd:
|
|
9893
|
+
relativePathFromCwd: join88(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
|
|
9437
9894
|
};
|
|
9438
9895
|
} catch (error) {
|
|
9439
9896
|
throw new Error(`Failed to delete rule file ${relativePathFromCwd}: ${formatError(error)}`, {
|
|
@@ -9442,23 +9899,23 @@ async function deleteRule({ relativePathFromCwd }) {
|
|
|
9442
9899
|
}
|
|
9443
9900
|
}
|
|
9444
9901
|
var ruleToolSchemas = {
|
|
9445
|
-
listRules:
|
|
9446
|
-
getRule:
|
|
9447
|
-
relativePathFromCwd:
|
|
9902
|
+
listRules: z37.object({}),
|
|
9903
|
+
getRule: z37.object({
|
|
9904
|
+
relativePathFromCwd: z37.string()
|
|
9448
9905
|
}),
|
|
9449
|
-
putRule:
|
|
9450
|
-
relativePathFromCwd:
|
|
9906
|
+
putRule: z37.object({
|
|
9907
|
+
relativePathFromCwd: z37.string(),
|
|
9451
9908
|
frontmatter: RulesyncRuleFrontmatterSchema,
|
|
9452
|
-
body:
|
|
9909
|
+
body: z37.string()
|
|
9453
9910
|
}),
|
|
9454
|
-
deleteRule:
|
|
9455
|
-
relativePathFromCwd:
|
|
9911
|
+
deleteRule: z37.object({
|
|
9912
|
+
relativePathFromCwd: z37.string()
|
|
9456
9913
|
})
|
|
9457
9914
|
};
|
|
9458
9915
|
var ruleTools = {
|
|
9459
9916
|
listRules: {
|
|
9460
9917
|
name: "listRules",
|
|
9461
|
-
description: `List all rules from ${
|
|
9918
|
+
description: `List all rules from ${join88(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
9462
9919
|
parameters: ruleToolSchemas.listRules,
|
|
9463
9920
|
execute: async () => {
|
|
9464
9921
|
const rules = await listRules();
|
|
@@ -9500,8 +9957,8 @@ var ruleTools = {
|
|
|
9500
9957
|
};
|
|
9501
9958
|
|
|
9502
9959
|
// src/mcp/skills.ts
|
|
9503
|
-
import { basename as basename24, dirname as dirname2, join as
|
|
9504
|
-
import { z as
|
|
9960
|
+
import { basename as basename24, dirname as dirname2, join as join89 } from "path";
|
|
9961
|
+
import { z as z38 } from "zod/mini";
|
|
9505
9962
|
var maxSkillSizeBytes = 1024 * 1024;
|
|
9506
9963
|
var maxSkillsCount = 1e3;
|
|
9507
9964
|
function aiDirFileToMcpSkillFile(file) {
|
|
@@ -9524,9 +9981,9 @@ function extractDirName(relativeDirPathFromCwd) {
|
|
|
9524
9981
|
return dirName;
|
|
9525
9982
|
}
|
|
9526
9983
|
async function listSkills() {
|
|
9527
|
-
const skillsDir =
|
|
9984
|
+
const skillsDir = join89(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH);
|
|
9528
9985
|
try {
|
|
9529
|
-
const skillDirPaths = await findFilesByGlobs(
|
|
9986
|
+
const skillDirPaths = await findFilesByGlobs(join89(skillsDir, "*"), { type: "dir" });
|
|
9530
9987
|
const skills = await Promise.all(
|
|
9531
9988
|
skillDirPaths.map(async (dirPath) => {
|
|
9532
9989
|
const dirName = basename24(dirPath);
|
|
@@ -9537,7 +9994,7 @@ async function listSkills() {
|
|
|
9537
9994
|
});
|
|
9538
9995
|
const frontmatter = skill.getFrontmatter();
|
|
9539
9996
|
return {
|
|
9540
|
-
relativeDirPathFromCwd:
|
|
9997
|
+
relativeDirPathFromCwd: join89(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
9541
9998
|
frontmatter
|
|
9542
9999
|
};
|
|
9543
10000
|
} catch (error) {
|
|
@@ -9563,7 +10020,7 @@ async function getSkill({ relativeDirPathFromCwd }) {
|
|
|
9563
10020
|
dirName
|
|
9564
10021
|
});
|
|
9565
10022
|
return {
|
|
9566
|
-
relativeDirPathFromCwd:
|
|
10023
|
+
relativeDirPathFromCwd: join89(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
9567
10024
|
frontmatter: skill.getFrontmatter(),
|
|
9568
10025
|
body: skill.getBody(),
|
|
9569
10026
|
otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
|
|
@@ -9597,7 +10054,7 @@ async function putSkill({
|
|
|
9597
10054
|
try {
|
|
9598
10055
|
const existingSkills = await listSkills();
|
|
9599
10056
|
const isUpdate = existingSkills.some(
|
|
9600
|
-
(skill2) => skill2.relativeDirPathFromCwd ===
|
|
10057
|
+
(skill2) => skill2.relativeDirPathFromCwd === join89(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
|
|
9601
10058
|
);
|
|
9602
10059
|
if (!isUpdate && existingSkills.length >= maxSkillsCount) {
|
|
9603
10060
|
throw new Error(`Maximum number of skills (${maxSkillsCount}) reached`);
|
|
@@ -9612,9 +10069,9 @@ async function putSkill({
|
|
|
9612
10069
|
otherFiles: aiDirFiles,
|
|
9613
10070
|
validate: true
|
|
9614
10071
|
});
|
|
9615
|
-
const skillDirPath =
|
|
10072
|
+
const skillDirPath = join89(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
|
|
9616
10073
|
await ensureDir(skillDirPath);
|
|
9617
|
-
const skillFilePath =
|
|
10074
|
+
const skillFilePath = join89(skillDirPath, SKILL_FILE_NAME);
|
|
9618
10075
|
const skillFileContent = stringifyFrontmatter(body, frontmatter);
|
|
9619
10076
|
await writeFileContent(skillFilePath, skillFileContent);
|
|
9620
10077
|
for (const file of otherFiles) {
|
|
@@ -9622,15 +10079,15 @@ async function putSkill({
|
|
|
9622
10079
|
relativePath: file.name,
|
|
9623
10080
|
intendedRootDir: skillDirPath
|
|
9624
10081
|
});
|
|
9625
|
-
const filePath =
|
|
9626
|
-
const fileDir =
|
|
10082
|
+
const filePath = join89(skillDirPath, file.name);
|
|
10083
|
+
const fileDir = join89(skillDirPath, dirname2(file.name));
|
|
9627
10084
|
if (fileDir !== skillDirPath) {
|
|
9628
10085
|
await ensureDir(fileDir);
|
|
9629
10086
|
}
|
|
9630
10087
|
await writeFileContent(filePath, file.body);
|
|
9631
10088
|
}
|
|
9632
10089
|
return {
|
|
9633
|
-
relativeDirPathFromCwd:
|
|
10090
|
+
relativeDirPathFromCwd: join89(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
9634
10091
|
frontmatter: skill.getFrontmatter(),
|
|
9635
10092
|
body: skill.getBody(),
|
|
9636
10093
|
otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
|
|
@@ -9652,13 +10109,13 @@ async function deleteSkill({
|
|
|
9652
10109
|
intendedRootDir: process.cwd()
|
|
9653
10110
|
});
|
|
9654
10111
|
const dirName = extractDirName(relativeDirPathFromCwd);
|
|
9655
|
-
const skillDirPath =
|
|
10112
|
+
const skillDirPath = join89(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
|
|
9656
10113
|
try {
|
|
9657
10114
|
if (await directoryExists(skillDirPath)) {
|
|
9658
10115
|
await removeDirectory(skillDirPath);
|
|
9659
10116
|
}
|
|
9660
10117
|
return {
|
|
9661
|
-
relativeDirPathFromCwd:
|
|
10118
|
+
relativeDirPathFromCwd: join89(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
|
|
9662
10119
|
};
|
|
9663
10120
|
} catch (error) {
|
|
9664
10121
|
throw new Error(
|
|
@@ -9669,29 +10126,29 @@ async function deleteSkill({
|
|
|
9669
10126
|
);
|
|
9670
10127
|
}
|
|
9671
10128
|
}
|
|
9672
|
-
var McpSkillFileSchema =
|
|
9673
|
-
name:
|
|
9674
|
-
body:
|
|
10129
|
+
var McpSkillFileSchema = z38.object({
|
|
10130
|
+
name: z38.string(),
|
|
10131
|
+
body: z38.string()
|
|
9675
10132
|
});
|
|
9676
10133
|
var skillToolSchemas = {
|
|
9677
|
-
listSkills:
|
|
9678
|
-
getSkill:
|
|
9679
|
-
relativeDirPathFromCwd:
|
|
10134
|
+
listSkills: z38.object({}),
|
|
10135
|
+
getSkill: z38.object({
|
|
10136
|
+
relativeDirPathFromCwd: z38.string()
|
|
9680
10137
|
}),
|
|
9681
|
-
putSkill:
|
|
9682
|
-
relativeDirPathFromCwd:
|
|
10138
|
+
putSkill: z38.object({
|
|
10139
|
+
relativeDirPathFromCwd: z38.string(),
|
|
9683
10140
|
frontmatter: RulesyncSkillFrontmatterSchema,
|
|
9684
|
-
body:
|
|
9685
|
-
otherFiles:
|
|
10141
|
+
body: z38.string(),
|
|
10142
|
+
otherFiles: z38.optional(z38.array(McpSkillFileSchema))
|
|
9686
10143
|
}),
|
|
9687
|
-
deleteSkill:
|
|
9688
|
-
relativeDirPathFromCwd:
|
|
10144
|
+
deleteSkill: z38.object({
|
|
10145
|
+
relativeDirPathFromCwd: z38.string()
|
|
9689
10146
|
})
|
|
9690
10147
|
};
|
|
9691
10148
|
var skillTools = {
|
|
9692
10149
|
listSkills: {
|
|
9693
10150
|
name: "listSkills",
|
|
9694
|
-
description: `List all skills from ${
|
|
10151
|
+
description: `List all skills from ${join89(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "*", SKILL_FILE_NAME)} with their frontmatter.`,
|
|
9695
10152
|
parameters: skillToolSchemas.listSkills,
|
|
9696
10153
|
execute: async () => {
|
|
9697
10154
|
const skills = await listSkills();
|
|
@@ -9734,12 +10191,12 @@ var skillTools = {
|
|
|
9734
10191
|
};
|
|
9735
10192
|
|
|
9736
10193
|
// src/mcp/subagents.ts
|
|
9737
|
-
import { basename as basename25, join as
|
|
9738
|
-
import { z as
|
|
10194
|
+
import { basename as basename25, join as join90 } from "path";
|
|
10195
|
+
import { z as z39 } from "zod/mini";
|
|
9739
10196
|
var maxSubagentSizeBytes = 1024 * 1024;
|
|
9740
10197
|
var maxSubagentsCount = 1e3;
|
|
9741
10198
|
async function listSubagents() {
|
|
9742
|
-
const subagentsDir =
|
|
10199
|
+
const subagentsDir = join90(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
|
|
9743
10200
|
try {
|
|
9744
10201
|
const files = await listDirectoryFiles(subagentsDir);
|
|
9745
10202
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -9752,7 +10209,7 @@ async function listSubagents() {
|
|
|
9752
10209
|
});
|
|
9753
10210
|
const frontmatter = subagent.getFrontmatter();
|
|
9754
10211
|
return {
|
|
9755
|
-
relativePathFromCwd:
|
|
10212
|
+
relativePathFromCwd: join90(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
|
|
9756
10213
|
frontmatter
|
|
9757
10214
|
};
|
|
9758
10215
|
} catch (error) {
|
|
@@ -9781,7 +10238,7 @@ async function getSubagent({ relativePathFromCwd }) {
|
|
|
9781
10238
|
validate: true
|
|
9782
10239
|
});
|
|
9783
10240
|
return {
|
|
9784
|
-
relativePathFromCwd:
|
|
10241
|
+
relativePathFromCwd: join90(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
|
|
9785
10242
|
frontmatter: subagent.getFrontmatter(),
|
|
9786
10243
|
body: subagent.getBody()
|
|
9787
10244
|
};
|
|
@@ -9810,7 +10267,7 @@ async function putSubagent({
|
|
|
9810
10267
|
try {
|
|
9811
10268
|
const existingSubagents = await listSubagents();
|
|
9812
10269
|
const isUpdate = existingSubagents.some(
|
|
9813
|
-
(subagent2) => subagent2.relativePathFromCwd ===
|
|
10270
|
+
(subagent2) => subagent2.relativePathFromCwd === join90(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
|
|
9814
10271
|
);
|
|
9815
10272
|
if (!isUpdate && existingSubagents.length >= maxSubagentsCount) {
|
|
9816
10273
|
throw new Error(`Maximum number of subagents (${maxSubagentsCount}) reached`);
|
|
@@ -9823,11 +10280,11 @@ async function putSubagent({
|
|
|
9823
10280
|
body,
|
|
9824
10281
|
validate: true
|
|
9825
10282
|
});
|
|
9826
|
-
const subagentsDir =
|
|
10283
|
+
const subagentsDir = join90(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
|
|
9827
10284
|
await ensureDir(subagentsDir);
|
|
9828
10285
|
await writeFileContent(subagent.getFilePath(), subagent.getFileContent());
|
|
9829
10286
|
return {
|
|
9830
|
-
relativePathFromCwd:
|
|
10287
|
+
relativePathFromCwd: join90(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
|
|
9831
10288
|
frontmatter: subagent.getFrontmatter(),
|
|
9832
10289
|
body: subagent.getBody()
|
|
9833
10290
|
};
|
|
@@ -9843,11 +10300,11 @@ async function deleteSubagent({ relativePathFromCwd }) {
|
|
|
9843
10300
|
intendedRootDir: process.cwd()
|
|
9844
10301
|
});
|
|
9845
10302
|
const filename = basename25(relativePathFromCwd);
|
|
9846
|
-
const fullPath =
|
|
10303
|
+
const fullPath = join90(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
|
|
9847
10304
|
try {
|
|
9848
10305
|
await removeFile(fullPath);
|
|
9849
10306
|
return {
|
|
9850
|
-
relativePathFromCwd:
|
|
10307
|
+
relativePathFromCwd: join90(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
|
|
9851
10308
|
};
|
|
9852
10309
|
} catch (error) {
|
|
9853
10310
|
throw new Error(
|
|
@@ -9859,23 +10316,23 @@ async function deleteSubagent({ relativePathFromCwd }) {
|
|
|
9859
10316
|
}
|
|
9860
10317
|
}
|
|
9861
10318
|
var subagentToolSchemas = {
|
|
9862
|
-
listSubagents:
|
|
9863
|
-
getSubagent:
|
|
9864
|
-
relativePathFromCwd:
|
|
10319
|
+
listSubagents: z39.object({}),
|
|
10320
|
+
getSubagent: z39.object({
|
|
10321
|
+
relativePathFromCwd: z39.string()
|
|
9865
10322
|
}),
|
|
9866
|
-
putSubagent:
|
|
9867
|
-
relativePathFromCwd:
|
|
10323
|
+
putSubagent: z39.object({
|
|
10324
|
+
relativePathFromCwd: z39.string(),
|
|
9868
10325
|
frontmatter: RulesyncSubagentFrontmatterSchema,
|
|
9869
|
-
body:
|
|
10326
|
+
body: z39.string()
|
|
9870
10327
|
}),
|
|
9871
|
-
deleteSubagent:
|
|
9872
|
-
relativePathFromCwd:
|
|
10328
|
+
deleteSubagent: z39.object({
|
|
10329
|
+
relativePathFromCwd: z39.string()
|
|
9873
10330
|
})
|
|
9874
10331
|
};
|
|
9875
10332
|
var subagentTools = {
|
|
9876
10333
|
listSubagents: {
|
|
9877
10334
|
name: "listSubagents",
|
|
9878
|
-
description: `List all subagents from ${
|
|
10335
|
+
description: `List all subagents from ${join90(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
9879
10336
|
parameters: subagentToolSchemas.listSubagents,
|
|
9880
10337
|
execute: async () => {
|
|
9881
10338
|
const subagents = await listSubagents();
|
|
@@ -9953,7 +10410,7 @@ async function mcpCommand({ version }) {
|
|
|
9953
10410
|
}
|
|
9954
10411
|
|
|
9955
10412
|
// src/cli/index.ts
|
|
9956
|
-
var getVersion = () => "3.
|
|
10413
|
+
var getVersion = () => "3.33.0";
|
|
9957
10414
|
var main = async () => {
|
|
9958
10415
|
const program = new Command();
|
|
9959
10416
|
const version = getVersion();
|