rulesync 3.28.0 → 3.28.2
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 +21 -4
- package/dist/index.cjs +102 -52
- package/dist/index.js +102 -52
- package/package.json +9 -8
package/README.md
CHANGED
|
@@ -203,7 +203,7 @@ npx rulesync generate --targets claudecode --features rules,subagents
|
|
|
203
203
|
npx rulesync generate --targets "*" --features rules
|
|
204
204
|
|
|
205
205
|
# Generate simulated commands and subagents
|
|
206
|
-
npx rulesync generate --targets copilot,cursor,codexcli --features commands,subagents --
|
|
206
|
+
npx rulesync generate --targets copilot,cursor,codexcli --features commands,subagents --simulate-commands --simulate-subagents
|
|
207
207
|
|
|
208
208
|
# Add generated files to .gitignore
|
|
209
209
|
npx rulesync gitignore
|
|
@@ -213,11 +213,28 @@ npx rulesync gitignore
|
|
|
213
213
|
|
|
214
214
|
You can configure Rulesync by creating a `rulesync.jsonc` file in the root of your project.
|
|
215
215
|
|
|
216
|
+
### JSON Schema Support
|
|
217
|
+
|
|
218
|
+
Rulesync provides a JSON Schema for editor validation and autocompletion. Add the `$schema` property to your `rulesync.jsonc`:
|
|
219
|
+
|
|
220
|
+
```jsonc
|
|
221
|
+
// rulesync.jsonc
|
|
222
|
+
{
|
|
223
|
+
"$schema": "https://raw.githubusercontent.com/dyoshikawa/rulesync/refs/heads/main/config-schema.json",
|
|
224
|
+
"targets": ["claudecode"],
|
|
225
|
+
"features": ["rules"]
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Configuration Options
|
|
230
|
+
|
|
216
231
|
Example:
|
|
217
232
|
|
|
218
233
|
```jsonc
|
|
219
234
|
// rulesync.jsonc
|
|
220
235
|
{
|
|
236
|
+
"$schema": "https://raw.githubusercontent.com/dyoshikawa/rulesync/refs/heads/main/config-schema.json",
|
|
237
|
+
|
|
221
238
|
// List of tools to generate configurations for. You can specify "*" to generate all tools.
|
|
222
239
|
"targets": ["cursor", "claudecode", "geminicli", "opencode", "codexcli"],
|
|
223
240
|
|
|
@@ -466,9 +483,9 @@ Simulated commands, subagents and skills allow you to generate simulated feature
|
|
|
466
483
|
npx rulesync generate \
|
|
467
484
|
--targets copilot,cursor,codexcli \
|
|
468
485
|
--features commands,subagents,skills \
|
|
469
|
-
--
|
|
470
|
-
--
|
|
471
|
-
--
|
|
486
|
+
--simulate-commands \
|
|
487
|
+
--simulate-subagents \
|
|
488
|
+
--simulate-skills
|
|
472
489
|
```
|
|
473
490
|
3. Use simulated commands, subagents and skills in your prompts.
|
|
474
491
|
- Prompt examples:
|
package/dist/index.cjs
CHANGED
|
@@ -290,6 +290,10 @@ var ConfigParamsSchema = import_mini3.z.object({
|
|
|
290
290
|
experimentalSimulateSubagents: (0, import_mini3.optional)(import_mini3.z.boolean())
|
|
291
291
|
});
|
|
292
292
|
var PartialConfigParamsSchema = import_mini3.z.partial(ConfigParamsSchema);
|
|
293
|
+
var ConfigFileSchema = import_mini3.z.object({
|
|
294
|
+
$schema: (0, import_mini3.optional)(import_mini3.z.string()),
|
|
295
|
+
...import_mini3.z.partial(ConfigParamsSchema).shape
|
|
296
|
+
});
|
|
293
297
|
var RequiredConfigParamsSchema = import_mini3.z.required(ConfigParamsSchema);
|
|
294
298
|
var Config = class {
|
|
295
299
|
baseDirs;
|
|
@@ -419,7 +423,9 @@ var ConfigResolver = class {
|
|
|
419
423
|
try {
|
|
420
424
|
const fileContent = await readFileContent(validatedConfigPath);
|
|
421
425
|
const jsonData = (0, import_jsonc_parser.parse)(fileContent);
|
|
422
|
-
|
|
426
|
+
const parsed = ConfigFileSchema.parse(jsonData);
|
|
427
|
+
const { $schema: _schema, ...configParams2 } = parsed;
|
|
428
|
+
configByFile = configParams2;
|
|
423
429
|
} catch (error) {
|
|
424
430
|
logger.error(`Failed to load config file: ${formatError(error)}`);
|
|
425
431
|
throw error;
|
|
@@ -665,6 +671,13 @@ var AiFile = class {
|
|
|
665
671
|
setFileContent(newFileContent) {
|
|
666
672
|
this.fileContent = newFileContent;
|
|
667
673
|
}
|
|
674
|
+
/**
|
|
675
|
+
* Returns whether this file can be deleted by rulesync.
|
|
676
|
+
* Override in subclasses that should not be deleted (e.g., user-managed config files).
|
|
677
|
+
*/
|
|
678
|
+
isDeletable() {
|
|
679
|
+
return true;
|
|
680
|
+
}
|
|
668
681
|
};
|
|
669
682
|
|
|
670
683
|
// src/features/commands/tool-command.ts
|
|
@@ -899,7 +912,7 @@ var RulesyncFile = class extends AiFile {
|
|
|
899
912
|
};
|
|
900
913
|
|
|
901
914
|
// src/features/commands/rulesync-command.ts
|
|
902
|
-
var RulesyncCommandFrontmatterSchema = import_mini5.z.
|
|
915
|
+
var RulesyncCommandFrontmatterSchema = import_mini5.z.looseObject({
|
|
903
916
|
targets: RulesyncTargetsSchema,
|
|
904
917
|
description: import_mini5.z.string()
|
|
905
918
|
});
|
|
@@ -1100,7 +1113,7 @@ var AntigravityCommand = class _AntigravityCommand extends ToolCommand {
|
|
|
1100
1113
|
// src/features/commands/claudecode-command.ts
|
|
1101
1114
|
var import_node_path9 = require("path");
|
|
1102
1115
|
var import_mini7 = require("zod/mini");
|
|
1103
|
-
var ClaudecodeCommandFrontmatterSchema = import_mini7.z.
|
|
1116
|
+
var ClaudecodeCommandFrontmatterSchema = import_mini7.z.looseObject({
|
|
1104
1117
|
description: import_mini7.z.string()
|
|
1105
1118
|
});
|
|
1106
1119
|
var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
@@ -1134,9 +1147,12 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
|
1134
1147
|
return this.frontmatter;
|
|
1135
1148
|
}
|
|
1136
1149
|
toRulesyncCommand() {
|
|
1150
|
+
const { description, ...restFields } = this.frontmatter;
|
|
1137
1151
|
const rulesyncFrontmatter = {
|
|
1138
1152
|
targets: ["*"],
|
|
1139
|
-
description
|
|
1153
|
+
description,
|
|
1154
|
+
// Preserve extra fields in claudecode section
|
|
1155
|
+
...Object.keys(restFields).length > 0 && { claudecode: restFields }
|
|
1140
1156
|
};
|
|
1141
1157
|
const fileContent = stringifyFrontmatter(this.body, rulesyncFrontmatter);
|
|
1142
1158
|
return new RulesyncCommand({
|
|
@@ -1157,8 +1173,10 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
|
1157
1173
|
global = false
|
|
1158
1174
|
}) {
|
|
1159
1175
|
const rulesyncFrontmatter = rulesyncCommand.getFrontmatter();
|
|
1176
|
+
const claudecodeFields = rulesyncFrontmatter.claudecode ?? {};
|
|
1160
1177
|
const claudecodeFrontmatter = {
|
|
1161
|
-
description: rulesyncFrontmatter.description
|
|
1178
|
+
description: rulesyncFrontmatter.description,
|
|
1179
|
+
...claudecodeFields
|
|
1162
1180
|
};
|
|
1163
1181
|
const body = rulesyncCommand.getBody();
|
|
1164
1182
|
const paths = this.getSettablePaths({ global });
|
|
@@ -1295,7 +1313,7 @@ var CodexcliCommand = class _CodexcliCommand extends ToolCommand {
|
|
|
1295
1313
|
// src/features/commands/copilot-command.ts
|
|
1296
1314
|
var import_node_path11 = require("path");
|
|
1297
1315
|
var import_mini8 = require("zod/mini");
|
|
1298
|
-
var CopilotCommandFrontmatterSchema = import_mini8.z.
|
|
1316
|
+
var CopilotCommandFrontmatterSchema = import_mini8.z.looseObject({
|
|
1299
1317
|
mode: import_mini8.z.literal("agent"),
|
|
1300
1318
|
description: import_mini8.z.string()
|
|
1301
1319
|
});
|
|
@@ -1330,9 +1348,12 @@ var CopilotCommand = class _CopilotCommand extends ToolCommand {
|
|
|
1330
1348
|
return this.frontmatter;
|
|
1331
1349
|
}
|
|
1332
1350
|
toRulesyncCommand() {
|
|
1351
|
+
const { mode: _mode, description, ...restFields } = this.frontmatter;
|
|
1333
1352
|
const rulesyncFrontmatter = {
|
|
1334
1353
|
targets: ["*"],
|
|
1335
|
-
description
|
|
1354
|
+
description,
|
|
1355
|
+
// Preserve extra fields in copilot section (excluding mode which is fixed)
|
|
1356
|
+
...Object.keys(restFields).length > 0 && { copilot: restFields }
|
|
1336
1357
|
};
|
|
1337
1358
|
const originalFilePath = this.relativeFilePath;
|
|
1338
1359
|
const relativeFilePath = originalFilePath.replace(/\.prompt\.md$/, ".md");
|
|
@@ -1369,9 +1390,11 @@ var CopilotCommand = class _CopilotCommand extends ToolCommand {
|
|
|
1369
1390
|
}) {
|
|
1370
1391
|
const paths = this.getSettablePaths();
|
|
1371
1392
|
const rulesyncFrontmatter = rulesyncCommand.getFrontmatter();
|
|
1393
|
+
const copilotFields = rulesyncFrontmatter.copilot ?? {};
|
|
1372
1394
|
const copilotFrontmatter = {
|
|
1373
1395
|
mode: "agent",
|
|
1374
|
-
description: rulesyncFrontmatter.description
|
|
1396
|
+
description: rulesyncFrontmatter.description,
|
|
1397
|
+
...copilotFields
|
|
1375
1398
|
};
|
|
1376
1399
|
const body = rulesyncCommand.getBody();
|
|
1377
1400
|
const originalFilePath = rulesyncCommand.getRelativeFilePath();
|
|
@@ -1490,7 +1513,7 @@ var CursorCommand = class _CursorCommand extends ToolCommand {
|
|
|
1490
1513
|
var import_node_path13 = require("path");
|
|
1491
1514
|
var import_smol_toml = require("smol-toml");
|
|
1492
1515
|
var import_mini9 = require("zod/mini");
|
|
1493
|
-
var GeminiCliCommandFrontmatterSchema = import_mini9.z.
|
|
1516
|
+
var GeminiCliCommandFrontmatterSchema = import_mini9.z.looseObject({
|
|
1494
1517
|
description: import_mini9.z.optional(import_mini9.z.string()),
|
|
1495
1518
|
prompt: import_mini9.z.string()
|
|
1496
1519
|
});
|
|
@@ -1518,8 +1541,8 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
|
|
|
1518
1541
|
);
|
|
1519
1542
|
}
|
|
1520
1543
|
return {
|
|
1521
|
-
|
|
1522
|
-
|
|
1544
|
+
...result.data,
|
|
1545
|
+
description: result.data.description || ""
|
|
1523
1546
|
};
|
|
1524
1547
|
} catch (error) {
|
|
1525
1548
|
throw new Error(`Failed to parse TOML command file: ${error}`, { cause: error });
|
|
@@ -1535,9 +1558,12 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
|
|
|
1535
1558
|
};
|
|
1536
1559
|
}
|
|
1537
1560
|
toRulesyncCommand() {
|
|
1561
|
+
const { description, prompt: _prompt, ...restFields } = this.frontmatter;
|
|
1538
1562
|
const rulesyncFrontmatter = {
|
|
1539
1563
|
targets: ["geminicli"],
|
|
1540
|
-
description:
|
|
1564
|
+
description: description ?? "",
|
|
1565
|
+
// Preserve extra fields in geminicli section (excluding prompt which is the body)
|
|
1566
|
+
...Object.keys(restFields).length > 0 && { geminicli: restFields }
|
|
1541
1567
|
};
|
|
1542
1568
|
const fileContent = stringifyFrontmatter(this.body, rulesyncFrontmatter);
|
|
1543
1569
|
return new RulesyncCommand({
|
|
@@ -1558,9 +1584,11 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
|
|
|
1558
1584
|
global = false
|
|
1559
1585
|
}) {
|
|
1560
1586
|
const rulesyncFrontmatter = rulesyncCommand.getFrontmatter();
|
|
1587
|
+
const geminicliFields = rulesyncFrontmatter.geminicli ?? {};
|
|
1561
1588
|
const geminiFrontmatter = {
|
|
1562
1589
|
description: rulesyncFrontmatter.description,
|
|
1563
|
-
prompt: rulesyncCommand.getBody()
|
|
1590
|
+
prompt: rulesyncCommand.getBody(),
|
|
1591
|
+
...geminicliFields
|
|
1564
1592
|
};
|
|
1565
1593
|
const tomlContent = `description = "${geminiFrontmatter.description}"
|
|
1566
1594
|
prompt = """
|
|
@@ -1611,7 +1639,7 @@ ${geminiFrontmatter.prompt}
|
|
|
1611
1639
|
// src/features/commands/roo-command.ts
|
|
1612
1640
|
var import_node_path14 = require("path");
|
|
1613
1641
|
var import_mini10 = require("zod/mini");
|
|
1614
|
-
var RooCommandFrontmatterSchema = import_mini10.z.
|
|
1642
|
+
var RooCommandFrontmatterSchema = import_mini10.z.looseObject({
|
|
1615
1643
|
description: import_mini10.z.string(),
|
|
1616
1644
|
"argument-hint": (0, import_mini10.optional)(import_mini10.z.string())
|
|
1617
1645
|
});
|
|
@@ -1646,9 +1674,12 @@ var RooCommand = class _RooCommand extends ToolCommand {
|
|
|
1646
1674
|
return this.frontmatter;
|
|
1647
1675
|
}
|
|
1648
1676
|
toRulesyncCommand() {
|
|
1677
|
+
const { description, ...restFields } = this.frontmatter;
|
|
1649
1678
|
const rulesyncFrontmatter = {
|
|
1650
1679
|
targets: ["roo"],
|
|
1651
|
-
description
|
|
1680
|
+
description,
|
|
1681
|
+
// Preserve extra fields in roo section
|
|
1682
|
+
...Object.keys(restFields).length > 0 && { roo: restFields }
|
|
1652
1683
|
};
|
|
1653
1684
|
const fileContent = stringifyFrontmatter(this.body, rulesyncFrontmatter);
|
|
1654
1685
|
return new RulesyncCommand({
|
|
@@ -1668,8 +1699,10 @@ var RooCommand = class _RooCommand extends ToolCommand {
|
|
|
1668
1699
|
validate = true
|
|
1669
1700
|
}) {
|
|
1670
1701
|
const rulesyncFrontmatter = rulesyncCommand.getFrontmatter();
|
|
1702
|
+
const rooFields = rulesyncFrontmatter.roo ?? {};
|
|
1671
1703
|
const rooFrontmatter = {
|
|
1672
|
-
description: rulesyncFrontmatter.description
|
|
1704
|
+
description: rulesyncFrontmatter.description,
|
|
1705
|
+
...rooFields
|
|
1673
1706
|
};
|
|
1674
1707
|
const body = rulesyncCommand.getBody();
|
|
1675
1708
|
const fileContent = stringifyFrontmatter(body, rooFrontmatter);
|
|
@@ -2304,6 +2337,13 @@ var ClaudecodeIgnore = class _ClaudecodeIgnore extends ToolIgnore {
|
|
|
2304
2337
|
relativeFilePath: "settings.local.json"
|
|
2305
2338
|
};
|
|
2306
2339
|
}
|
|
2340
|
+
/**
|
|
2341
|
+
* ClaudecodeIgnore uses settings.local.json which is a user-managed config file.
|
|
2342
|
+
* It should not be deleted by rulesync.
|
|
2343
|
+
*/
|
|
2344
|
+
isDeletable() {
|
|
2345
|
+
return false;
|
|
2346
|
+
}
|
|
2307
2347
|
toRulesyncIgnore() {
|
|
2308
2348
|
const rulesyncPatterns = this.patterns.map((pattern) => {
|
|
2309
2349
|
if (pattern.startsWith("Read(") && pattern.endsWith(")")) {
|
|
@@ -2794,7 +2834,7 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
2794
2834
|
try {
|
|
2795
2835
|
const toolIgnores = await this.loadToolIgnores();
|
|
2796
2836
|
if (forDeletion) {
|
|
2797
|
-
return toolIgnores.filter((toolFile) =>
|
|
2837
|
+
return toolIgnores.filter((toolFile) => toolFile.isDeletable());
|
|
2798
2838
|
}
|
|
2799
2839
|
return toolIgnores;
|
|
2800
2840
|
} catch (error) {
|
|
@@ -3296,6 +3336,14 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
|
|
|
3296
3336
|
getJson() {
|
|
3297
3337
|
return this.json;
|
|
3298
3338
|
}
|
|
3339
|
+
/**
|
|
3340
|
+
* In global mode, ~/.claude/.claude.json should not be deleted
|
|
3341
|
+
* as it may contain other user settings.
|
|
3342
|
+
* In local mode, .mcp.json can be safely deleted.
|
|
3343
|
+
*/
|
|
3344
|
+
isDeletable() {
|
|
3345
|
+
return !this.global;
|
|
3346
|
+
}
|
|
3299
3347
|
static getSettablePaths({ global } = {}) {
|
|
3300
3348
|
if (global) {
|
|
3301
3349
|
return {
|
|
@@ -3878,6 +3926,12 @@ var OpencodeMcp = class _OpencodeMcp extends ToolMcp {
|
|
|
3878
3926
|
getJson() {
|
|
3879
3927
|
return this.json;
|
|
3880
3928
|
}
|
|
3929
|
+
/**
|
|
3930
|
+
* opencode.json may contain other settings, so it should not be deleted.
|
|
3931
|
+
*/
|
|
3932
|
+
isDeletable() {
|
|
3933
|
+
return false;
|
|
3934
|
+
}
|
|
3881
3935
|
static getSettablePaths({ global } = {}) {
|
|
3882
3936
|
if (global) {
|
|
3883
3937
|
return {
|
|
@@ -4162,11 +4216,7 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
4162
4216
|
})();
|
|
4163
4217
|
logger.info(`Successfully loaded ${toolMcps.length} ${this.toolTarget} MCP files`);
|
|
4164
4218
|
if (forDeletion) {
|
|
4165
|
-
|
|
4166
|
-
if (this.global) {
|
|
4167
|
-
filteredMcps = filteredMcps.filter((toolFile) => !(toolFile instanceof ClaudecodeMcp));
|
|
4168
|
-
}
|
|
4169
|
-
return filteredMcps;
|
|
4219
|
+
return toolMcps.filter((toolFile) => toolFile.isDeletable());
|
|
4170
4220
|
}
|
|
4171
4221
|
return toolMcps;
|
|
4172
4222
|
} catch (error) {
|
|
@@ -4547,20 +4597,13 @@ var SimulatedSkill = class extends ToolSkill {
|
|
|
4547
4597
|
name: rulesyncFrontmatter.name,
|
|
4548
4598
|
description: rulesyncFrontmatter.description
|
|
4549
4599
|
};
|
|
4550
|
-
const otherFiles = rulesyncSkill.getOtherFiles();
|
|
4551
|
-
if (otherFiles.length > 0) {
|
|
4552
|
-
logger.warn(
|
|
4553
|
-
`Skill "${rulesyncFrontmatter.name}" has ${otherFiles.length} additional file(s) that will be ignored for simulated skill generation.`
|
|
4554
|
-
);
|
|
4555
|
-
}
|
|
4556
4600
|
return {
|
|
4557
4601
|
baseDir: rulesyncSkill.getBaseDir(),
|
|
4558
4602
|
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
4559
4603
|
dirName: rulesyncSkill.getDirName(),
|
|
4560
4604
|
frontmatter: simulatedFrontmatter,
|
|
4561
4605
|
body: rulesyncSkill.getBody(),
|
|
4562
|
-
otherFiles:
|
|
4563
|
-
// Simulated skills ignore otherFiles
|
|
4606
|
+
otherFiles: rulesyncSkill.getOtherFiles(),
|
|
4564
4607
|
validate
|
|
4565
4608
|
};
|
|
4566
4609
|
}
|
|
@@ -4582,14 +4625,19 @@ var SimulatedSkill = class extends ToolSkill {
|
|
|
4582
4625
|
if (!result.success) {
|
|
4583
4626
|
throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
|
|
4584
4627
|
}
|
|
4628
|
+
const otherFiles = await this.collectOtherFiles(
|
|
4629
|
+
baseDir,
|
|
4630
|
+
actualRelativeDirPath,
|
|
4631
|
+
dirName,
|
|
4632
|
+
SKILL_FILE_NAME
|
|
4633
|
+
);
|
|
4585
4634
|
return {
|
|
4586
4635
|
baseDir,
|
|
4587
4636
|
relativeDirPath: actualRelativeDirPath,
|
|
4588
4637
|
dirName,
|
|
4589
4638
|
frontmatter: result.data,
|
|
4590
4639
|
body: content.trim(),
|
|
4591
|
-
otherFiles
|
|
4592
|
-
// Simulated skills ignore otherFiles
|
|
4640
|
+
otherFiles,
|
|
4593
4641
|
validate: true
|
|
4594
4642
|
};
|
|
4595
4643
|
}
|
|
@@ -5603,16 +5651,10 @@ var import_mini24 = require("zod/mini");
|
|
|
5603
5651
|
// src/features/subagents/rulesync-subagent.ts
|
|
5604
5652
|
var import_node_path58 = require("path");
|
|
5605
5653
|
var import_mini23 = require("zod/mini");
|
|
5606
|
-
var
|
|
5607
|
-
var RulesyncSubagentFrontmatterSchema = import_mini23.z.object({
|
|
5654
|
+
var RulesyncSubagentFrontmatterSchema = import_mini23.z.looseObject({
|
|
5608
5655
|
targets: RulesyncTargetsSchema,
|
|
5609
5656
|
name: import_mini23.z.string(),
|
|
5610
|
-
description: import_mini23.z.string()
|
|
5611
|
-
claudecode: import_mini23.z.optional(
|
|
5612
|
-
import_mini23.z.object({
|
|
5613
|
-
model: RulesyncSubagentModelSchema
|
|
5614
|
-
})
|
|
5615
|
-
)
|
|
5657
|
+
description: import_mini23.z.string()
|
|
5616
5658
|
});
|
|
5617
5659
|
var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
5618
5660
|
frontmatter;
|
|
@@ -5683,7 +5725,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
5683
5725
|
};
|
|
5684
5726
|
|
|
5685
5727
|
// src/features/subagents/claudecode-subagent.ts
|
|
5686
|
-
var ClaudecodeSubagentFrontmatterSchema = import_mini24.z.
|
|
5728
|
+
var ClaudecodeSubagentFrontmatterSchema = import_mini24.z.looseObject({
|
|
5687
5729
|
name: import_mini24.z.string(),
|
|
5688
5730
|
description: import_mini24.z.string(),
|
|
5689
5731
|
model: import_mini24.z.optional(import_mini24.z.enum(["opus", "sonnet", "haiku", "inherit"]))
|
|
@@ -5718,15 +5760,17 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
5718
5760
|
return this.body;
|
|
5719
5761
|
}
|
|
5720
5762
|
toRulesyncSubagent() {
|
|
5763
|
+
const { name, description, model, ...restFields } = this.frontmatter;
|
|
5764
|
+
const claudecodeSection = {
|
|
5765
|
+
...model && { model },
|
|
5766
|
+
...restFields
|
|
5767
|
+
};
|
|
5721
5768
|
const rulesyncFrontmatter = {
|
|
5722
5769
|
targets: ["claudecode"],
|
|
5723
|
-
name
|
|
5724
|
-
description
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
model: this.frontmatter.model
|
|
5728
|
-
}
|
|
5729
|
-
}
|
|
5770
|
+
name,
|
|
5771
|
+
description,
|
|
5772
|
+
// Only include claudecode section if there are fields
|
|
5773
|
+
...Object.keys(claudecodeSection).length > 0 && { claudecode: claudecodeSection }
|
|
5730
5774
|
};
|
|
5731
5775
|
return new RulesyncSubagent({
|
|
5732
5776
|
baseDir: ".",
|
|
@@ -5745,11 +5789,17 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
5745
5789
|
global = false
|
|
5746
5790
|
}) {
|
|
5747
5791
|
const rulesyncFrontmatter = rulesyncSubagent.getFrontmatter();
|
|
5748
|
-
const
|
|
5792
|
+
const claudecodeSection = rulesyncFrontmatter.claudecode ?? {};
|
|
5793
|
+
const rawClaudecodeFrontmatter = {
|
|
5749
5794
|
name: rulesyncFrontmatter.name,
|
|
5750
5795
|
description: rulesyncFrontmatter.description,
|
|
5751
|
-
|
|
5796
|
+
...claudecodeSection
|
|
5752
5797
|
};
|
|
5798
|
+
const result = ClaudecodeSubagentFrontmatterSchema.safeParse(rawClaudecodeFrontmatter);
|
|
5799
|
+
if (!result.success) {
|
|
5800
|
+
throw new Error(`Invalid claudecode subagent frontmatter: ${formatError(result.error)}`);
|
|
5801
|
+
}
|
|
5802
|
+
const claudecodeFrontmatter = result.data;
|
|
5753
5803
|
const body = rulesyncSubagent.getBody();
|
|
5754
5804
|
const fileContent = stringifyFrontmatter(body, claudecodeFrontmatter);
|
|
5755
5805
|
const paths = this.getSettablePaths({ global });
|
|
@@ -8638,7 +8688,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
8638
8688
|
`@${rule.getRelativePathFromCwd()} description: "${escapedDescription}" globs: "${globsText}"`
|
|
8639
8689
|
);
|
|
8640
8690
|
}
|
|
8641
|
-
return lines.join("\n") + "\n";
|
|
8691
|
+
return lines.join("\n") + "\n\n";
|
|
8642
8692
|
}
|
|
8643
8693
|
generateAdditionalConventionsSection({
|
|
8644
8694
|
commands,
|
|
@@ -10218,7 +10268,7 @@ async function mcpCommand({ version }) {
|
|
|
10218
10268
|
}
|
|
10219
10269
|
|
|
10220
10270
|
// src/cli/index.ts
|
|
10221
|
-
var getVersion = () => "3.28.
|
|
10271
|
+
var getVersion = () => "3.28.2";
|
|
10222
10272
|
var main = async () => {
|
|
10223
10273
|
const program = new import_commander.Command();
|
|
10224
10274
|
const version = getVersion();
|
package/dist/index.js
CHANGED
|
@@ -267,6 +267,10 @@ var ConfigParamsSchema = z3.object({
|
|
|
267
267
|
experimentalSimulateSubagents: optional(z3.boolean())
|
|
268
268
|
});
|
|
269
269
|
var PartialConfigParamsSchema = z3.partial(ConfigParamsSchema);
|
|
270
|
+
var ConfigFileSchema = z3.object({
|
|
271
|
+
$schema: optional(z3.string()),
|
|
272
|
+
...z3.partial(ConfigParamsSchema).shape
|
|
273
|
+
});
|
|
270
274
|
var RequiredConfigParamsSchema = z3.required(ConfigParamsSchema);
|
|
271
275
|
var Config = class {
|
|
272
276
|
baseDirs;
|
|
@@ -396,7 +400,9 @@ var ConfigResolver = class {
|
|
|
396
400
|
try {
|
|
397
401
|
const fileContent = await readFileContent(validatedConfigPath);
|
|
398
402
|
const jsonData = parseJsonc(fileContent);
|
|
399
|
-
|
|
403
|
+
const parsed = ConfigFileSchema.parse(jsonData);
|
|
404
|
+
const { $schema: _schema, ...configParams2 } = parsed;
|
|
405
|
+
configByFile = configParams2;
|
|
400
406
|
} catch (error) {
|
|
401
407
|
logger.error(`Failed to load config file: ${formatError(error)}`);
|
|
402
408
|
throw error;
|
|
@@ -642,6 +648,13 @@ var AiFile = class {
|
|
|
642
648
|
setFileContent(newFileContent) {
|
|
643
649
|
this.fileContent = newFileContent;
|
|
644
650
|
}
|
|
651
|
+
/**
|
|
652
|
+
* Returns whether this file can be deleted by rulesync.
|
|
653
|
+
* Override in subclasses that should not be deleted (e.g., user-managed config files).
|
|
654
|
+
*/
|
|
655
|
+
isDeletable() {
|
|
656
|
+
return true;
|
|
657
|
+
}
|
|
645
658
|
};
|
|
646
659
|
|
|
647
660
|
// src/features/commands/tool-command.ts
|
|
@@ -876,7 +889,7 @@ var RulesyncFile = class extends AiFile {
|
|
|
876
889
|
};
|
|
877
890
|
|
|
878
891
|
// src/features/commands/rulesync-command.ts
|
|
879
|
-
var RulesyncCommandFrontmatterSchema = z5.
|
|
892
|
+
var RulesyncCommandFrontmatterSchema = z5.looseObject({
|
|
880
893
|
targets: RulesyncTargetsSchema,
|
|
881
894
|
description: z5.string()
|
|
882
895
|
});
|
|
@@ -1077,7 +1090,7 @@ var AntigravityCommand = class _AntigravityCommand extends ToolCommand {
|
|
|
1077
1090
|
// src/features/commands/claudecode-command.ts
|
|
1078
1091
|
import { basename as basename6, join as join7 } from "path";
|
|
1079
1092
|
import { z as z7 } from "zod/mini";
|
|
1080
|
-
var ClaudecodeCommandFrontmatterSchema = z7.
|
|
1093
|
+
var ClaudecodeCommandFrontmatterSchema = z7.looseObject({
|
|
1081
1094
|
description: z7.string()
|
|
1082
1095
|
});
|
|
1083
1096
|
var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
@@ -1111,9 +1124,12 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
|
1111
1124
|
return this.frontmatter;
|
|
1112
1125
|
}
|
|
1113
1126
|
toRulesyncCommand() {
|
|
1127
|
+
const { description, ...restFields } = this.frontmatter;
|
|
1114
1128
|
const rulesyncFrontmatter = {
|
|
1115
1129
|
targets: ["*"],
|
|
1116
|
-
description
|
|
1130
|
+
description,
|
|
1131
|
+
// Preserve extra fields in claudecode section
|
|
1132
|
+
...Object.keys(restFields).length > 0 && { claudecode: restFields }
|
|
1117
1133
|
};
|
|
1118
1134
|
const fileContent = stringifyFrontmatter(this.body, rulesyncFrontmatter);
|
|
1119
1135
|
return new RulesyncCommand({
|
|
@@ -1134,8 +1150,10 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
|
1134
1150
|
global = false
|
|
1135
1151
|
}) {
|
|
1136
1152
|
const rulesyncFrontmatter = rulesyncCommand.getFrontmatter();
|
|
1153
|
+
const claudecodeFields = rulesyncFrontmatter.claudecode ?? {};
|
|
1137
1154
|
const claudecodeFrontmatter = {
|
|
1138
|
-
description: rulesyncFrontmatter.description
|
|
1155
|
+
description: rulesyncFrontmatter.description,
|
|
1156
|
+
...claudecodeFields
|
|
1139
1157
|
};
|
|
1140
1158
|
const body = rulesyncCommand.getBody();
|
|
1141
1159
|
const paths = this.getSettablePaths({ global });
|
|
@@ -1272,7 +1290,7 @@ var CodexcliCommand = class _CodexcliCommand extends ToolCommand {
|
|
|
1272
1290
|
// src/features/commands/copilot-command.ts
|
|
1273
1291
|
import { basename as basename8, join as join9 } from "path";
|
|
1274
1292
|
import { z as z8 } from "zod/mini";
|
|
1275
|
-
var CopilotCommandFrontmatterSchema = z8.
|
|
1293
|
+
var CopilotCommandFrontmatterSchema = z8.looseObject({
|
|
1276
1294
|
mode: z8.literal("agent"),
|
|
1277
1295
|
description: z8.string()
|
|
1278
1296
|
});
|
|
@@ -1307,9 +1325,12 @@ var CopilotCommand = class _CopilotCommand extends ToolCommand {
|
|
|
1307
1325
|
return this.frontmatter;
|
|
1308
1326
|
}
|
|
1309
1327
|
toRulesyncCommand() {
|
|
1328
|
+
const { mode: _mode, description, ...restFields } = this.frontmatter;
|
|
1310
1329
|
const rulesyncFrontmatter = {
|
|
1311
1330
|
targets: ["*"],
|
|
1312
|
-
description
|
|
1331
|
+
description,
|
|
1332
|
+
// Preserve extra fields in copilot section (excluding mode which is fixed)
|
|
1333
|
+
...Object.keys(restFields).length > 0 && { copilot: restFields }
|
|
1313
1334
|
};
|
|
1314
1335
|
const originalFilePath = this.relativeFilePath;
|
|
1315
1336
|
const relativeFilePath = originalFilePath.replace(/\.prompt\.md$/, ".md");
|
|
@@ -1346,9 +1367,11 @@ var CopilotCommand = class _CopilotCommand extends ToolCommand {
|
|
|
1346
1367
|
}) {
|
|
1347
1368
|
const paths = this.getSettablePaths();
|
|
1348
1369
|
const rulesyncFrontmatter = rulesyncCommand.getFrontmatter();
|
|
1370
|
+
const copilotFields = rulesyncFrontmatter.copilot ?? {};
|
|
1349
1371
|
const copilotFrontmatter = {
|
|
1350
1372
|
mode: "agent",
|
|
1351
|
-
description: rulesyncFrontmatter.description
|
|
1373
|
+
description: rulesyncFrontmatter.description,
|
|
1374
|
+
...copilotFields
|
|
1352
1375
|
};
|
|
1353
1376
|
const body = rulesyncCommand.getBody();
|
|
1354
1377
|
const originalFilePath = rulesyncCommand.getRelativeFilePath();
|
|
@@ -1467,7 +1490,7 @@ var CursorCommand = class _CursorCommand extends ToolCommand {
|
|
|
1467
1490
|
import { basename as basename10, join as join11 } from "path";
|
|
1468
1491
|
import { parse as parseToml } from "smol-toml";
|
|
1469
1492
|
import { z as z9 } from "zod/mini";
|
|
1470
|
-
var GeminiCliCommandFrontmatterSchema = z9.
|
|
1493
|
+
var GeminiCliCommandFrontmatterSchema = z9.looseObject({
|
|
1471
1494
|
description: z9.optional(z9.string()),
|
|
1472
1495
|
prompt: z9.string()
|
|
1473
1496
|
});
|
|
@@ -1495,8 +1518,8 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
|
|
|
1495
1518
|
);
|
|
1496
1519
|
}
|
|
1497
1520
|
return {
|
|
1498
|
-
|
|
1499
|
-
|
|
1521
|
+
...result.data,
|
|
1522
|
+
description: result.data.description || ""
|
|
1500
1523
|
};
|
|
1501
1524
|
} catch (error) {
|
|
1502
1525
|
throw new Error(`Failed to parse TOML command file: ${error}`, { cause: error });
|
|
@@ -1512,9 +1535,12 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
|
|
|
1512
1535
|
};
|
|
1513
1536
|
}
|
|
1514
1537
|
toRulesyncCommand() {
|
|
1538
|
+
const { description, prompt: _prompt, ...restFields } = this.frontmatter;
|
|
1515
1539
|
const rulesyncFrontmatter = {
|
|
1516
1540
|
targets: ["geminicli"],
|
|
1517
|
-
description:
|
|
1541
|
+
description: description ?? "",
|
|
1542
|
+
// Preserve extra fields in geminicli section (excluding prompt which is the body)
|
|
1543
|
+
...Object.keys(restFields).length > 0 && { geminicli: restFields }
|
|
1518
1544
|
};
|
|
1519
1545
|
const fileContent = stringifyFrontmatter(this.body, rulesyncFrontmatter);
|
|
1520
1546
|
return new RulesyncCommand({
|
|
@@ -1535,9 +1561,11 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
|
|
|
1535
1561
|
global = false
|
|
1536
1562
|
}) {
|
|
1537
1563
|
const rulesyncFrontmatter = rulesyncCommand.getFrontmatter();
|
|
1564
|
+
const geminicliFields = rulesyncFrontmatter.geminicli ?? {};
|
|
1538
1565
|
const geminiFrontmatter = {
|
|
1539
1566
|
description: rulesyncFrontmatter.description,
|
|
1540
|
-
prompt: rulesyncCommand.getBody()
|
|
1567
|
+
prompt: rulesyncCommand.getBody(),
|
|
1568
|
+
...geminicliFields
|
|
1541
1569
|
};
|
|
1542
1570
|
const tomlContent = `description = "${geminiFrontmatter.description}"
|
|
1543
1571
|
prompt = """
|
|
@@ -1588,7 +1616,7 @@ ${geminiFrontmatter.prompt}
|
|
|
1588
1616
|
// src/features/commands/roo-command.ts
|
|
1589
1617
|
import { basename as basename11, join as join12 } from "path";
|
|
1590
1618
|
import { optional as optional2, z as z10 } from "zod/mini";
|
|
1591
|
-
var RooCommandFrontmatterSchema = z10.
|
|
1619
|
+
var RooCommandFrontmatterSchema = z10.looseObject({
|
|
1592
1620
|
description: z10.string(),
|
|
1593
1621
|
"argument-hint": optional2(z10.string())
|
|
1594
1622
|
});
|
|
@@ -1623,9 +1651,12 @@ var RooCommand = class _RooCommand extends ToolCommand {
|
|
|
1623
1651
|
return this.frontmatter;
|
|
1624
1652
|
}
|
|
1625
1653
|
toRulesyncCommand() {
|
|
1654
|
+
const { description, ...restFields } = this.frontmatter;
|
|
1626
1655
|
const rulesyncFrontmatter = {
|
|
1627
1656
|
targets: ["roo"],
|
|
1628
|
-
description
|
|
1657
|
+
description,
|
|
1658
|
+
// Preserve extra fields in roo section
|
|
1659
|
+
...Object.keys(restFields).length > 0 && { roo: restFields }
|
|
1629
1660
|
};
|
|
1630
1661
|
const fileContent = stringifyFrontmatter(this.body, rulesyncFrontmatter);
|
|
1631
1662
|
return new RulesyncCommand({
|
|
@@ -1645,8 +1676,10 @@ var RooCommand = class _RooCommand extends ToolCommand {
|
|
|
1645
1676
|
validate = true
|
|
1646
1677
|
}) {
|
|
1647
1678
|
const rulesyncFrontmatter = rulesyncCommand.getFrontmatter();
|
|
1679
|
+
const rooFields = rulesyncFrontmatter.roo ?? {};
|
|
1648
1680
|
const rooFrontmatter = {
|
|
1649
|
-
description: rulesyncFrontmatter.description
|
|
1681
|
+
description: rulesyncFrontmatter.description,
|
|
1682
|
+
...rooFields
|
|
1650
1683
|
};
|
|
1651
1684
|
const body = rulesyncCommand.getBody();
|
|
1652
1685
|
const fileContent = stringifyFrontmatter(body, rooFrontmatter);
|
|
@@ -2281,6 +2314,13 @@ var ClaudecodeIgnore = class _ClaudecodeIgnore extends ToolIgnore {
|
|
|
2281
2314
|
relativeFilePath: "settings.local.json"
|
|
2282
2315
|
};
|
|
2283
2316
|
}
|
|
2317
|
+
/**
|
|
2318
|
+
* ClaudecodeIgnore uses settings.local.json which is a user-managed config file.
|
|
2319
|
+
* It should not be deleted by rulesync.
|
|
2320
|
+
*/
|
|
2321
|
+
isDeletable() {
|
|
2322
|
+
return false;
|
|
2323
|
+
}
|
|
2284
2324
|
toRulesyncIgnore() {
|
|
2285
2325
|
const rulesyncPatterns = this.patterns.map((pattern) => {
|
|
2286
2326
|
if (pattern.startsWith("Read(") && pattern.endsWith(")")) {
|
|
@@ -2771,7 +2811,7 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
2771
2811
|
try {
|
|
2772
2812
|
const toolIgnores = await this.loadToolIgnores();
|
|
2773
2813
|
if (forDeletion) {
|
|
2774
|
-
return toolIgnores.filter((toolFile) =>
|
|
2814
|
+
return toolIgnores.filter((toolFile) => toolFile.isDeletable());
|
|
2775
2815
|
}
|
|
2776
2816
|
return toolIgnores;
|
|
2777
2817
|
} catch (error) {
|
|
@@ -3273,6 +3313,14 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
|
|
|
3273
3313
|
getJson() {
|
|
3274
3314
|
return this.json;
|
|
3275
3315
|
}
|
|
3316
|
+
/**
|
|
3317
|
+
* In global mode, ~/.claude/.claude.json should not be deleted
|
|
3318
|
+
* as it may contain other user settings.
|
|
3319
|
+
* In local mode, .mcp.json can be safely deleted.
|
|
3320
|
+
*/
|
|
3321
|
+
isDeletable() {
|
|
3322
|
+
return !this.global;
|
|
3323
|
+
}
|
|
3276
3324
|
static getSettablePaths({ global } = {}) {
|
|
3277
3325
|
if (global) {
|
|
3278
3326
|
return {
|
|
@@ -3855,6 +3903,12 @@ var OpencodeMcp = class _OpencodeMcp extends ToolMcp {
|
|
|
3855
3903
|
getJson() {
|
|
3856
3904
|
return this.json;
|
|
3857
3905
|
}
|
|
3906
|
+
/**
|
|
3907
|
+
* opencode.json may contain other settings, so it should not be deleted.
|
|
3908
|
+
*/
|
|
3909
|
+
isDeletable() {
|
|
3910
|
+
return false;
|
|
3911
|
+
}
|
|
3858
3912
|
static getSettablePaths({ global } = {}) {
|
|
3859
3913
|
if (global) {
|
|
3860
3914
|
return {
|
|
@@ -4139,11 +4193,7 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
4139
4193
|
})();
|
|
4140
4194
|
logger.info(`Successfully loaded ${toolMcps.length} ${this.toolTarget} MCP files`);
|
|
4141
4195
|
if (forDeletion) {
|
|
4142
|
-
|
|
4143
|
-
if (this.global) {
|
|
4144
|
-
filteredMcps = filteredMcps.filter((toolFile) => !(toolFile instanceof ClaudecodeMcp));
|
|
4145
|
-
}
|
|
4146
|
-
return filteredMcps;
|
|
4196
|
+
return toolMcps.filter((toolFile) => toolFile.isDeletable());
|
|
4147
4197
|
}
|
|
4148
4198
|
return toolMcps;
|
|
4149
4199
|
} catch (error) {
|
|
@@ -4524,20 +4574,13 @@ var SimulatedSkill = class extends ToolSkill {
|
|
|
4524
4574
|
name: rulesyncFrontmatter.name,
|
|
4525
4575
|
description: rulesyncFrontmatter.description
|
|
4526
4576
|
};
|
|
4527
|
-
const otherFiles = rulesyncSkill.getOtherFiles();
|
|
4528
|
-
if (otherFiles.length > 0) {
|
|
4529
|
-
logger.warn(
|
|
4530
|
-
`Skill "${rulesyncFrontmatter.name}" has ${otherFiles.length} additional file(s) that will be ignored for simulated skill generation.`
|
|
4531
|
-
);
|
|
4532
|
-
}
|
|
4533
4577
|
return {
|
|
4534
4578
|
baseDir: rulesyncSkill.getBaseDir(),
|
|
4535
4579
|
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
4536
4580
|
dirName: rulesyncSkill.getDirName(),
|
|
4537
4581
|
frontmatter: simulatedFrontmatter,
|
|
4538
4582
|
body: rulesyncSkill.getBody(),
|
|
4539
|
-
otherFiles:
|
|
4540
|
-
// Simulated skills ignore otherFiles
|
|
4583
|
+
otherFiles: rulesyncSkill.getOtherFiles(),
|
|
4541
4584
|
validate
|
|
4542
4585
|
};
|
|
4543
4586
|
}
|
|
@@ -4559,14 +4602,19 @@ var SimulatedSkill = class extends ToolSkill {
|
|
|
4559
4602
|
if (!result.success) {
|
|
4560
4603
|
throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
|
|
4561
4604
|
}
|
|
4605
|
+
const otherFiles = await this.collectOtherFiles(
|
|
4606
|
+
baseDir,
|
|
4607
|
+
actualRelativeDirPath,
|
|
4608
|
+
dirName,
|
|
4609
|
+
SKILL_FILE_NAME
|
|
4610
|
+
);
|
|
4562
4611
|
return {
|
|
4563
4612
|
baseDir,
|
|
4564
4613
|
relativeDirPath: actualRelativeDirPath,
|
|
4565
4614
|
dirName,
|
|
4566
4615
|
frontmatter: result.data,
|
|
4567
4616
|
body: content.trim(),
|
|
4568
|
-
otherFiles
|
|
4569
|
-
// Simulated skills ignore otherFiles
|
|
4617
|
+
otherFiles,
|
|
4570
4618
|
validate: true
|
|
4571
4619
|
};
|
|
4572
4620
|
}
|
|
@@ -5580,16 +5628,10 @@ import { z as z24 } from "zod/mini";
|
|
|
5580
5628
|
// src/features/subagents/rulesync-subagent.ts
|
|
5581
5629
|
import { basename as basename16, join as join56 } from "path";
|
|
5582
5630
|
import { z as z23 } from "zod/mini";
|
|
5583
|
-
var
|
|
5584
|
-
var RulesyncSubagentFrontmatterSchema = z23.object({
|
|
5631
|
+
var RulesyncSubagentFrontmatterSchema = z23.looseObject({
|
|
5585
5632
|
targets: RulesyncTargetsSchema,
|
|
5586
5633
|
name: z23.string(),
|
|
5587
|
-
description: z23.string()
|
|
5588
|
-
claudecode: z23.optional(
|
|
5589
|
-
z23.object({
|
|
5590
|
-
model: RulesyncSubagentModelSchema
|
|
5591
|
-
})
|
|
5592
|
-
)
|
|
5634
|
+
description: z23.string()
|
|
5593
5635
|
});
|
|
5594
5636
|
var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
5595
5637
|
frontmatter;
|
|
@@ -5660,7 +5702,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
5660
5702
|
};
|
|
5661
5703
|
|
|
5662
5704
|
// src/features/subagents/claudecode-subagent.ts
|
|
5663
|
-
var ClaudecodeSubagentFrontmatterSchema = z24.
|
|
5705
|
+
var ClaudecodeSubagentFrontmatterSchema = z24.looseObject({
|
|
5664
5706
|
name: z24.string(),
|
|
5665
5707
|
description: z24.string(),
|
|
5666
5708
|
model: z24.optional(z24.enum(["opus", "sonnet", "haiku", "inherit"]))
|
|
@@ -5695,15 +5737,17 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
5695
5737
|
return this.body;
|
|
5696
5738
|
}
|
|
5697
5739
|
toRulesyncSubagent() {
|
|
5740
|
+
const { name, description, model, ...restFields } = this.frontmatter;
|
|
5741
|
+
const claudecodeSection = {
|
|
5742
|
+
...model && { model },
|
|
5743
|
+
...restFields
|
|
5744
|
+
};
|
|
5698
5745
|
const rulesyncFrontmatter = {
|
|
5699
5746
|
targets: ["claudecode"],
|
|
5700
|
-
name
|
|
5701
|
-
description
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
model: this.frontmatter.model
|
|
5705
|
-
}
|
|
5706
|
-
}
|
|
5747
|
+
name,
|
|
5748
|
+
description,
|
|
5749
|
+
// Only include claudecode section if there are fields
|
|
5750
|
+
...Object.keys(claudecodeSection).length > 0 && { claudecode: claudecodeSection }
|
|
5707
5751
|
};
|
|
5708
5752
|
return new RulesyncSubagent({
|
|
5709
5753
|
baseDir: ".",
|
|
@@ -5722,11 +5766,17 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
5722
5766
|
global = false
|
|
5723
5767
|
}) {
|
|
5724
5768
|
const rulesyncFrontmatter = rulesyncSubagent.getFrontmatter();
|
|
5725
|
-
const
|
|
5769
|
+
const claudecodeSection = rulesyncFrontmatter.claudecode ?? {};
|
|
5770
|
+
const rawClaudecodeFrontmatter = {
|
|
5726
5771
|
name: rulesyncFrontmatter.name,
|
|
5727
5772
|
description: rulesyncFrontmatter.description,
|
|
5728
|
-
|
|
5773
|
+
...claudecodeSection
|
|
5729
5774
|
};
|
|
5775
|
+
const result = ClaudecodeSubagentFrontmatterSchema.safeParse(rawClaudecodeFrontmatter);
|
|
5776
|
+
if (!result.success) {
|
|
5777
|
+
throw new Error(`Invalid claudecode subagent frontmatter: ${formatError(result.error)}`);
|
|
5778
|
+
}
|
|
5779
|
+
const claudecodeFrontmatter = result.data;
|
|
5730
5780
|
const body = rulesyncSubagent.getBody();
|
|
5731
5781
|
const fileContent = stringifyFrontmatter(body, claudecodeFrontmatter);
|
|
5732
5782
|
const paths = this.getSettablePaths({ global });
|
|
@@ -8615,7 +8665,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
8615
8665
|
`@${rule.getRelativePathFromCwd()} description: "${escapedDescription}" globs: "${globsText}"`
|
|
8616
8666
|
);
|
|
8617
8667
|
}
|
|
8618
|
-
return lines.join("\n") + "\n";
|
|
8668
|
+
return lines.join("\n") + "\n\n";
|
|
8619
8669
|
}
|
|
8620
8670
|
generateAdditionalConventionsSection({
|
|
8621
8671
|
commands,
|
|
@@ -10195,7 +10245,7 @@ async function mcpCommand({ version }) {
|
|
|
10195
10245
|
}
|
|
10196
10246
|
|
|
10197
10247
|
// src/cli/index.ts
|
|
10198
|
-
var getVersion = () => "3.28.
|
|
10248
|
+
var getVersion = () => "3.28.2";
|
|
10199
10249
|
var main = async () => {
|
|
10200
10250
|
const program = new Command();
|
|
10201
10251
|
const version = getVersion();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rulesync",
|
|
3
|
-
"version": "3.28.
|
|
3
|
+
"version": "3.28.2",
|
|
4
4
|
"description": "Unified AI rules management CLI tool that generates configuration files for various AI development tools",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -49,15 +49,15 @@
|
|
|
49
49
|
"zod": "4.1.13"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@anthropic-ai/claude-agent-sdk": "0.1.
|
|
53
|
-
"@biomejs/biome": "2.3.
|
|
52
|
+
"@anthropic-ai/claude-agent-sdk": "0.1.55",
|
|
53
|
+
"@biomejs/biome": "2.3.8",
|
|
54
54
|
"@eslint/js": "9.39.1",
|
|
55
55
|
"@secretlint/secretlint-rule-preset-recommend": "11.2.5",
|
|
56
56
|
"@tsconfig/node24": "24.0.3",
|
|
57
57
|
"@types/js-yaml": "4.0.9",
|
|
58
58
|
"@types/node": "24.10.1",
|
|
59
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
60
|
-
"@vitest/coverage-v8": "4.0.
|
|
59
|
+
"@typescript/native-preview": "7.0.0-dev.20251130.1",
|
|
60
|
+
"@vitest/coverage-v8": "4.0.14",
|
|
61
61
|
"cspell": "9.3.2",
|
|
62
62
|
"eslint": "9.39.1",
|
|
63
63
|
"eslint-plugin-import": "2.32.0",
|
|
@@ -70,12 +70,12 @@
|
|
|
70
70
|
"oxlint": "1.30.0",
|
|
71
71
|
"secretlint": "11.2.5",
|
|
72
72
|
"simple-git-hooks": "2.13.1",
|
|
73
|
-
"sort-package-json": "3.
|
|
73
|
+
"sort-package-json": "3.5.0",
|
|
74
74
|
"tsup": "8.5.1",
|
|
75
|
-
"tsx": "4.
|
|
75
|
+
"tsx": "4.21.0",
|
|
76
76
|
"typescript": "5.9.3",
|
|
77
77
|
"typescript-eslint": "8.48.0",
|
|
78
|
-
"vitest": "4.0.
|
|
78
|
+
"vitest": "4.0.14"
|
|
79
79
|
},
|
|
80
80
|
"engines": {
|
|
81
81
|
"node": ">=22.0.0"
|
|
@@ -98,6 +98,7 @@
|
|
|
98
98
|
"eslint:fix": "eslint . --fix --max-warnings 0 --cache",
|
|
99
99
|
"fix": "pnpm run bcheck:fix && pnpm run oxlint:fix && pnpm run eslint:fix",
|
|
100
100
|
"generate": "pnpm run dev generate",
|
|
101
|
+
"generate:schema": "tsx scripts/generate-json-schema.ts",
|
|
101
102
|
"knip": "knip",
|
|
102
103
|
"oxlint": "oxlint . --max-warnings 0",
|
|
103
104
|
"oxlint:fix": "oxlint . --fix --max-warnings 0",
|