rulesync 3.5.2 → 3.7.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 +2 -1
- package/dist/index.cjs +370 -145
- package/dist/index.js +360 -135
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -3100,8 +3100,82 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
|
|
|
3100
3100
|
}
|
|
3101
3101
|
};
|
|
3102
3102
|
|
|
3103
|
-
// src/mcp/
|
|
3103
|
+
// src/mcp/geminicli-mcp.ts
|
|
3104
3104
|
import { join as join31 } from "path";
|
|
3105
|
+
var GeminiCliMcp = class _GeminiCliMcp extends ToolMcp {
|
|
3106
|
+
json;
|
|
3107
|
+
constructor(params) {
|
|
3108
|
+
super(params);
|
|
3109
|
+
this.json = JSON.parse(this.fileContent || "{}");
|
|
3110
|
+
}
|
|
3111
|
+
getJson() {
|
|
3112
|
+
return this.json;
|
|
3113
|
+
}
|
|
3114
|
+
static getSettablePaths({ global } = {}) {
|
|
3115
|
+
if (global) {
|
|
3116
|
+
return {
|
|
3117
|
+
relativeDirPath: ".gemini",
|
|
3118
|
+
relativeFilePath: "settings.json"
|
|
3119
|
+
};
|
|
3120
|
+
}
|
|
3121
|
+
return {
|
|
3122
|
+
relativeDirPath: ".gemini",
|
|
3123
|
+
relativeFilePath: "settings.json"
|
|
3124
|
+
};
|
|
3125
|
+
}
|
|
3126
|
+
static async fromFile({
|
|
3127
|
+
baseDir = ".",
|
|
3128
|
+
validate = true,
|
|
3129
|
+
global = false
|
|
3130
|
+
}) {
|
|
3131
|
+
const paths = this.getSettablePaths({ global });
|
|
3132
|
+
const fileContent = await readOrInitializeFileContent(
|
|
3133
|
+
join31(baseDir, paths.relativeDirPath, paths.relativeFilePath),
|
|
3134
|
+
JSON.stringify({ mcpServers: {} }, null, 2)
|
|
3135
|
+
);
|
|
3136
|
+
const json = JSON.parse(fileContent);
|
|
3137
|
+
const newJson = { ...json, mcpServers: json.mcpServers ?? {} };
|
|
3138
|
+
return new _GeminiCliMcp({
|
|
3139
|
+
baseDir,
|
|
3140
|
+
relativeDirPath: paths.relativeDirPath,
|
|
3141
|
+
relativeFilePath: paths.relativeFilePath,
|
|
3142
|
+
fileContent: JSON.stringify(newJson, null, 2),
|
|
3143
|
+
validate
|
|
3144
|
+
});
|
|
3145
|
+
}
|
|
3146
|
+
static async fromRulesyncMcp({
|
|
3147
|
+
baseDir = ".",
|
|
3148
|
+
rulesyncMcp,
|
|
3149
|
+
validate = true,
|
|
3150
|
+
global = false
|
|
3151
|
+
}) {
|
|
3152
|
+
const paths = this.getSettablePaths({ global });
|
|
3153
|
+
const fileContent = await readOrInitializeFileContent(
|
|
3154
|
+
join31(baseDir, paths.relativeDirPath, paths.relativeFilePath),
|
|
3155
|
+
JSON.stringify({ mcpServers: {} }, null, 2)
|
|
3156
|
+
);
|
|
3157
|
+
const json = JSON.parse(fileContent);
|
|
3158
|
+
const newJson = { ...json, mcpServers: rulesyncMcp.getJson().mcpServers };
|
|
3159
|
+
return new _GeminiCliMcp({
|
|
3160
|
+
baseDir,
|
|
3161
|
+
relativeDirPath: paths.relativeDirPath,
|
|
3162
|
+
relativeFilePath: paths.relativeFilePath,
|
|
3163
|
+
fileContent: JSON.stringify(newJson, null, 2),
|
|
3164
|
+
validate
|
|
3165
|
+
});
|
|
3166
|
+
}
|
|
3167
|
+
toRulesyncMcp() {
|
|
3168
|
+
return this.toRulesyncMcpDefault({
|
|
3169
|
+
fileContent: JSON.stringify({ mcpServers: this.json.mcpServers }, null, 2)
|
|
3170
|
+
});
|
|
3171
|
+
}
|
|
3172
|
+
validate() {
|
|
3173
|
+
return { success: true, error: null };
|
|
3174
|
+
}
|
|
3175
|
+
};
|
|
3176
|
+
|
|
3177
|
+
// src/mcp/roo-mcp.ts
|
|
3178
|
+
import { join as join32 } from "path";
|
|
3105
3179
|
var RooMcp = class _RooMcp extends ToolMcp {
|
|
3106
3180
|
json;
|
|
3107
3181
|
constructor(params) {
|
|
@@ -3122,7 +3196,7 @@ var RooMcp = class _RooMcp extends ToolMcp {
|
|
|
3122
3196
|
validate = true
|
|
3123
3197
|
}) {
|
|
3124
3198
|
const fileContent = await readFileContent(
|
|
3125
|
-
|
|
3199
|
+
join32(
|
|
3126
3200
|
baseDir,
|
|
3127
3201
|
this.getSettablePaths().relativeDirPath,
|
|
3128
3202
|
this.getSettablePaths().relativeFilePath
|
|
@@ -3165,13 +3239,14 @@ var mcpProcessorToolTargets = [
|
|
|
3165
3239
|
"cline",
|
|
3166
3240
|
"copilot",
|
|
3167
3241
|
"cursor",
|
|
3242
|
+
"geminicli",
|
|
3168
3243
|
"roo"
|
|
3169
3244
|
];
|
|
3170
3245
|
var McpProcessorToolTargetSchema = z12.enum(
|
|
3171
3246
|
// codexcli is not in the list of tool targets but we add it here because it is a valid tool target for global mode generation
|
|
3172
3247
|
mcpProcessorToolTargets.concat("codexcli")
|
|
3173
3248
|
);
|
|
3174
|
-
var mcpProcessorToolTargetsGlobal = ["claudecode", "codexcli"];
|
|
3249
|
+
var mcpProcessorToolTargetsGlobal = ["claudecode", "codexcli", "geminicli"];
|
|
3175
3250
|
var McpProcessor = class extends FeatureProcessor {
|
|
3176
3251
|
toolTarget;
|
|
3177
3252
|
global;
|
|
@@ -3268,6 +3343,15 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
3268
3343
|
})
|
|
3269
3344
|
];
|
|
3270
3345
|
}
|
|
3346
|
+
case "geminicli": {
|
|
3347
|
+
return [
|
|
3348
|
+
await GeminiCliMcp.fromFile({
|
|
3349
|
+
baseDir: this.baseDir,
|
|
3350
|
+
validate: true,
|
|
3351
|
+
global: this.global
|
|
3352
|
+
})
|
|
3353
|
+
];
|
|
3354
|
+
}
|
|
3271
3355
|
case "roo": {
|
|
3272
3356
|
return [
|
|
3273
3357
|
await RooMcp.fromFile({
|
|
@@ -3333,6 +3417,12 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
3333
3417
|
rulesyncMcp: rulesyncMcp2,
|
|
3334
3418
|
global: this.global
|
|
3335
3419
|
});
|
|
3420
|
+
case "geminicli":
|
|
3421
|
+
return GeminiCliMcp.fromRulesyncMcp({
|
|
3422
|
+
baseDir: this.baseDir,
|
|
3423
|
+
rulesyncMcp: rulesyncMcp2,
|
|
3424
|
+
global: this.global
|
|
3425
|
+
});
|
|
3336
3426
|
case "roo":
|
|
3337
3427
|
return RooMcp.fromRulesyncMcp({
|
|
3338
3428
|
baseDir: this.baseDir,
|
|
@@ -3369,12 +3459,12 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
3369
3459
|
};
|
|
3370
3460
|
|
|
3371
3461
|
// src/rules/rules-processor.ts
|
|
3372
|
-
import { basename as basename17, join as
|
|
3462
|
+
import { basename as basename17, join as join56 } from "path";
|
|
3373
3463
|
import { XMLBuilder } from "fast-xml-parser";
|
|
3374
3464
|
import { z as z21 } from "zod/mini";
|
|
3375
3465
|
|
|
3376
3466
|
// src/subagents/simulated-subagent.ts
|
|
3377
|
-
import { basename as basename12, join as
|
|
3467
|
+
import { basename as basename12, join as join33 } from "path";
|
|
3378
3468
|
import { z as z13 } from "zod/mini";
|
|
3379
3469
|
|
|
3380
3470
|
// src/subagents/tool-subagent.ts
|
|
@@ -3422,7 +3512,7 @@ var SimulatedSubagent = class extends ToolSubagent {
|
|
|
3422
3512
|
const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
3423
3513
|
if (!result.success) {
|
|
3424
3514
|
throw new Error(
|
|
3425
|
-
`Invalid frontmatter in ${
|
|
3515
|
+
`Invalid frontmatter in ${join33(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
|
|
3426
3516
|
);
|
|
3427
3517
|
}
|
|
3428
3518
|
}
|
|
@@ -3473,7 +3563,7 @@ var SimulatedSubagent = class extends ToolSubagent {
|
|
|
3473
3563
|
return {
|
|
3474
3564
|
success: false,
|
|
3475
3565
|
error: new Error(
|
|
3476
|
-
`Invalid frontmatter in ${
|
|
3566
|
+
`Invalid frontmatter in ${join33(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
|
|
3477
3567
|
)
|
|
3478
3568
|
};
|
|
3479
3569
|
}
|
|
@@ -3483,7 +3573,7 @@ var SimulatedSubagent = class extends ToolSubagent {
|
|
|
3483
3573
|
relativeFilePath,
|
|
3484
3574
|
validate = true
|
|
3485
3575
|
}) {
|
|
3486
|
-
const filePath =
|
|
3576
|
+
const filePath = join33(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
|
|
3487
3577
|
const fileContent = await readFileContent(filePath);
|
|
3488
3578
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
3489
3579
|
const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -3640,15 +3730,15 @@ var RooSubagent = class _RooSubagent extends SimulatedSubagent {
|
|
|
3640
3730
|
};
|
|
3641
3731
|
|
|
3642
3732
|
// src/subagents/subagents-processor.ts
|
|
3643
|
-
import { basename as basename14, join as
|
|
3733
|
+
import { basename as basename14, join as join36 } from "path";
|
|
3644
3734
|
import { z as z16 } from "zod/mini";
|
|
3645
3735
|
|
|
3646
3736
|
// src/subagents/claudecode-subagent.ts
|
|
3647
|
-
import { join as
|
|
3737
|
+
import { join as join35 } from "path";
|
|
3648
3738
|
import { z as z15 } from "zod/mini";
|
|
3649
3739
|
|
|
3650
3740
|
// src/subagents/rulesync-subagent.ts
|
|
3651
|
-
import { basename as basename13, join as
|
|
3741
|
+
import { basename as basename13, join as join34 } from "path";
|
|
3652
3742
|
import { z as z14 } from "zod/mini";
|
|
3653
3743
|
var RulesyncSubagentModelSchema = z14.enum(["opus", "sonnet", "haiku", "inherit"]);
|
|
3654
3744
|
var RulesyncSubagentFrontmatterSchema = z14.object({
|
|
@@ -3669,7 +3759,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
3669
3759
|
const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
3670
3760
|
if (!result.success) {
|
|
3671
3761
|
throw new Error(
|
|
3672
|
-
`Invalid frontmatter in ${
|
|
3762
|
+
`Invalid frontmatter in ${join34(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
|
|
3673
3763
|
);
|
|
3674
3764
|
}
|
|
3675
3765
|
}
|
|
@@ -3701,7 +3791,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
3701
3791
|
return {
|
|
3702
3792
|
success: false,
|
|
3703
3793
|
error: new Error(
|
|
3704
|
-
`Invalid frontmatter in ${
|
|
3794
|
+
`Invalid frontmatter in ${join34(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
|
|
3705
3795
|
)
|
|
3706
3796
|
};
|
|
3707
3797
|
}
|
|
@@ -3709,7 +3799,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
3709
3799
|
static async fromFile({
|
|
3710
3800
|
relativeFilePath
|
|
3711
3801
|
}) {
|
|
3712
|
-
const fileContent = await readFileContent(
|
|
3802
|
+
const fileContent = await readFileContent(join34(".rulesync/subagents", relativeFilePath));
|
|
3713
3803
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
3714
3804
|
const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
3715
3805
|
if (!result.success) {
|
|
@@ -3741,7 +3831,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
3741
3831
|
const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
3742
3832
|
if (!result.success) {
|
|
3743
3833
|
throw new Error(
|
|
3744
|
-
`Invalid frontmatter in ${
|
|
3834
|
+
`Invalid frontmatter in ${join35(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
|
|
3745
3835
|
);
|
|
3746
3836
|
}
|
|
3747
3837
|
}
|
|
@@ -3753,7 +3843,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
3753
3843
|
}
|
|
3754
3844
|
static getSettablePaths(_options = {}) {
|
|
3755
3845
|
return {
|
|
3756
|
-
relativeDirPath:
|
|
3846
|
+
relativeDirPath: join35(".claude", "agents")
|
|
3757
3847
|
};
|
|
3758
3848
|
}
|
|
3759
3849
|
getFrontmatter() {
|
|
@@ -3821,7 +3911,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
3821
3911
|
return {
|
|
3822
3912
|
success: false,
|
|
3823
3913
|
error: new Error(
|
|
3824
|
-
`Invalid frontmatter in ${
|
|
3914
|
+
`Invalid frontmatter in ${join35(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
|
|
3825
3915
|
)
|
|
3826
3916
|
};
|
|
3827
3917
|
}
|
|
@@ -3839,7 +3929,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
3839
3929
|
global = false
|
|
3840
3930
|
}) {
|
|
3841
3931
|
const paths = this.getSettablePaths({ global });
|
|
3842
|
-
const filePath =
|
|
3932
|
+
const filePath = join35(baseDir, paths.relativeDirPath, relativeFilePath);
|
|
3843
3933
|
const fileContent = await readFileContent(filePath);
|
|
3844
3934
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
3845
3935
|
const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -3993,7 +4083,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
3993
4083
|
* Load and parse rulesync subagent files from .rulesync/subagents/ directory
|
|
3994
4084
|
*/
|
|
3995
4085
|
async loadRulesyncFiles() {
|
|
3996
|
-
const subagentsDir =
|
|
4086
|
+
const subagentsDir = join36(RulesyncSubagent.getSettablePaths().relativeDirPath);
|
|
3997
4087
|
const dirExists = await directoryExists(subagentsDir);
|
|
3998
4088
|
if (!dirExists) {
|
|
3999
4089
|
logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
|
|
@@ -4008,7 +4098,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4008
4098
|
logger.info(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
|
|
4009
4099
|
const rulesyncSubagents = [];
|
|
4010
4100
|
for (const mdFile of mdFiles) {
|
|
4011
|
-
const filepath =
|
|
4101
|
+
const filepath = join36(subagentsDir, mdFile);
|
|
4012
4102
|
try {
|
|
4013
4103
|
const rulesyncSubagent = await RulesyncSubagent.fromFile({
|
|
4014
4104
|
relativeFilePath: mdFile,
|
|
@@ -4127,7 +4217,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4127
4217
|
relativeDirPath,
|
|
4128
4218
|
fromFile
|
|
4129
4219
|
}) {
|
|
4130
|
-
const paths = await findFilesByGlobs(
|
|
4220
|
+
const paths = await findFilesByGlobs(join36(this.baseDir, relativeDirPath, "*.md"));
|
|
4131
4221
|
const subagents = (await Promise.allSettled(paths.map((path2) => fromFile(basename14(path2))))).filter((r) => r.status === "fulfilled").map((r) => r.value);
|
|
4132
4222
|
logger.info(`Successfully loaded ${subagents.length} ${relativeDirPath} subagents`);
|
|
4133
4223
|
return subagents;
|
|
@@ -4155,13 +4245,13 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4155
4245
|
};
|
|
4156
4246
|
|
|
4157
4247
|
// src/rules/agentsmd-rule.ts
|
|
4158
|
-
import { join as
|
|
4248
|
+
import { join as join39 } from "path";
|
|
4159
4249
|
|
|
4160
4250
|
// src/rules/tool-rule.ts
|
|
4161
|
-
import { join as
|
|
4251
|
+
import { join as join38 } from "path";
|
|
4162
4252
|
|
|
4163
4253
|
// src/rules/rulesync-rule.ts
|
|
4164
|
-
import { basename as basename15, join as
|
|
4254
|
+
import { basename as basename15, join as join37 } from "path";
|
|
4165
4255
|
import { z as z17 } from "zod/mini";
|
|
4166
4256
|
var RulesyncRuleFrontmatterSchema = z17.object({
|
|
4167
4257
|
root: z17.optional(z17.optional(z17.boolean())),
|
|
@@ -4190,7 +4280,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
4190
4280
|
const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
|
|
4191
4281
|
if (!result.success) {
|
|
4192
4282
|
throw new Error(
|
|
4193
|
-
`Invalid frontmatter in ${
|
|
4283
|
+
`Invalid frontmatter in ${join37(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
|
|
4194
4284
|
);
|
|
4195
4285
|
}
|
|
4196
4286
|
}
|
|
@@ -4225,7 +4315,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
4225
4315
|
return {
|
|
4226
4316
|
success: false,
|
|
4227
4317
|
error: new Error(
|
|
4228
|
-
`Invalid frontmatter in ${
|
|
4318
|
+
`Invalid frontmatter in ${join37(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
|
|
4229
4319
|
)
|
|
4230
4320
|
};
|
|
4231
4321
|
}
|
|
@@ -4234,7 +4324,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
4234
4324
|
relativeFilePath,
|
|
4235
4325
|
validate = true
|
|
4236
4326
|
}) {
|
|
4237
|
-
const filePath =
|
|
4327
|
+
const filePath = join37(this.getSettablePaths().legacy.relativeDirPath, relativeFilePath);
|
|
4238
4328
|
const fileContent = await readFileContent(filePath);
|
|
4239
4329
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4240
4330
|
const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -4263,7 +4353,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
4263
4353
|
relativeFilePath,
|
|
4264
4354
|
validate = true
|
|
4265
4355
|
}) {
|
|
4266
|
-
const filePath =
|
|
4356
|
+
const filePath = join37(this.getSettablePaths().recommended.relativeDirPath, relativeFilePath);
|
|
4267
4357
|
const fileContent = await readFileContent(filePath);
|
|
4268
4358
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4269
4359
|
const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -4364,7 +4454,7 @@ var ToolRule = class extends ToolFile {
|
|
|
4364
4454
|
});
|
|
4365
4455
|
const rulesyncFrontmatter = rulesyncRule.getFrontmatter();
|
|
4366
4456
|
if (!rulesyncFrontmatter.root && rulesyncFrontmatter.agentsmd?.subprojectPath) {
|
|
4367
|
-
params.relativeDirPath =
|
|
4457
|
+
params.relativeDirPath = join38(rulesyncFrontmatter.agentsmd.subprojectPath);
|
|
4368
4458
|
params.relativeFilePath = "AGENTS.md";
|
|
4369
4459
|
}
|
|
4370
4460
|
return params;
|
|
@@ -4440,8 +4530,8 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
|
|
|
4440
4530
|
validate = true
|
|
4441
4531
|
}) {
|
|
4442
4532
|
const isRoot = relativeFilePath === "AGENTS.md";
|
|
4443
|
-
const relativePath = isRoot ? "AGENTS.md" :
|
|
4444
|
-
const fileContent = await readFileContent(
|
|
4533
|
+
const relativePath = isRoot ? "AGENTS.md" : join39(".agents/memories", relativeFilePath);
|
|
4534
|
+
const fileContent = await readFileContent(join39(baseDir, relativePath));
|
|
4445
4535
|
return new _AgentsMdRule({
|
|
4446
4536
|
baseDir,
|
|
4447
4537
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -4481,7 +4571,7 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
|
|
|
4481
4571
|
};
|
|
4482
4572
|
|
|
4483
4573
|
// src/rules/amazonqcli-rule.ts
|
|
4484
|
-
import { join as
|
|
4574
|
+
import { join as join40 } from "path";
|
|
4485
4575
|
var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
|
|
4486
4576
|
static getSettablePaths() {
|
|
4487
4577
|
return {
|
|
@@ -4496,7 +4586,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
|
|
|
4496
4586
|
validate = true
|
|
4497
4587
|
}) {
|
|
4498
4588
|
const fileContent = await readFileContent(
|
|
4499
|
-
|
|
4589
|
+
join40(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
4500
4590
|
);
|
|
4501
4591
|
return new _AmazonQCliRule({
|
|
4502
4592
|
baseDir,
|
|
@@ -4536,7 +4626,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
|
|
|
4536
4626
|
};
|
|
4537
4627
|
|
|
4538
4628
|
// src/rules/augmentcode-legacy-rule.ts
|
|
4539
|
-
import { join as
|
|
4629
|
+
import { join as join41 } from "path";
|
|
4540
4630
|
var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
4541
4631
|
toRulesyncRule() {
|
|
4542
4632
|
const rulesyncFrontmatter = {
|
|
@@ -4597,8 +4687,8 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
|
4597
4687
|
}) {
|
|
4598
4688
|
const settablePaths = this.getSettablePaths();
|
|
4599
4689
|
const isRoot = relativeFilePath === settablePaths.root.relativeFilePath;
|
|
4600
|
-
const relativePath = isRoot ? settablePaths.root.relativeFilePath :
|
|
4601
|
-
const fileContent = await readFileContent(
|
|
4690
|
+
const relativePath = isRoot ? settablePaths.root.relativeFilePath : join41(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
|
|
4691
|
+
const fileContent = await readFileContent(join41(baseDir, relativePath));
|
|
4602
4692
|
return new _AugmentcodeLegacyRule({
|
|
4603
4693
|
baseDir,
|
|
4604
4694
|
relativeDirPath: isRoot ? settablePaths.root.relativeDirPath : settablePaths.nonRoot.relativeDirPath,
|
|
@@ -4611,7 +4701,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
|
4611
4701
|
};
|
|
4612
4702
|
|
|
4613
4703
|
// src/rules/augmentcode-rule.ts
|
|
4614
|
-
import { join as
|
|
4704
|
+
import { join as join42 } from "path";
|
|
4615
4705
|
var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
4616
4706
|
toRulesyncRule() {
|
|
4617
4707
|
return this.toRulesyncRuleDefault();
|
|
@@ -4643,7 +4733,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
|
4643
4733
|
validate = true
|
|
4644
4734
|
}) {
|
|
4645
4735
|
const fileContent = await readFileContent(
|
|
4646
|
-
|
|
4736
|
+
join42(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
4647
4737
|
);
|
|
4648
4738
|
const { body: content } = parseFrontmatter(fileContent);
|
|
4649
4739
|
return new _AugmentcodeRule({
|
|
@@ -4666,7 +4756,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
|
4666
4756
|
};
|
|
4667
4757
|
|
|
4668
4758
|
// src/rules/claudecode-rule.ts
|
|
4669
|
-
import { join as
|
|
4759
|
+
import { join as join43 } from "path";
|
|
4670
4760
|
var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
4671
4761
|
static getSettablePaths({
|
|
4672
4762
|
global
|
|
@@ -4685,7 +4775,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
4685
4775
|
relativeFilePath: "CLAUDE.md"
|
|
4686
4776
|
},
|
|
4687
4777
|
nonRoot: {
|
|
4688
|
-
relativeDirPath:
|
|
4778
|
+
relativeDirPath: join43(".claude", "memories")
|
|
4689
4779
|
}
|
|
4690
4780
|
};
|
|
4691
4781
|
}
|
|
@@ -4700,7 +4790,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
4700
4790
|
if (isRoot) {
|
|
4701
4791
|
const relativePath2 = paths.root.relativeFilePath;
|
|
4702
4792
|
const fileContent2 = await readFileContent(
|
|
4703
|
-
|
|
4793
|
+
join43(baseDir, paths.root.relativeDirPath, relativePath2)
|
|
4704
4794
|
);
|
|
4705
4795
|
return new _ClaudecodeRule({
|
|
4706
4796
|
baseDir,
|
|
@@ -4714,8 +4804,8 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
4714
4804
|
if (!paths.nonRoot) {
|
|
4715
4805
|
throw new Error("nonRoot path is not set");
|
|
4716
4806
|
}
|
|
4717
|
-
const relativePath =
|
|
4718
|
-
const fileContent = await readFileContent(
|
|
4807
|
+
const relativePath = join43(paths.nonRoot.relativeDirPath, relativeFilePath);
|
|
4808
|
+
const fileContent = await readFileContent(join43(baseDir, relativePath));
|
|
4719
4809
|
return new _ClaudecodeRule({
|
|
4720
4810
|
baseDir,
|
|
4721
4811
|
relativeDirPath: paths.nonRoot.relativeDirPath,
|
|
@@ -4757,7 +4847,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
4757
4847
|
};
|
|
4758
4848
|
|
|
4759
4849
|
// src/rules/cline-rule.ts
|
|
4760
|
-
import { join as
|
|
4850
|
+
import { join as join44 } from "path";
|
|
4761
4851
|
import { z as z18 } from "zod/mini";
|
|
4762
4852
|
var ClineRuleFrontmatterSchema = z18.object({
|
|
4763
4853
|
description: z18.string()
|
|
@@ -4802,7 +4892,7 @@ var ClineRule = class _ClineRule extends ToolRule {
|
|
|
4802
4892
|
validate = true
|
|
4803
4893
|
}) {
|
|
4804
4894
|
const fileContent = await readFileContent(
|
|
4805
|
-
|
|
4895
|
+
join44(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
4806
4896
|
);
|
|
4807
4897
|
return new _ClineRule({
|
|
4808
4898
|
baseDir,
|
|
@@ -4815,7 +4905,7 @@ var ClineRule = class _ClineRule extends ToolRule {
|
|
|
4815
4905
|
};
|
|
4816
4906
|
|
|
4817
4907
|
// src/rules/codexcli-rule.ts
|
|
4818
|
-
import { join as
|
|
4908
|
+
import { join as join45 } from "path";
|
|
4819
4909
|
var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
4820
4910
|
static getSettablePaths({
|
|
4821
4911
|
global
|
|
@@ -4849,7 +4939,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
4849
4939
|
if (isRoot) {
|
|
4850
4940
|
const relativePath2 = paths.root.relativeFilePath;
|
|
4851
4941
|
const fileContent2 = await readFileContent(
|
|
4852
|
-
|
|
4942
|
+
join45(baseDir, paths.root.relativeDirPath, relativePath2)
|
|
4853
4943
|
);
|
|
4854
4944
|
return new _CodexcliRule({
|
|
4855
4945
|
baseDir,
|
|
@@ -4863,8 +4953,8 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
4863
4953
|
if (!paths.nonRoot) {
|
|
4864
4954
|
throw new Error("nonRoot path is not set");
|
|
4865
4955
|
}
|
|
4866
|
-
const relativePath =
|
|
4867
|
-
const fileContent = await readFileContent(
|
|
4956
|
+
const relativePath = join45(paths.nonRoot.relativeDirPath, relativeFilePath);
|
|
4957
|
+
const fileContent = await readFileContent(join45(baseDir, relativePath));
|
|
4868
4958
|
return new _CodexcliRule({
|
|
4869
4959
|
baseDir,
|
|
4870
4960
|
relativeDirPath: paths.nonRoot.relativeDirPath,
|
|
@@ -4906,7 +4996,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
4906
4996
|
};
|
|
4907
4997
|
|
|
4908
4998
|
// src/rules/copilot-rule.ts
|
|
4909
|
-
import { join as
|
|
4999
|
+
import { join as join46 } from "path";
|
|
4910
5000
|
import { z as z19 } from "zod/mini";
|
|
4911
5001
|
var CopilotRuleFrontmatterSchema = z19.object({
|
|
4912
5002
|
description: z19.optional(z19.string()),
|
|
@@ -4931,7 +5021,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
4931
5021
|
const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
|
|
4932
5022
|
if (!result.success) {
|
|
4933
5023
|
throw new Error(
|
|
4934
|
-
`Invalid frontmatter in ${
|
|
5024
|
+
`Invalid frontmatter in ${join46(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
|
|
4935
5025
|
);
|
|
4936
5026
|
}
|
|
4937
5027
|
}
|
|
@@ -5003,11 +5093,11 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
5003
5093
|
validate = true
|
|
5004
5094
|
}) {
|
|
5005
5095
|
const isRoot = relativeFilePath === "copilot-instructions.md";
|
|
5006
|
-
const relativePath = isRoot ?
|
|
5096
|
+
const relativePath = isRoot ? join46(
|
|
5007
5097
|
this.getSettablePaths().root.relativeDirPath,
|
|
5008
5098
|
this.getSettablePaths().root.relativeFilePath
|
|
5009
|
-
) :
|
|
5010
|
-
const fileContent = await readFileContent(
|
|
5099
|
+
) : join46(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
|
|
5100
|
+
const fileContent = await readFileContent(join46(baseDir, relativePath));
|
|
5011
5101
|
if (isRoot) {
|
|
5012
5102
|
return new _CopilotRule({
|
|
5013
5103
|
baseDir,
|
|
@@ -5026,7 +5116,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
5026
5116
|
const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
|
|
5027
5117
|
if (!result.success) {
|
|
5028
5118
|
throw new Error(
|
|
5029
|
-
`Invalid frontmatter in ${
|
|
5119
|
+
`Invalid frontmatter in ${join46(baseDir, relativeFilePath)}: ${result.error.message}`
|
|
5030
5120
|
);
|
|
5031
5121
|
}
|
|
5032
5122
|
return new _CopilotRule({
|
|
@@ -5050,7 +5140,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
5050
5140
|
return {
|
|
5051
5141
|
success: false,
|
|
5052
5142
|
error: new Error(
|
|
5053
|
-
`Invalid frontmatter in ${
|
|
5143
|
+
`Invalid frontmatter in ${join46(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
|
|
5054
5144
|
)
|
|
5055
5145
|
};
|
|
5056
5146
|
}
|
|
@@ -5070,7 +5160,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
5070
5160
|
};
|
|
5071
5161
|
|
|
5072
5162
|
// src/rules/cursor-rule.ts
|
|
5073
|
-
import { basename as basename16, join as
|
|
5163
|
+
import { basename as basename16, join as join47 } from "path";
|
|
5074
5164
|
import { z as z20 } from "zod/mini";
|
|
5075
5165
|
var CursorRuleFrontmatterSchema = z20.object({
|
|
5076
5166
|
description: z20.optional(z20.string()),
|
|
@@ -5092,7 +5182,7 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
5092
5182
|
const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
|
|
5093
5183
|
if (!result.success) {
|
|
5094
5184
|
throw new Error(
|
|
5095
|
-
`Invalid frontmatter in ${
|
|
5185
|
+
`Invalid frontmatter in ${join47(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
|
|
5096
5186
|
);
|
|
5097
5187
|
}
|
|
5098
5188
|
}
|
|
@@ -5169,6 +5259,16 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
5169
5259
|
validate: true
|
|
5170
5260
|
});
|
|
5171
5261
|
}
|
|
5262
|
+
/**
|
|
5263
|
+
* Resolve cursor globs with priority: cursor-specific > parent
|
|
5264
|
+
* Returns comma-separated string for Cursor format, or undefined if no globs
|
|
5265
|
+
* @param cursorSpecificGlobs - Cursor-specific globs (takes priority if defined)
|
|
5266
|
+
* @param parentGlobs - Parent globs (used if cursorSpecificGlobs is undefined)
|
|
5267
|
+
*/
|
|
5268
|
+
static resolveCursorGlobs(cursorSpecificGlobs, parentGlobs) {
|
|
5269
|
+
const targetGlobs = cursorSpecificGlobs !== void 0 ? cursorSpecificGlobs : parentGlobs;
|
|
5270
|
+
return targetGlobs && targetGlobs.length > 0 ? targetGlobs.join(",") : void 0;
|
|
5271
|
+
}
|
|
5172
5272
|
static fromRulesyncRule({
|
|
5173
5273
|
baseDir = ".",
|
|
5174
5274
|
rulesyncRule,
|
|
@@ -5177,7 +5277,7 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
5177
5277
|
const rulesyncFrontmatter = rulesyncRule.getFrontmatter();
|
|
5178
5278
|
const cursorFrontmatter = {
|
|
5179
5279
|
description: rulesyncFrontmatter.description,
|
|
5180
|
-
globs: rulesyncFrontmatter.globs
|
|
5280
|
+
globs: this.resolveCursorGlobs(rulesyncFrontmatter.cursor?.globs, rulesyncFrontmatter.globs),
|
|
5181
5281
|
alwaysApply: rulesyncFrontmatter.cursor?.alwaysApply ?? void 0
|
|
5182
5282
|
};
|
|
5183
5283
|
const body = rulesyncRule.getBody();
|
|
@@ -5199,13 +5299,13 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
5199
5299
|
validate = true
|
|
5200
5300
|
}) {
|
|
5201
5301
|
const fileContent = await readFileContent(
|
|
5202
|
-
|
|
5302
|
+
join47(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
5203
5303
|
);
|
|
5204
5304
|
const { frontmatter, body: content } = _CursorRule.parseCursorFrontmatter(fileContent);
|
|
5205
5305
|
const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
|
|
5206
5306
|
if (!result.success) {
|
|
5207
5307
|
throw new Error(
|
|
5208
|
-
`Invalid frontmatter in ${
|
|
5308
|
+
`Invalid frontmatter in ${join47(baseDir, relativeFilePath)}: ${result.error.message}`
|
|
5209
5309
|
);
|
|
5210
5310
|
}
|
|
5211
5311
|
return new _CursorRule({
|
|
@@ -5228,7 +5328,7 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
5228
5328
|
return {
|
|
5229
5329
|
success: false,
|
|
5230
5330
|
error: new Error(
|
|
5231
|
-
`Invalid frontmatter in ${
|
|
5331
|
+
`Invalid frontmatter in ${join47(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
|
|
5232
5332
|
)
|
|
5233
5333
|
};
|
|
5234
5334
|
}
|
|
@@ -5248,7 +5348,7 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
5248
5348
|
};
|
|
5249
5349
|
|
|
5250
5350
|
// src/rules/geminicli-rule.ts
|
|
5251
|
-
import { join as
|
|
5351
|
+
import { join as join48 } from "path";
|
|
5252
5352
|
var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
5253
5353
|
static getSettablePaths({
|
|
5254
5354
|
global
|
|
@@ -5282,7 +5382,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
5282
5382
|
if (isRoot) {
|
|
5283
5383
|
const relativePath2 = paths.root.relativeFilePath;
|
|
5284
5384
|
const fileContent2 = await readFileContent(
|
|
5285
|
-
|
|
5385
|
+
join48(baseDir, paths.root.relativeDirPath, relativePath2)
|
|
5286
5386
|
);
|
|
5287
5387
|
return new _GeminiCliRule({
|
|
5288
5388
|
baseDir,
|
|
@@ -5296,8 +5396,8 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
5296
5396
|
if (!paths.nonRoot) {
|
|
5297
5397
|
throw new Error("nonRoot path is not set");
|
|
5298
5398
|
}
|
|
5299
|
-
const relativePath =
|
|
5300
|
-
const fileContent = await readFileContent(
|
|
5399
|
+
const relativePath = join48(paths.nonRoot.relativeDirPath, relativeFilePath);
|
|
5400
|
+
const fileContent = await readFileContent(join48(baseDir, relativePath));
|
|
5301
5401
|
return new _GeminiCliRule({
|
|
5302
5402
|
baseDir,
|
|
5303
5403
|
relativeDirPath: paths.nonRoot.relativeDirPath,
|
|
@@ -5339,7 +5439,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
5339
5439
|
};
|
|
5340
5440
|
|
|
5341
5441
|
// src/rules/junie-rule.ts
|
|
5342
|
-
import { join as
|
|
5442
|
+
import { join as join49 } from "path";
|
|
5343
5443
|
var JunieRule = class _JunieRule extends ToolRule {
|
|
5344
5444
|
static getSettablePaths() {
|
|
5345
5445
|
return {
|
|
@@ -5358,8 +5458,8 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
5358
5458
|
validate = true
|
|
5359
5459
|
}) {
|
|
5360
5460
|
const isRoot = relativeFilePath === "guidelines.md";
|
|
5361
|
-
const relativePath = isRoot ? "guidelines.md" :
|
|
5362
|
-
const fileContent = await readFileContent(
|
|
5461
|
+
const relativePath = isRoot ? "guidelines.md" : join49(".junie/memories", relativeFilePath);
|
|
5462
|
+
const fileContent = await readFileContent(join49(baseDir, relativePath));
|
|
5363
5463
|
return new _JunieRule({
|
|
5364
5464
|
baseDir,
|
|
5365
5465
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -5399,7 +5499,7 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
5399
5499
|
};
|
|
5400
5500
|
|
|
5401
5501
|
// src/rules/kiro-rule.ts
|
|
5402
|
-
import { join as
|
|
5502
|
+
import { join as join50 } from "path";
|
|
5403
5503
|
var KiroRule = class _KiroRule extends ToolRule {
|
|
5404
5504
|
static getSettablePaths() {
|
|
5405
5505
|
return {
|
|
@@ -5414,7 +5514,7 @@ var KiroRule = class _KiroRule extends ToolRule {
|
|
|
5414
5514
|
validate = true
|
|
5415
5515
|
}) {
|
|
5416
5516
|
const fileContent = await readFileContent(
|
|
5417
|
-
|
|
5517
|
+
join50(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
5418
5518
|
);
|
|
5419
5519
|
return new _KiroRule({
|
|
5420
5520
|
baseDir,
|
|
@@ -5454,7 +5554,7 @@ var KiroRule = class _KiroRule extends ToolRule {
|
|
|
5454
5554
|
};
|
|
5455
5555
|
|
|
5456
5556
|
// src/rules/opencode-rule.ts
|
|
5457
|
-
import { join as
|
|
5557
|
+
import { join as join51 } from "path";
|
|
5458
5558
|
var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
5459
5559
|
static getSettablePaths() {
|
|
5460
5560
|
return {
|
|
@@ -5473,8 +5573,8 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
|
5473
5573
|
validate = true
|
|
5474
5574
|
}) {
|
|
5475
5575
|
const isRoot = relativeFilePath === "AGENTS.md";
|
|
5476
|
-
const relativePath = isRoot ? "AGENTS.md" :
|
|
5477
|
-
const fileContent = await readFileContent(
|
|
5576
|
+
const relativePath = isRoot ? "AGENTS.md" : join51(".opencode/memories", relativeFilePath);
|
|
5577
|
+
const fileContent = await readFileContent(join51(baseDir, relativePath));
|
|
5478
5578
|
return new _OpenCodeRule({
|
|
5479
5579
|
baseDir,
|
|
5480
5580
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -5514,7 +5614,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
|
5514
5614
|
};
|
|
5515
5615
|
|
|
5516
5616
|
// src/rules/qwencode-rule.ts
|
|
5517
|
-
import { join as
|
|
5617
|
+
import { join as join52 } from "path";
|
|
5518
5618
|
var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
5519
5619
|
static getSettablePaths() {
|
|
5520
5620
|
return {
|
|
@@ -5533,8 +5633,8 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
|
5533
5633
|
validate = true
|
|
5534
5634
|
}) {
|
|
5535
5635
|
const isRoot = relativeFilePath === "QWEN.md";
|
|
5536
|
-
const relativePath = isRoot ? "QWEN.md" :
|
|
5537
|
-
const fileContent = await readFileContent(
|
|
5636
|
+
const relativePath = isRoot ? "QWEN.md" : join52(".qwen/memories", relativeFilePath);
|
|
5637
|
+
const fileContent = await readFileContent(join52(baseDir, relativePath));
|
|
5538
5638
|
return new _QwencodeRule({
|
|
5539
5639
|
baseDir,
|
|
5540
5640
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -5571,7 +5671,7 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
|
5571
5671
|
};
|
|
5572
5672
|
|
|
5573
5673
|
// src/rules/roo-rule.ts
|
|
5574
|
-
import { join as
|
|
5674
|
+
import { join as join53 } from "path";
|
|
5575
5675
|
var RooRule = class _RooRule extends ToolRule {
|
|
5576
5676
|
static getSettablePaths() {
|
|
5577
5677
|
return {
|
|
@@ -5586,7 +5686,7 @@ var RooRule = class _RooRule extends ToolRule {
|
|
|
5586
5686
|
validate = true
|
|
5587
5687
|
}) {
|
|
5588
5688
|
const fileContent = await readFileContent(
|
|
5589
|
-
|
|
5689
|
+
join53(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
5590
5690
|
);
|
|
5591
5691
|
return new _RooRule({
|
|
5592
5692
|
baseDir,
|
|
@@ -5641,7 +5741,7 @@ var RooRule = class _RooRule extends ToolRule {
|
|
|
5641
5741
|
};
|
|
5642
5742
|
|
|
5643
5743
|
// src/rules/warp-rule.ts
|
|
5644
|
-
import { join as
|
|
5744
|
+
import { join as join54 } from "path";
|
|
5645
5745
|
var WarpRule = class _WarpRule extends ToolRule {
|
|
5646
5746
|
constructor({ fileContent, root, ...rest }) {
|
|
5647
5747
|
super({
|
|
@@ -5667,8 +5767,8 @@ var WarpRule = class _WarpRule extends ToolRule {
|
|
|
5667
5767
|
validate = true
|
|
5668
5768
|
}) {
|
|
5669
5769
|
const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
|
|
5670
|
-
const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath :
|
|
5671
|
-
const fileContent = await readFileContent(
|
|
5770
|
+
const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join54(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
|
|
5771
|
+
const fileContent = await readFileContent(join54(baseDir, relativePath));
|
|
5672
5772
|
return new _WarpRule({
|
|
5673
5773
|
baseDir,
|
|
5674
5774
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : ".warp",
|
|
@@ -5708,7 +5808,7 @@ var WarpRule = class _WarpRule extends ToolRule {
|
|
|
5708
5808
|
};
|
|
5709
5809
|
|
|
5710
5810
|
// src/rules/windsurf-rule.ts
|
|
5711
|
-
import { join as
|
|
5811
|
+
import { join as join55 } from "path";
|
|
5712
5812
|
var WindsurfRule = class _WindsurfRule extends ToolRule {
|
|
5713
5813
|
static getSettablePaths() {
|
|
5714
5814
|
return {
|
|
@@ -5723,7 +5823,7 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
|
|
|
5723
5823
|
validate = true
|
|
5724
5824
|
}) {
|
|
5725
5825
|
const fileContent = await readFileContent(
|
|
5726
|
-
|
|
5826
|
+
join55(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
5727
5827
|
);
|
|
5728
5828
|
return new _WindsurfRule({
|
|
5729
5829
|
baseDir,
|
|
@@ -6123,7 +6223,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6123
6223
|
* Load and parse rulesync rule files from .rulesync/rules/ directory
|
|
6124
6224
|
*/
|
|
6125
6225
|
async loadRulesyncFiles() {
|
|
6126
|
-
const files = await findFilesByGlobs(
|
|
6226
|
+
const files = await findFilesByGlobs(join56(".rulesync/rules", "*.md"));
|
|
6127
6227
|
logger.debug(`Found ${files.length} rulesync files`);
|
|
6128
6228
|
const rulesyncRules = await Promise.all(
|
|
6129
6229
|
files.map((file) => RulesyncRule.fromFile({ relativeFilePath: basename17(file) }))
|
|
@@ -6144,7 +6244,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6144
6244
|
return rulesyncRules;
|
|
6145
6245
|
}
|
|
6146
6246
|
async loadRulesyncFilesLegacy() {
|
|
6147
|
-
const legacyFiles = await findFilesByGlobs(
|
|
6247
|
+
const legacyFiles = await findFilesByGlobs(join56(".rulesync", "*.md"));
|
|
6148
6248
|
logger.debug(`Found ${legacyFiles.length} legacy rulesync files`);
|
|
6149
6249
|
return Promise.all(
|
|
6150
6250
|
legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath: basename17(file) }))
|
|
@@ -6211,7 +6311,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6211
6311
|
return [];
|
|
6212
6312
|
}
|
|
6213
6313
|
const rootFilePaths = await findFilesByGlobs(
|
|
6214
|
-
|
|
6314
|
+
join56(this.baseDir, root.relativeDirPath ?? ".", root.relativeFilePath)
|
|
6215
6315
|
);
|
|
6216
6316
|
return await Promise.all(
|
|
6217
6317
|
rootFilePaths.map(
|
|
@@ -6229,7 +6329,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6229
6329
|
return [];
|
|
6230
6330
|
}
|
|
6231
6331
|
const nonRootFilePaths = await findFilesByGlobs(
|
|
6232
|
-
|
|
6332
|
+
join56(this.baseDir, nonRoot.relativeDirPath, `*.${nonRoot.extension}`)
|
|
6233
6333
|
);
|
|
6234
6334
|
return await Promise.all(
|
|
6235
6335
|
nonRootFilePaths.map(
|
|
@@ -6605,14 +6705,14 @@ s/<command> [arguments]
|
|
|
6605
6705
|
This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
|
|
6606
6706
|
The \`s\` in \`s/\` stands for *simulate*. Because custom slash commands are not built-in, this syntax provides a pseudo way to invoke them.
|
|
6607
6707
|
|
|
6608
|
-
When users call a custom slash command, you have to look for the markdown file, \`${
|
|
6708
|
+
When users call a custom slash command, you have to look for the markdown file, \`${join56(commands.relativeDirPath, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
|
|
6609
6709
|
const subagentsSection = subagents ? `## Simulated Subagents
|
|
6610
6710
|
|
|
6611
6711
|
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.
|
|
6612
6712
|
|
|
6613
|
-
When users call a simulated subagent, it will look for the corresponding markdown file, \`${
|
|
6713
|
+
When users call a simulated subagent, it will look for the corresponding markdown file, \`${join56(subagents.relativeDirPath, "{subagent}.md")}\`, and execute its contents as the block of operations.
|
|
6614
6714
|
|
|
6615
|
-
For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${
|
|
6715
|
+
For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join56(subagents.relativeDirPath, "planner.md")}\`, and execute its contents as the block of operations.` : "";
|
|
6616
6716
|
const result = [
|
|
6617
6717
|
overview,
|
|
6618
6718
|
...this.simulateCommands && CommandsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [commandsSection] : [],
|
|
@@ -6822,58 +6922,69 @@ async function generateSubagents(config) {
|
|
|
6822
6922
|
}
|
|
6823
6923
|
|
|
6824
6924
|
// src/cli/commands/gitignore.ts
|
|
6825
|
-
import { join as
|
|
6925
|
+
import { join as join57 } from "path";
|
|
6826
6926
|
var gitignoreCommand = async () => {
|
|
6827
|
-
const gitignorePath =
|
|
6927
|
+
const gitignorePath = join57(process.cwd(), ".gitignore");
|
|
6828
6928
|
const rulesFilesToIgnore = [
|
|
6829
6929
|
"# Generated by rulesync - AI tool configuration files",
|
|
6930
|
+
// AGENTS.md
|
|
6931
|
+
"**/AGENTS.md",
|
|
6932
|
+
"**/.agents/",
|
|
6933
|
+
// Amazon Q
|
|
6830
6934
|
"**/.amazonq/",
|
|
6831
|
-
|
|
6832
|
-
"**/.
|
|
6833
|
-
"**/.
|
|
6834
|
-
"**/.
|
|
6835
|
-
|
|
6836
|
-
"**/.clinerules/",
|
|
6837
|
-
"**/.clineignore",
|
|
6935
|
+
// Augment
|
|
6936
|
+
"**/.augmentignore",
|
|
6937
|
+
"**/.augment/rules/",
|
|
6938
|
+
"**/.augment-guidelines",
|
|
6939
|
+
// Claude Code
|
|
6838
6940
|
"**/CLAUDE.md",
|
|
6839
6941
|
"**/.claude/memories/",
|
|
6840
6942
|
"**/.claude/commands/",
|
|
6841
6943
|
"**/.claude/agents/",
|
|
6842
6944
|
"**/.claude/settings.local.json",
|
|
6843
|
-
"
|
|
6844
|
-
|
|
6845
|
-
"**/.
|
|
6846
|
-
"**/.
|
|
6847
|
-
"**/.
|
|
6945
|
+
"**/.mcp.json",
|
|
6946
|
+
// Cline
|
|
6947
|
+
"**/.clinerules/",
|
|
6948
|
+
"**/.clineignore",
|
|
6949
|
+
"**/.cline/mcp.json",
|
|
6950
|
+
// Codex
|
|
6951
|
+
"**/.codexignore",
|
|
6952
|
+
"**/.codex/",
|
|
6953
|
+
// Cursor
|
|
6954
|
+
"**/.cursor/",
|
|
6955
|
+
"**/.cursorignore",
|
|
6956
|
+
"**/.cursor/mcp.json",
|
|
6957
|
+
// Gemini
|
|
6848
6958
|
"**/GEMINI.md",
|
|
6849
6959
|
"**/.gemini/memories/",
|
|
6850
6960
|
"**/.gemini/commands/",
|
|
6851
6961
|
"**/.gemini/subagents/",
|
|
6852
|
-
|
|
6853
|
-
"**/.
|
|
6854
|
-
"**/.
|
|
6855
|
-
"**/.
|
|
6856
|
-
"**/.
|
|
6857
|
-
"**/.
|
|
6858
|
-
|
|
6859
|
-
"**/.augment-guidelines",
|
|
6962
|
+
// GitHub Copilot
|
|
6963
|
+
"**/.github/copilot-instructions.md",
|
|
6964
|
+
"**/.github/instructions/",
|
|
6965
|
+
"**/.github/prompts/",
|
|
6966
|
+
"**/.github/subagents/",
|
|
6967
|
+
"**/.vscode/mcp.json",
|
|
6968
|
+
// Junie
|
|
6860
6969
|
"**/.junie/guidelines.md",
|
|
6861
|
-
|
|
6970
|
+
// Kiro
|
|
6971
|
+
"**/.kiro/steering/",
|
|
6972
|
+
"**/.aiignore",
|
|
6973
|
+
// OpenCode
|
|
6862
6974
|
"**/.opencode/memories/",
|
|
6863
6975
|
"**/.opencode/commands/",
|
|
6864
6976
|
"**/opencode.json",
|
|
6865
|
-
|
|
6866
|
-
"
|
|
6867
|
-
"**/.
|
|
6977
|
+
// Qwen
|
|
6978
|
+
"**/QWEN.md",
|
|
6979
|
+
"**/.qwen/memories/",
|
|
6980
|
+
// Roo
|
|
6981
|
+
"**/.roo/rules/",
|
|
6982
|
+
"**/.rooignore",
|
|
6868
6983
|
"**/.roo/mcp.json",
|
|
6869
6984
|
"**/.roo/subagents/",
|
|
6870
|
-
|
|
6871
|
-
"**/.github/commands/",
|
|
6872
|
-
"**/.github/subagents/",
|
|
6985
|
+
// Warp
|
|
6873
6986
|
"**/.warp/",
|
|
6874
|
-
"**/WARP.md"
|
|
6875
|
-
"**/.codexignore",
|
|
6876
|
-
"**/.codex/"
|
|
6987
|
+
"**/WARP.md"
|
|
6877
6988
|
];
|
|
6878
6989
|
let gitignoreContent = "";
|
|
6879
6990
|
if (await fileExists(gitignorePath)) {
|
|
@@ -7052,7 +7163,7 @@ async function importSubagents(config, tool) {
|
|
|
7052
7163
|
}
|
|
7053
7164
|
|
|
7054
7165
|
// src/cli/commands/init.ts
|
|
7055
|
-
import { join as
|
|
7166
|
+
import { join as join58 } from "path";
|
|
7056
7167
|
async function initCommand() {
|
|
7057
7168
|
logger.info("Initializing rulesync...");
|
|
7058
7169
|
await ensureDir(".rulesync");
|
|
@@ -7060,7 +7171,7 @@ async function initCommand() {
|
|
|
7060
7171
|
await createConfigFile();
|
|
7061
7172
|
logger.success("rulesync initialized successfully!");
|
|
7062
7173
|
logger.info("Next steps:");
|
|
7063
|
-
logger.info(`1. Edit
|
|
7174
|
+
logger.info(`1. Edit .rulesync/**/*.md, .rulesync/.mcp.json and .rulesyncignore`);
|
|
7064
7175
|
logger.info("2. Run 'rulesync generate' to create configuration files");
|
|
7065
7176
|
}
|
|
7066
7177
|
async function createConfigFile() {
|
|
@@ -7088,7 +7199,7 @@ async function createConfigFile() {
|
|
|
7088
7199
|
logger.success("Created rulesync.jsonc");
|
|
7089
7200
|
}
|
|
7090
7201
|
async function createSampleFiles() {
|
|
7091
|
-
const
|
|
7202
|
+
const sampleRuleFile = {
|
|
7092
7203
|
filename: "overview.md",
|
|
7093
7204
|
content: `---
|
|
7094
7205
|
root: true
|
|
@@ -7123,20 +7234,134 @@ globs: ["**/*"]
|
|
|
7123
7234
|
- Follow single responsibility principle
|
|
7124
7235
|
`
|
|
7125
7236
|
};
|
|
7126
|
-
const
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7237
|
+
const sampleMcpFile = {
|
|
7238
|
+
filename: ".mcp.json",
|
|
7239
|
+
content: `{
|
|
7240
|
+
"mcpServers": {
|
|
7241
|
+
"serena": {
|
|
7242
|
+
"type": "stdio",
|
|
7243
|
+
"command": "uvx",
|
|
7244
|
+
"args": [
|
|
7245
|
+
"--from",
|
|
7246
|
+
"git+https://github.com/oraios/serena",
|
|
7247
|
+
"serena",
|
|
7248
|
+
"start-mcp-server",
|
|
7249
|
+
"--context",
|
|
7250
|
+
"ide-assistant",
|
|
7251
|
+
"--enable-web-dashboard",
|
|
7252
|
+
"false",
|
|
7253
|
+
"--project",
|
|
7254
|
+
"."
|
|
7255
|
+
],
|
|
7256
|
+
"env": {}
|
|
7257
|
+
},
|
|
7258
|
+
"context7": {
|
|
7259
|
+
"type": "stdio",
|
|
7260
|
+
"command": "npx",
|
|
7261
|
+
"args": [
|
|
7262
|
+
"-y",
|
|
7263
|
+
"@upstash/context7-mcp"
|
|
7264
|
+
],
|
|
7265
|
+
"env": {}
|
|
7266
|
+
}
|
|
7267
|
+
}
|
|
7268
|
+
}
|
|
7269
|
+
`
|
|
7270
|
+
};
|
|
7271
|
+
const sampleCommandFile = {
|
|
7272
|
+
filename: "review-pr.md",
|
|
7273
|
+
content: `---
|
|
7274
|
+
description: 'Review a pull request'
|
|
7275
|
+
targets: ["*"]
|
|
7276
|
+
---
|
|
7277
|
+
|
|
7278
|
+
target_pr = $ARGUMENTS
|
|
7279
|
+
|
|
7280
|
+
If target_pr is not provided, use the PR of the current branch.
|
|
7281
|
+
|
|
7282
|
+
Execute the following in parallel:
|
|
7283
|
+
|
|
7284
|
+
1. Check code quality and style consistency
|
|
7285
|
+
2. Review test coverage
|
|
7286
|
+
3. Verify documentation updates
|
|
7287
|
+
4. Check for potential bugs or security issues
|
|
7288
|
+
|
|
7289
|
+
Then provide a summary of findings and suggestions for improvement.
|
|
7290
|
+
`
|
|
7291
|
+
};
|
|
7292
|
+
const sampleSubagentFile = {
|
|
7293
|
+
filename: "planner.md",
|
|
7294
|
+
content: `---
|
|
7295
|
+
name: planner
|
|
7296
|
+
targets: ["*"]
|
|
7297
|
+
description: >-
|
|
7298
|
+
This is the general-purpose planner. The user asks the agent to plan to
|
|
7299
|
+
suggest a specification, implement a new feature, refactor the codebase, or
|
|
7300
|
+
fix a bug. This agent can be called by the user explicitly only.
|
|
7301
|
+
claudecode:
|
|
7302
|
+
model: inherit
|
|
7303
|
+
---
|
|
7304
|
+
|
|
7305
|
+
You are the planner for any tasks.
|
|
7306
|
+
|
|
7307
|
+
Based on the user's instruction, create a plan while analyzing the related files. Then, report the plan in detail. You can output files to @tmp/ if needed.
|
|
7308
|
+
|
|
7309
|
+
Attention, again, you are just the planner, so though you can read any files and run any commands for analysis, please don't write any code.
|
|
7310
|
+
`
|
|
7311
|
+
};
|
|
7312
|
+
const sampleIgnoreFile = {
|
|
7313
|
+
content: `credentials/
|
|
7314
|
+
`
|
|
7315
|
+
};
|
|
7316
|
+
const rulePaths = RulesyncRule.getSettablePaths();
|
|
7317
|
+
const mcpPaths = RulesyncMcp.getSettablePaths();
|
|
7318
|
+
const commandPaths = RulesyncCommand.getSettablePaths();
|
|
7319
|
+
const subagentPaths = RulesyncSubagent.getSettablePaths();
|
|
7320
|
+
const ignorePaths = RulesyncIgnore.getSettablePaths();
|
|
7321
|
+
await ensureDir(rulePaths.recommended.relativeDirPath);
|
|
7322
|
+
await ensureDir(mcpPaths.relativeDirPath);
|
|
7323
|
+
await ensureDir(commandPaths.relativeDirPath);
|
|
7324
|
+
await ensureDir(subagentPaths.relativeDirPath);
|
|
7325
|
+
await ensureDir(ignorePaths.relativeDirPath);
|
|
7326
|
+
const ruleFilepath = join58(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
|
|
7327
|
+
if (!await fileExists(ruleFilepath)) {
|
|
7328
|
+
await writeFileContent(ruleFilepath, sampleRuleFile.content);
|
|
7329
|
+
logger.success(`Created ${ruleFilepath}`);
|
|
7330
|
+
} else {
|
|
7331
|
+
logger.info(`Skipped ${ruleFilepath} (already exists)`);
|
|
7332
|
+
}
|
|
7333
|
+
const mcpFilepath = join58(mcpPaths.relativeDirPath, mcpPaths.relativeFilePath);
|
|
7334
|
+
if (!await fileExists(mcpFilepath)) {
|
|
7335
|
+
await writeFileContent(mcpFilepath, sampleMcpFile.content);
|
|
7336
|
+
logger.success(`Created ${mcpFilepath}`);
|
|
7337
|
+
} else {
|
|
7338
|
+
logger.info(`Skipped ${mcpFilepath} (already exists)`);
|
|
7339
|
+
}
|
|
7340
|
+
const commandFilepath = join58(commandPaths.relativeDirPath, sampleCommandFile.filename);
|
|
7341
|
+
if (!await fileExists(commandFilepath)) {
|
|
7342
|
+
await writeFileContent(commandFilepath, sampleCommandFile.content);
|
|
7343
|
+
logger.success(`Created ${commandFilepath}`);
|
|
7344
|
+
} else {
|
|
7345
|
+
logger.info(`Skipped ${commandFilepath} (already exists)`);
|
|
7346
|
+
}
|
|
7347
|
+
const subagentFilepath = join58(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
|
|
7348
|
+
if (!await fileExists(subagentFilepath)) {
|
|
7349
|
+
await writeFileContent(subagentFilepath, sampleSubagentFile.content);
|
|
7350
|
+
logger.success(`Created ${subagentFilepath}`);
|
|
7351
|
+
} else {
|
|
7352
|
+
logger.info(`Skipped ${subagentFilepath} (already exists)`);
|
|
7353
|
+
}
|
|
7354
|
+
const ignoreFilepath = join58(ignorePaths.relativeDirPath, ignorePaths.relativeFilePath);
|
|
7355
|
+
if (!await fileExists(ignoreFilepath)) {
|
|
7356
|
+
await writeFileContent(ignoreFilepath, sampleIgnoreFile.content);
|
|
7357
|
+
logger.success(`Created ${ignoreFilepath}`);
|
|
7133
7358
|
} else {
|
|
7134
|
-
logger.info(`Skipped ${
|
|
7359
|
+
logger.info(`Skipped ${ignoreFilepath} (already exists)`);
|
|
7135
7360
|
}
|
|
7136
7361
|
}
|
|
7137
7362
|
|
|
7138
7363
|
// src/cli/index.ts
|
|
7139
|
-
var getVersion = () => "3.
|
|
7364
|
+
var getVersion = () => "3.7.0";
|
|
7140
7365
|
var main = async () => {
|
|
7141
7366
|
const program = new Command();
|
|
7142
7367
|
const version = getVersion();
|