rulesync 0.75.0 → 0.76.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 +9 -5
- package/dist/index.cjs +1033 -907
- package/dist/index.js +1036 -910
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -742,7 +742,7 @@ import { basename as basename6, join as join6 } from "path";
|
|
|
742
742
|
var CopilotCommand = class _CopilotCommand extends SimulatedCommand {
|
|
743
743
|
static getSettablePaths() {
|
|
744
744
|
return {
|
|
745
|
-
relativeDirPath: ".
|
|
745
|
+
relativeDirPath: ".github/commands"
|
|
746
746
|
};
|
|
747
747
|
}
|
|
748
748
|
static fromRulesyncCommand({
|
|
@@ -1300,6 +1300,9 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
1300
1300
|
}
|
|
1301
1301
|
return commandsProcessorToolTargets;
|
|
1302
1302
|
}
|
|
1303
|
+
static getToolTargetsSimulated() {
|
|
1304
|
+
return commandsProcessorToolTargetsSimulated;
|
|
1305
|
+
}
|
|
1303
1306
|
};
|
|
1304
1307
|
|
|
1305
1308
|
// src/config/config-resolver.ts
|
|
@@ -2777,9 +2780,9 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
2777
2780
|
};
|
|
2778
2781
|
|
|
2779
2782
|
// src/rules/rules-processor.ts
|
|
2780
|
-
import { basename as
|
|
2783
|
+
import { basename as basename16, join as join52 } from "path";
|
|
2781
2784
|
import { XMLBuilder } from "fast-xml-parser";
|
|
2782
|
-
import { z as
|
|
2785
|
+
import { z as z20 } from "zod/mini";
|
|
2783
2786
|
|
|
2784
2787
|
// src/constants/paths.ts
|
|
2785
2788
|
import { join as join29 } from "path";
|
|
@@ -2937,7 +2940,7 @@ var CodexCliSubagent = class _CodexCliSubagent extends SimulatedSubagent {
|
|
|
2937
2940
|
var CopilotSubagent = class _CopilotSubagent extends SimulatedSubagent {
|
|
2938
2941
|
static getSettablePaths() {
|
|
2939
2942
|
return {
|
|
2940
|
-
relativeDirPath: ".
|
|
2943
|
+
relativeDirPath: ".github/subagents"
|
|
2941
2944
|
};
|
|
2942
2945
|
}
|
|
2943
2946
|
static async fromFile(params) {
|
|
@@ -2979,189 +2982,686 @@ var CursorSubagent = class _CursorSubagent extends SimulatedSubagent {
|
|
|
2979
2982
|
}
|
|
2980
2983
|
};
|
|
2981
2984
|
|
|
2982
|
-
// src/
|
|
2985
|
+
// src/subagents/geminicli-subagent.ts
|
|
2986
|
+
var GeminiCliSubagent = class _GeminiCliSubagent extends SimulatedSubagent {
|
|
2987
|
+
static getSettablePaths() {
|
|
2988
|
+
return {
|
|
2989
|
+
relativeDirPath: ".gemini/subagents"
|
|
2990
|
+
};
|
|
2991
|
+
}
|
|
2992
|
+
static async fromFile(params) {
|
|
2993
|
+
const baseParams = await this.fromFileDefault(params);
|
|
2994
|
+
return new _GeminiCliSubagent(baseParams);
|
|
2995
|
+
}
|
|
2996
|
+
static fromRulesyncSubagent(params) {
|
|
2997
|
+
const baseParams = this.fromRulesyncSubagentDefault(params);
|
|
2998
|
+
return new _GeminiCliSubagent(baseParams);
|
|
2999
|
+
}
|
|
3000
|
+
static isTargetedByRulesyncSubagent(rulesyncSubagent) {
|
|
3001
|
+
return this.isTargetedByRulesyncSubagentDefault({
|
|
3002
|
+
rulesyncSubagent,
|
|
3003
|
+
toolTarget: "geminicli"
|
|
3004
|
+
});
|
|
3005
|
+
}
|
|
3006
|
+
};
|
|
3007
|
+
|
|
3008
|
+
// src/subagents/roo-subagent.ts
|
|
3009
|
+
var RooSubagent = class _RooSubagent extends SimulatedSubagent {
|
|
3010
|
+
static getSettablePaths() {
|
|
3011
|
+
return {
|
|
3012
|
+
relativeDirPath: ".roo/subagents"
|
|
3013
|
+
};
|
|
3014
|
+
}
|
|
3015
|
+
static async fromFile(params) {
|
|
3016
|
+
const baseParams = await this.fromFileDefault(params);
|
|
3017
|
+
return new _RooSubagent(baseParams);
|
|
3018
|
+
}
|
|
3019
|
+
static fromRulesyncSubagent(params) {
|
|
3020
|
+
const baseParams = this.fromRulesyncSubagentDefault(params);
|
|
3021
|
+
return new _RooSubagent(baseParams);
|
|
3022
|
+
}
|
|
3023
|
+
static isTargetedByRulesyncSubagent(rulesyncSubagent) {
|
|
3024
|
+
return this.isTargetedByRulesyncSubagentDefault({
|
|
3025
|
+
rulesyncSubagent,
|
|
3026
|
+
toolTarget: "roo"
|
|
3027
|
+
});
|
|
3028
|
+
}
|
|
3029
|
+
};
|
|
3030
|
+
|
|
3031
|
+
// src/subagents/subagents-processor.ts
|
|
3032
|
+
import { basename as basename13, join as join33 } from "path";
|
|
3033
|
+
import { z as z15 } from "zod/mini";
|
|
3034
|
+
|
|
3035
|
+
// src/subagents/claudecode-subagent.ts
|
|
2983
3036
|
import { join as join32 } from "path";
|
|
3037
|
+
import { z as z14 } from "zod/mini";
|
|
2984
3038
|
|
|
2985
|
-
// src/
|
|
3039
|
+
// src/subagents/rulesync-subagent.ts
|
|
2986
3040
|
import { basename as basename12, join as join31 } from "path";
|
|
2987
3041
|
import { z as z13 } from "zod/mini";
|
|
2988
|
-
var
|
|
2989
|
-
|
|
2990
|
-
targets:
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
3042
|
+
var RulesyncSubagentModelSchema = z13.enum(["opus", "sonnet", "haiku", "inherit"]);
|
|
3043
|
+
var RulesyncSubagentFrontmatterSchema = z13.object({
|
|
3044
|
+
targets: RulesyncTargetsSchema,
|
|
3045
|
+
name: z13.string(),
|
|
3046
|
+
description: z13.string(),
|
|
3047
|
+
claudecode: z13.optional(
|
|
2994
3048
|
z13.object({
|
|
2995
|
-
|
|
2996
|
-
description: z13.optional(z13.string()),
|
|
2997
|
-
globs: z13.optional(z13.array(z13.string()))
|
|
3049
|
+
model: RulesyncSubagentModelSchema
|
|
2998
3050
|
})
|
|
2999
3051
|
)
|
|
3000
3052
|
});
|
|
3001
|
-
var
|
|
3053
|
+
var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
3002
3054
|
frontmatter;
|
|
3003
3055
|
body;
|
|
3004
3056
|
constructor({ frontmatter, body, ...rest }) {
|
|
3005
3057
|
if (rest.validate !== false) {
|
|
3006
|
-
const result =
|
|
3058
|
+
const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
3007
3059
|
if (!result.success) {
|
|
3008
3060
|
throw result.error;
|
|
3009
3061
|
}
|
|
3010
3062
|
}
|
|
3011
3063
|
super({
|
|
3012
|
-
...rest
|
|
3013
|
-
fileContent: stringifyFrontmatter(body, frontmatter)
|
|
3064
|
+
...rest
|
|
3014
3065
|
});
|
|
3015
3066
|
this.frontmatter = frontmatter;
|
|
3016
3067
|
this.body = body;
|
|
3017
3068
|
}
|
|
3018
3069
|
static getSettablePaths() {
|
|
3019
3070
|
return {
|
|
3020
|
-
|
|
3021
|
-
relativeDirPath: ".rulesync/rules"
|
|
3022
|
-
},
|
|
3023
|
-
legacy: {
|
|
3024
|
-
relativeDirPath: ".rulesync"
|
|
3025
|
-
}
|
|
3071
|
+
relativeDirPath: ".rulesync/subagents"
|
|
3026
3072
|
};
|
|
3027
3073
|
}
|
|
3028
3074
|
getFrontmatter() {
|
|
3029
3075
|
return this.frontmatter;
|
|
3030
3076
|
}
|
|
3077
|
+
getBody() {
|
|
3078
|
+
return this.body;
|
|
3079
|
+
}
|
|
3031
3080
|
validate() {
|
|
3032
3081
|
if (!this.frontmatter) {
|
|
3033
3082
|
return { success: true, error: null };
|
|
3034
3083
|
}
|
|
3035
|
-
const result =
|
|
3084
|
+
const result = RulesyncSubagentFrontmatterSchema.safeParse(this.frontmatter);
|
|
3036
3085
|
if (result.success) {
|
|
3037
3086
|
return { success: true, error: null };
|
|
3038
3087
|
} else {
|
|
3039
3088
|
return { success: false, error: result.error };
|
|
3040
3089
|
}
|
|
3041
3090
|
}
|
|
3042
|
-
static async
|
|
3043
|
-
relativeFilePath
|
|
3044
|
-
validate = true
|
|
3091
|
+
static async fromFile({
|
|
3092
|
+
relativeFilePath
|
|
3045
3093
|
}) {
|
|
3046
|
-
const
|
|
3047
|
-
const fileContent = await readFileContent(filePath);
|
|
3094
|
+
const fileContent = await readFileContent(join31(RULESYNC_SUBAGENTS_DIR, relativeFilePath));
|
|
3048
3095
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
3049
|
-
const result =
|
|
3096
|
+
const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
3050
3097
|
if (!result.success) {
|
|
3051
|
-
throw new Error(`Invalid frontmatter in ${
|
|
3098
|
+
throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
|
|
3052
3099
|
}
|
|
3053
|
-
const
|
|
3054
|
-
|
|
3055
|
-
targets: result.data.targets ?? ["*"],
|
|
3056
|
-
description: result.data.description ?? "",
|
|
3057
|
-
globs: result.data.globs ?? [],
|
|
3058
|
-
cursor: result.data.cursor
|
|
3059
|
-
};
|
|
3060
|
-
const filename = basename12(filePath);
|
|
3061
|
-
return new _RulesyncRule({
|
|
3100
|
+
const filename = basename12(relativeFilePath);
|
|
3101
|
+
return new _RulesyncSubagent({
|
|
3062
3102
|
baseDir: ".",
|
|
3063
|
-
relativeDirPath: this.getSettablePaths().
|
|
3103
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
3064
3104
|
relativeFilePath: filename,
|
|
3065
|
-
frontmatter:
|
|
3105
|
+
frontmatter: result.data,
|
|
3066
3106
|
body: content.trim(),
|
|
3067
|
-
|
|
3107
|
+
fileContent
|
|
3068
3108
|
});
|
|
3069
3109
|
}
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3110
|
+
};
|
|
3111
|
+
|
|
3112
|
+
// src/subagents/claudecode-subagent.ts
|
|
3113
|
+
var ClaudecodeSubagentFrontmatterSchema = z14.object({
|
|
3114
|
+
name: z14.string(),
|
|
3115
|
+
description: z14.string(),
|
|
3116
|
+
model: z14.optional(z14.enum(["opus", "sonnet", "haiku", "inherit"]))
|
|
3117
|
+
});
|
|
3118
|
+
var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
3119
|
+
frontmatter;
|
|
3120
|
+
body;
|
|
3121
|
+
constructor({ frontmatter, body, ...rest }) {
|
|
3122
|
+
if (rest.validate !== false) {
|
|
3123
|
+
const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
3124
|
+
if (!result.success) {
|
|
3125
|
+
throw result.error;
|
|
3126
|
+
}
|
|
3080
3127
|
}
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
targets: result.data.targets ?? ["*"],
|
|
3084
|
-
description: result.data.description ?? "",
|
|
3085
|
-
globs: result.data.globs ?? [],
|
|
3086
|
-
cursor: result.data.cursor
|
|
3087
|
-
};
|
|
3088
|
-
const filename = basename12(filePath);
|
|
3089
|
-
return new _RulesyncRule({
|
|
3090
|
-
baseDir: ".",
|
|
3091
|
-
relativeDirPath: this.getSettablePaths().recommended.relativeDirPath,
|
|
3092
|
-
relativeFilePath: filename,
|
|
3093
|
-
frontmatter: validatedFrontmatter,
|
|
3094
|
-
body: content.trim(),
|
|
3095
|
-
validate
|
|
3128
|
+
super({
|
|
3129
|
+
...rest
|
|
3096
3130
|
});
|
|
3131
|
+
this.frontmatter = frontmatter;
|
|
3132
|
+
this.body = body;
|
|
3097
3133
|
}
|
|
3098
|
-
|
|
3099
|
-
return
|
|
3134
|
+
static getSettablePaths() {
|
|
3135
|
+
return {
|
|
3136
|
+
relativeDirPath: ".claude/agents"
|
|
3137
|
+
};
|
|
3100
3138
|
}
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
// src/rules/tool-rule.ts
|
|
3104
|
-
var ToolRule = class extends ToolFile {
|
|
3105
|
-
root;
|
|
3106
|
-
constructor({ root = false, ...rest }) {
|
|
3107
|
-
super(rest);
|
|
3108
|
-
this.root = root;
|
|
3139
|
+
getFrontmatter() {
|
|
3140
|
+
return this.frontmatter;
|
|
3109
3141
|
}
|
|
3110
|
-
|
|
3111
|
-
|
|
3142
|
+
getBody() {
|
|
3143
|
+
return this.body;
|
|
3112
3144
|
}
|
|
3113
|
-
|
|
3114
|
-
|
|
3145
|
+
toRulesyncSubagent() {
|
|
3146
|
+
const rulesyncFrontmatter = {
|
|
3147
|
+
targets: ["claudecode"],
|
|
3148
|
+
name: this.frontmatter.name,
|
|
3149
|
+
description: this.frontmatter.description,
|
|
3150
|
+
...this.frontmatter.model && {
|
|
3151
|
+
claudecode: {
|
|
3152
|
+
model: this.frontmatter.model
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
};
|
|
3156
|
+
const fileContent = stringifyFrontmatter(this.body, rulesyncFrontmatter);
|
|
3157
|
+
return new RulesyncSubagent({
|
|
3158
|
+
frontmatter: rulesyncFrontmatter,
|
|
3159
|
+
body: this.body,
|
|
3160
|
+
baseDir: this.baseDir,
|
|
3161
|
+
relativeDirPath: ".rulesync/subagents",
|
|
3162
|
+
relativeFilePath: this.getRelativeFilePath(),
|
|
3163
|
+
fileContent,
|
|
3164
|
+
validate: true
|
|
3165
|
+
});
|
|
3115
3166
|
}
|
|
3116
|
-
static
|
|
3167
|
+
static fromRulesyncSubagent({
|
|
3117
3168
|
baseDir = ".",
|
|
3118
|
-
|
|
3119
|
-
validate = true
|
|
3120
|
-
rootPath = { relativeDirPath: ".", relativeFilePath: "AGENTS.md" },
|
|
3121
|
-
nonRootPath = { relativeDirPath: ".agents/memories" }
|
|
3169
|
+
rulesyncSubagent,
|
|
3170
|
+
validate = true
|
|
3122
3171
|
}) {
|
|
3123
|
-
const
|
|
3124
|
-
|
|
3172
|
+
const rulesyncFrontmatter = rulesyncSubagent.getFrontmatter();
|
|
3173
|
+
const claudecodeFrontmatter = {
|
|
3174
|
+
name: rulesyncFrontmatter.name,
|
|
3175
|
+
description: rulesyncFrontmatter.description,
|
|
3176
|
+
model: rulesyncFrontmatter.claudecode?.model
|
|
3177
|
+
};
|
|
3178
|
+
const body = rulesyncSubagent.getBody();
|
|
3179
|
+
const fileContent = stringifyFrontmatter(body, claudecodeFrontmatter);
|
|
3180
|
+
return new _ClaudecodeSubagent({
|
|
3125
3181
|
baseDir,
|
|
3126
|
-
|
|
3127
|
-
|
|
3182
|
+
frontmatter: claudecodeFrontmatter,
|
|
3183
|
+
body,
|
|
3184
|
+
relativeDirPath: ".claude/agents",
|
|
3185
|
+
relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
|
|
3128
3186
|
fileContent,
|
|
3129
|
-
validate
|
|
3130
|
-
root: rulesyncRule.getFrontmatter().root ?? false
|
|
3131
|
-
};
|
|
3132
|
-
}
|
|
3133
|
-
toRulesyncRuleDefault() {
|
|
3134
|
-
return new RulesyncRule({
|
|
3135
|
-
baseDir: this.getBaseDir(),
|
|
3136
|
-
relativeDirPath: RULESYNC_RULES_DIR,
|
|
3137
|
-
relativeFilePath: this.getRelativeFilePath(),
|
|
3138
|
-
frontmatter: {
|
|
3139
|
-
root: this.isRoot(),
|
|
3140
|
-
targets: ["*"],
|
|
3141
|
-
description: "",
|
|
3142
|
-
globs: this.isRoot() ? ["**/*"] : []
|
|
3143
|
-
},
|
|
3144
|
-
body: this.getFileContent()
|
|
3187
|
+
validate
|
|
3145
3188
|
});
|
|
3146
3189
|
}
|
|
3147
|
-
|
|
3148
|
-
|
|
3190
|
+
validate() {
|
|
3191
|
+
if (!this.frontmatter) {
|
|
3192
|
+
return { success: true, error: null };
|
|
3193
|
+
}
|
|
3194
|
+
const result = ClaudecodeSubagentFrontmatterSchema.safeParse(this.frontmatter);
|
|
3195
|
+
if (result.success) {
|
|
3196
|
+
return { success: true, error: null };
|
|
3197
|
+
} else {
|
|
3198
|
+
return { success: false, error: result.error };
|
|
3199
|
+
}
|
|
3149
3200
|
}
|
|
3150
|
-
static
|
|
3151
|
-
|
|
3201
|
+
static isTargetedByRulesyncSubagent(rulesyncSubagent) {
|
|
3202
|
+
return this.isTargetedByRulesyncSubagentDefault({
|
|
3203
|
+
rulesyncSubagent,
|
|
3204
|
+
toolTarget: "claudecode"
|
|
3205
|
+
});
|
|
3152
3206
|
}
|
|
3153
|
-
static
|
|
3154
|
-
|
|
3155
|
-
|
|
3207
|
+
static async fromFile({
|
|
3208
|
+
baseDir = ".",
|
|
3209
|
+
relativeFilePath,
|
|
3210
|
+
validate = true
|
|
3156
3211
|
}) {
|
|
3157
|
-
const
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
return true;
|
|
3212
|
+
const fileContent = await readFileContent(join32(baseDir, ".claude/agents", relativeFilePath));
|
|
3213
|
+
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
3214
|
+
const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
3215
|
+
if (!result.success) {
|
|
3216
|
+
throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
|
|
3163
3217
|
}
|
|
3164
|
-
|
|
3218
|
+
return new _ClaudecodeSubagent({
|
|
3219
|
+
baseDir,
|
|
3220
|
+
relativeDirPath: ".claude/agents",
|
|
3221
|
+
relativeFilePath,
|
|
3222
|
+
frontmatter: result.data,
|
|
3223
|
+
body: content.trim(),
|
|
3224
|
+
fileContent,
|
|
3225
|
+
validate
|
|
3226
|
+
});
|
|
3227
|
+
}
|
|
3228
|
+
};
|
|
3229
|
+
|
|
3230
|
+
// src/subagents/subagents-processor.ts
|
|
3231
|
+
var subagentsProcessorToolTargets = [
|
|
3232
|
+
"claudecode",
|
|
3233
|
+
"copilot",
|
|
3234
|
+
"cursor",
|
|
3235
|
+
"codexcli",
|
|
3236
|
+
"geminicli",
|
|
3237
|
+
"roo"
|
|
3238
|
+
];
|
|
3239
|
+
var subagentsProcessorToolTargetsSimulated = [
|
|
3240
|
+
"copilot",
|
|
3241
|
+
"cursor",
|
|
3242
|
+
"codexcli",
|
|
3243
|
+
"geminicli",
|
|
3244
|
+
"roo"
|
|
3245
|
+
];
|
|
3246
|
+
var SubagentsProcessorToolTargetSchema = z15.enum(subagentsProcessorToolTargets);
|
|
3247
|
+
var SubagentsProcessor = class extends FeatureProcessor {
|
|
3248
|
+
toolTarget;
|
|
3249
|
+
constructor({
|
|
3250
|
+
baseDir = ".",
|
|
3251
|
+
toolTarget
|
|
3252
|
+
}) {
|
|
3253
|
+
super({ baseDir });
|
|
3254
|
+
this.toolTarget = SubagentsProcessorToolTargetSchema.parse(toolTarget);
|
|
3255
|
+
}
|
|
3256
|
+
async convertRulesyncFilesToToolFiles(rulesyncFiles) {
|
|
3257
|
+
const rulesyncSubagents = rulesyncFiles.filter(
|
|
3258
|
+
(file) => file instanceof RulesyncSubagent
|
|
3259
|
+
);
|
|
3260
|
+
const toolSubagents = rulesyncSubagents.map((rulesyncSubagent) => {
|
|
3261
|
+
switch (this.toolTarget) {
|
|
3262
|
+
case "claudecode":
|
|
3263
|
+
if (!ClaudecodeSubagent.isTargetedByRulesyncSubagent(rulesyncSubagent)) {
|
|
3264
|
+
return null;
|
|
3265
|
+
}
|
|
3266
|
+
return ClaudecodeSubagent.fromRulesyncSubagent({
|
|
3267
|
+
baseDir: this.baseDir,
|
|
3268
|
+
relativeDirPath: RulesyncSubagent.getSettablePaths().relativeDirPath,
|
|
3269
|
+
rulesyncSubagent
|
|
3270
|
+
});
|
|
3271
|
+
case "copilot":
|
|
3272
|
+
if (!CopilotSubagent.isTargetedByRulesyncSubagent(rulesyncSubagent)) {
|
|
3273
|
+
return null;
|
|
3274
|
+
}
|
|
3275
|
+
return CopilotSubagent.fromRulesyncSubagent({
|
|
3276
|
+
baseDir: this.baseDir,
|
|
3277
|
+
relativeDirPath: RulesyncSubagent.getSettablePaths().relativeDirPath,
|
|
3278
|
+
rulesyncSubagent
|
|
3279
|
+
});
|
|
3280
|
+
case "cursor":
|
|
3281
|
+
if (!CursorSubagent.isTargetedByRulesyncSubagent(rulesyncSubagent)) {
|
|
3282
|
+
return null;
|
|
3283
|
+
}
|
|
3284
|
+
return CursorSubagent.fromRulesyncSubagent({
|
|
3285
|
+
baseDir: this.baseDir,
|
|
3286
|
+
relativeDirPath: RulesyncSubagent.getSettablePaths().relativeDirPath,
|
|
3287
|
+
rulesyncSubagent
|
|
3288
|
+
});
|
|
3289
|
+
case "codexcli":
|
|
3290
|
+
if (!CodexCliSubagent.isTargetedByRulesyncSubagent(rulesyncSubagent)) {
|
|
3291
|
+
return null;
|
|
3292
|
+
}
|
|
3293
|
+
return CodexCliSubagent.fromRulesyncSubagent({
|
|
3294
|
+
baseDir: this.baseDir,
|
|
3295
|
+
relativeDirPath: RulesyncSubagent.getSettablePaths().relativeDirPath,
|
|
3296
|
+
rulesyncSubagent
|
|
3297
|
+
});
|
|
3298
|
+
case "geminicli":
|
|
3299
|
+
if (!GeminiCliSubagent.isTargetedByRulesyncSubagent(rulesyncSubagent)) {
|
|
3300
|
+
return null;
|
|
3301
|
+
}
|
|
3302
|
+
return GeminiCliSubagent.fromRulesyncSubagent({
|
|
3303
|
+
baseDir: this.baseDir,
|
|
3304
|
+
relativeDirPath: RulesyncSubagent.getSettablePaths().relativeDirPath,
|
|
3305
|
+
rulesyncSubagent
|
|
3306
|
+
});
|
|
3307
|
+
case "roo":
|
|
3308
|
+
if (!RooSubagent.isTargetedByRulesyncSubagent(rulesyncSubagent)) {
|
|
3309
|
+
return null;
|
|
3310
|
+
}
|
|
3311
|
+
return RooSubagent.fromRulesyncSubagent({
|
|
3312
|
+
baseDir: this.baseDir,
|
|
3313
|
+
relativeDirPath: RulesyncSubagent.getSettablePaths().relativeDirPath,
|
|
3314
|
+
rulesyncSubagent
|
|
3315
|
+
});
|
|
3316
|
+
default:
|
|
3317
|
+
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
3318
|
+
}
|
|
3319
|
+
}).filter((subagent) => subagent !== null);
|
|
3320
|
+
return toolSubagents;
|
|
3321
|
+
}
|
|
3322
|
+
async convertToolFilesToRulesyncFiles(toolFiles) {
|
|
3323
|
+
const toolSubagents = toolFiles.filter(
|
|
3324
|
+
(file) => file instanceof ToolSubagent
|
|
3325
|
+
);
|
|
3326
|
+
const rulesyncSubagents = [];
|
|
3327
|
+
for (const toolSubagent of toolSubagents) {
|
|
3328
|
+
if (toolSubagent instanceof SimulatedSubagent) {
|
|
3329
|
+
logger.debug(
|
|
3330
|
+
`Skipping simulated subagent conversion: ${toolSubagent.getRelativeFilePath()}`
|
|
3331
|
+
);
|
|
3332
|
+
continue;
|
|
3333
|
+
}
|
|
3334
|
+
rulesyncSubagents.push(toolSubagent.toRulesyncSubagent());
|
|
3335
|
+
}
|
|
3336
|
+
return rulesyncSubagents;
|
|
3337
|
+
}
|
|
3338
|
+
/**
|
|
3339
|
+
* Implementation of abstract method from Processor
|
|
3340
|
+
* Load and parse rulesync subagent files from .rulesync/subagents/ directory
|
|
3341
|
+
*/
|
|
3342
|
+
async loadRulesyncFiles() {
|
|
3343
|
+
const subagentsDir = join33(this.baseDir, RulesyncSubagent.getSettablePaths().relativeDirPath);
|
|
3344
|
+
const dirExists = await directoryExists(subagentsDir);
|
|
3345
|
+
if (!dirExists) {
|
|
3346
|
+
logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
|
|
3347
|
+
return [];
|
|
3348
|
+
}
|
|
3349
|
+
const entries = await listDirectoryFiles(subagentsDir);
|
|
3350
|
+
const mdFiles = entries.filter((file) => file.endsWith(".md"));
|
|
3351
|
+
if (mdFiles.length === 0) {
|
|
3352
|
+
logger.debug(`No markdown files found in rulesync subagents directory: ${subagentsDir}`);
|
|
3353
|
+
return [];
|
|
3354
|
+
}
|
|
3355
|
+
logger.info(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
|
|
3356
|
+
const rulesyncSubagents = [];
|
|
3357
|
+
for (const mdFile of mdFiles) {
|
|
3358
|
+
const filepath = join33(subagentsDir, mdFile);
|
|
3359
|
+
try {
|
|
3360
|
+
const rulesyncSubagent = await RulesyncSubagent.fromFile({
|
|
3361
|
+
relativeFilePath: mdFile,
|
|
3362
|
+
validate: true
|
|
3363
|
+
});
|
|
3364
|
+
rulesyncSubagents.push(rulesyncSubagent);
|
|
3365
|
+
logger.debug(`Successfully loaded subagent: ${mdFile}`);
|
|
3366
|
+
} catch (error) {
|
|
3367
|
+
logger.warn(`Failed to load subagent file ${filepath}:`, error);
|
|
3368
|
+
continue;
|
|
3369
|
+
}
|
|
3370
|
+
}
|
|
3371
|
+
if (rulesyncSubagents.length === 0) {
|
|
3372
|
+
logger.debug(`No valid subagents found in ${subagentsDir}`);
|
|
3373
|
+
return [];
|
|
3374
|
+
}
|
|
3375
|
+
logger.info(`Successfully loaded ${rulesyncSubagents.length} rulesync subagents`);
|
|
3376
|
+
return rulesyncSubagents;
|
|
3377
|
+
}
|
|
3378
|
+
/**
|
|
3379
|
+
* Implementation of abstract method from Processor
|
|
3380
|
+
* Load tool-specific subagent configurations and parse them into ToolSubagent instances
|
|
3381
|
+
*/
|
|
3382
|
+
async loadToolFiles() {
|
|
3383
|
+
switch (this.toolTarget) {
|
|
3384
|
+
case "claudecode":
|
|
3385
|
+
return await this.loadClaudecodeSubagents();
|
|
3386
|
+
case "copilot":
|
|
3387
|
+
return await this.loadCopilotSubagents();
|
|
3388
|
+
case "cursor":
|
|
3389
|
+
return await this.loadCursorSubagents();
|
|
3390
|
+
case "codexcli":
|
|
3391
|
+
return await this.loadCodexCliSubagents();
|
|
3392
|
+
case "geminicli":
|
|
3393
|
+
return await this.loadGeminiCliSubagents();
|
|
3394
|
+
case "roo":
|
|
3395
|
+
return await this.loadRooSubagents();
|
|
3396
|
+
default:
|
|
3397
|
+
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
/**
|
|
3401
|
+
* Load Claude Code subagent configurations from .claude/agents/ directory
|
|
3402
|
+
*/
|
|
3403
|
+
async loadClaudecodeSubagents() {
|
|
3404
|
+
return await this.loadToolSubagentsDefault({
|
|
3405
|
+
relativeDirPath: ClaudecodeSubagent.getSettablePaths().relativeDirPath,
|
|
3406
|
+
fromFile: (relativeFilePath) => ClaudecodeSubagent.fromFile({ relativeFilePath })
|
|
3407
|
+
});
|
|
3408
|
+
}
|
|
3409
|
+
/**
|
|
3410
|
+
* Load Copilot subagent configurations from .github/subagents/ directory
|
|
3411
|
+
*/
|
|
3412
|
+
async loadCopilotSubagents() {
|
|
3413
|
+
return await this.loadToolSubagentsDefault({
|
|
3414
|
+
relativeDirPath: CopilotSubagent.getSettablePaths().relativeDirPath,
|
|
3415
|
+
fromFile: (relativeFilePath) => CopilotSubagent.fromFile({ relativeFilePath })
|
|
3416
|
+
});
|
|
3417
|
+
}
|
|
3418
|
+
/**
|
|
3419
|
+
* Load Cursor subagent configurations from .cursor/subagents/ directory
|
|
3420
|
+
*/
|
|
3421
|
+
async loadCursorSubagents() {
|
|
3422
|
+
return await this.loadToolSubagentsDefault({
|
|
3423
|
+
relativeDirPath: CursorSubagent.getSettablePaths().relativeDirPath,
|
|
3424
|
+
fromFile: (relativeFilePath) => CursorSubagent.fromFile({ relativeFilePath })
|
|
3425
|
+
});
|
|
3426
|
+
}
|
|
3427
|
+
/**
|
|
3428
|
+
* Load CodexCli subagent configurations from .codex/subagents/ directory
|
|
3429
|
+
*/
|
|
3430
|
+
async loadCodexCliSubagents() {
|
|
3431
|
+
return await this.loadToolSubagentsDefault({
|
|
3432
|
+
relativeDirPath: CodexCliSubagent.getSettablePaths().relativeDirPath,
|
|
3433
|
+
fromFile: (relativeFilePath) => CodexCliSubagent.fromFile({ relativeFilePath })
|
|
3434
|
+
});
|
|
3435
|
+
}
|
|
3436
|
+
/**
|
|
3437
|
+
* Load GeminiCli subagent configurations from .gemini/subagents/ directory
|
|
3438
|
+
*/
|
|
3439
|
+
async loadGeminiCliSubagents() {
|
|
3440
|
+
return await this.loadToolSubagentsDefault({
|
|
3441
|
+
relativeDirPath: GeminiCliSubagent.getSettablePaths().relativeDirPath,
|
|
3442
|
+
fromFile: (relativeFilePath) => GeminiCliSubagent.fromFile({ relativeFilePath })
|
|
3443
|
+
});
|
|
3444
|
+
}
|
|
3445
|
+
/**
|
|
3446
|
+
* Load Roo subagent configurations from .roo/subagents/ directory
|
|
3447
|
+
*/
|
|
3448
|
+
async loadRooSubagents() {
|
|
3449
|
+
return await this.loadToolSubagentsDefault({
|
|
3450
|
+
relativeDirPath: RooSubagent.getSettablePaths().relativeDirPath,
|
|
3451
|
+
fromFile: (relativeFilePath) => RooSubagent.fromFile({ relativeFilePath })
|
|
3452
|
+
});
|
|
3453
|
+
}
|
|
3454
|
+
async loadToolSubagentsDefault({
|
|
3455
|
+
relativeDirPath,
|
|
3456
|
+
fromFile
|
|
3457
|
+
}) {
|
|
3458
|
+
const paths = await findFilesByGlobs(join33(this.baseDir, relativeDirPath, "*.md"));
|
|
3459
|
+
const subagents = (await Promise.allSettled(paths.map((path2) => fromFile(basename13(path2))))).filter((r) => r.status === "fulfilled").map((r) => r.value);
|
|
3460
|
+
logger.info(`Successfully loaded ${subagents.length} ${relativeDirPath} subagents`);
|
|
3461
|
+
return subagents;
|
|
3462
|
+
}
|
|
3463
|
+
/**
|
|
3464
|
+
* Implementation of abstract method from FeatureProcessor
|
|
3465
|
+
* Return the tool targets that this processor supports
|
|
3466
|
+
*/
|
|
3467
|
+
static getToolTargets({
|
|
3468
|
+
includeSimulated = false
|
|
3469
|
+
} = {}) {
|
|
3470
|
+
if (!includeSimulated) {
|
|
3471
|
+
return subagentsProcessorToolTargets.filter(
|
|
3472
|
+
(target) => !subagentsProcessorToolTargetsSimulated.includes(target)
|
|
3473
|
+
);
|
|
3474
|
+
}
|
|
3475
|
+
return subagentsProcessorToolTargets;
|
|
3476
|
+
}
|
|
3477
|
+
static getToolTargetsSimulated() {
|
|
3478
|
+
return subagentsProcessorToolTargetsSimulated;
|
|
3479
|
+
}
|
|
3480
|
+
};
|
|
3481
|
+
|
|
3482
|
+
// src/rules/agentsmd-rule.ts
|
|
3483
|
+
import { join as join35 } from "path";
|
|
3484
|
+
|
|
3485
|
+
// src/rules/rulesync-rule.ts
|
|
3486
|
+
import { basename as basename14, join as join34 } from "path";
|
|
3487
|
+
import { z as z16 } from "zod/mini";
|
|
3488
|
+
var RulesyncRuleFrontmatterSchema = z16.object({
|
|
3489
|
+
root: z16.optional(z16.optional(z16.boolean())),
|
|
3490
|
+
targets: z16.optional(RulesyncTargetsSchema),
|
|
3491
|
+
description: z16.optional(z16.string()),
|
|
3492
|
+
globs: z16.optional(z16.array(z16.string())),
|
|
3493
|
+
cursor: z16.optional(
|
|
3494
|
+
z16.object({
|
|
3495
|
+
alwaysApply: z16.optional(z16.boolean()),
|
|
3496
|
+
description: z16.optional(z16.string()),
|
|
3497
|
+
globs: z16.optional(z16.array(z16.string()))
|
|
3498
|
+
})
|
|
3499
|
+
)
|
|
3500
|
+
});
|
|
3501
|
+
var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
3502
|
+
frontmatter;
|
|
3503
|
+
body;
|
|
3504
|
+
constructor({ frontmatter, body, ...rest }) {
|
|
3505
|
+
if (rest.validate !== false) {
|
|
3506
|
+
const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
|
|
3507
|
+
if (!result.success) {
|
|
3508
|
+
throw result.error;
|
|
3509
|
+
}
|
|
3510
|
+
}
|
|
3511
|
+
super({
|
|
3512
|
+
...rest,
|
|
3513
|
+
fileContent: stringifyFrontmatter(body, frontmatter)
|
|
3514
|
+
});
|
|
3515
|
+
this.frontmatter = frontmatter;
|
|
3516
|
+
this.body = body;
|
|
3517
|
+
}
|
|
3518
|
+
static getSettablePaths() {
|
|
3519
|
+
return {
|
|
3520
|
+
recommended: {
|
|
3521
|
+
relativeDirPath: ".rulesync/rules"
|
|
3522
|
+
},
|
|
3523
|
+
legacy: {
|
|
3524
|
+
relativeDirPath: ".rulesync"
|
|
3525
|
+
}
|
|
3526
|
+
};
|
|
3527
|
+
}
|
|
3528
|
+
getFrontmatter() {
|
|
3529
|
+
return this.frontmatter;
|
|
3530
|
+
}
|
|
3531
|
+
validate() {
|
|
3532
|
+
if (!this.frontmatter) {
|
|
3533
|
+
return { success: true, error: null };
|
|
3534
|
+
}
|
|
3535
|
+
const result = RulesyncRuleFrontmatterSchema.safeParse(this.frontmatter);
|
|
3536
|
+
if (result.success) {
|
|
3537
|
+
return { success: true, error: null };
|
|
3538
|
+
} else {
|
|
3539
|
+
return { success: false, error: result.error };
|
|
3540
|
+
}
|
|
3541
|
+
}
|
|
3542
|
+
static async fromFileLegacy({
|
|
3543
|
+
relativeFilePath,
|
|
3544
|
+
validate = true
|
|
3545
|
+
}) {
|
|
3546
|
+
const filePath = join34(this.getSettablePaths().legacy.relativeDirPath, relativeFilePath);
|
|
3547
|
+
const fileContent = await readFileContent(filePath);
|
|
3548
|
+
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
3549
|
+
const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
|
|
3550
|
+
if (!result.success) {
|
|
3551
|
+
throw new Error(`Invalid frontmatter in ${filePath}: ${result.error.message}`);
|
|
3552
|
+
}
|
|
3553
|
+
const validatedFrontmatter = {
|
|
3554
|
+
root: result.data.root ?? false,
|
|
3555
|
+
targets: result.data.targets ?? ["*"],
|
|
3556
|
+
description: result.data.description ?? "",
|
|
3557
|
+
globs: result.data.globs ?? [],
|
|
3558
|
+
cursor: result.data.cursor
|
|
3559
|
+
};
|
|
3560
|
+
const filename = basename14(filePath);
|
|
3561
|
+
return new _RulesyncRule({
|
|
3562
|
+
baseDir: ".",
|
|
3563
|
+
relativeDirPath: this.getSettablePaths().recommended.relativeDirPath,
|
|
3564
|
+
relativeFilePath: filename,
|
|
3565
|
+
frontmatter: validatedFrontmatter,
|
|
3566
|
+
body: content.trim(),
|
|
3567
|
+
validate
|
|
3568
|
+
});
|
|
3569
|
+
}
|
|
3570
|
+
static async fromFile({
|
|
3571
|
+
relativeFilePath,
|
|
3572
|
+
validate = true
|
|
3573
|
+
}) {
|
|
3574
|
+
const filePath = join34(this.getSettablePaths().recommended.relativeDirPath, relativeFilePath);
|
|
3575
|
+
const fileContent = await readFileContent(filePath);
|
|
3576
|
+
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
3577
|
+
const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
|
|
3578
|
+
if (!result.success) {
|
|
3579
|
+
throw new Error(`Invalid frontmatter in ${filePath}: ${result.error.message}`);
|
|
3580
|
+
}
|
|
3581
|
+
const validatedFrontmatter = {
|
|
3582
|
+
root: result.data.root ?? false,
|
|
3583
|
+
targets: result.data.targets ?? ["*"],
|
|
3584
|
+
description: result.data.description ?? "",
|
|
3585
|
+
globs: result.data.globs ?? [],
|
|
3586
|
+
cursor: result.data.cursor
|
|
3587
|
+
};
|
|
3588
|
+
const filename = basename14(filePath);
|
|
3589
|
+
return new _RulesyncRule({
|
|
3590
|
+
baseDir: ".",
|
|
3591
|
+
relativeDirPath: this.getSettablePaths().recommended.relativeDirPath,
|
|
3592
|
+
relativeFilePath: filename,
|
|
3593
|
+
frontmatter: validatedFrontmatter,
|
|
3594
|
+
body: content.trim(),
|
|
3595
|
+
validate
|
|
3596
|
+
});
|
|
3597
|
+
}
|
|
3598
|
+
getBody() {
|
|
3599
|
+
return this.body;
|
|
3600
|
+
}
|
|
3601
|
+
};
|
|
3602
|
+
|
|
3603
|
+
// src/rules/tool-rule.ts
|
|
3604
|
+
var ToolRule = class extends ToolFile {
|
|
3605
|
+
root;
|
|
3606
|
+
constructor({ root = false, ...rest }) {
|
|
3607
|
+
super(rest);
|
|
3608
|
+
this.root = root;
|
|
3609
|
+
}
|
|
3610
|
+
static async fromFile(_params) {
|
|
3611
|
+
throw new Error("Please implement this method in the subclass.");
|
|
3612
|
+
}
|
|
3613
|
+
static fromRulesyncRule(_params) {
|
|
3614
|
+
throw new Error("Please implement this method in the subclass.");
|
|
3615
|
+
}
|
|
3616
|
+
static buildToolRuleParamsDefault({
|
|
3617
|
+
baseDir = ".",
|
|
3618
|
+
rulesyncRule,
|
|
3619
|
+
validate = true,
|
|
3620
|
+
rootPath = { relativeDirPath: ".", relativeFilePath: "AGENTS.md" },
|
|
3621
|
+
nonRootPath = { relativeDirPath: ".agents/memories" }
|
|
3622
|
+
}) {
|
|
3623
|
+
const fileContent = rulesyncRule.getBody();
|
|
3624
|
+
return {
|
|
3625
|
+
baseDir,
|
|
3626
|
+
relativeDirPath: rulesyncRule.getFrontmatter().root ? rootPath.relativeDirPath : nonRootPath.relativeDirPath,
|
|
3627
|
+
relativeFilePath: rulesyncRule.getFrontmatter().root ? rootPath.relativeFilePath : rulesyncRule.getRelativeFilePath(),
|
|
3628
|
+
fileContent,
|
|
3629
|
+
validate,
|
|
3630
|
+
root: rulesyncRule.getFrontmatter().root ?? false
|
|
3631
|
+
};
|
|
3632
|
+
}
|
|
3633
|
+
toRulesyncRuleDefault() {
|
|
3634
|
+
return new RulesyncRule({
|
|
3635
|
+
baseDir: this.getBaseDir(),
|
|
3636
|
+
relativeDirPath: RULESYNC_RULES_DIR,
|
|
3637
|
+
relativeFilePath: this.getRelativeFilePath(),
|
|
3638
|
+
frontmatter: {
|
|
3639
|
+
root: this.isRoot(),
|
|
3640
|
+
targets: ["*"],
|
|
3641
|
+
description: "",
|
|
3642
|
+
globs: this.isRoot() ? ["**/*"] : []
|
|
3643
|
+
},
|
|
3644
|
+
body: this.getFileContent()
|
|
3645
|
+
});
|
|
3646
|
+
}
|
|
3647
|
+
isRoot() {
|
|
3648
|
+
return this.root;
|
|
3649
|
+
}
|
|
3650
|
+
static isTargetedByRulesyncRule(_rulesyncRule) {
|
|
3651
|
+
throw new Error("Please implement this method in the subclass.");
|
|
3652
|
+
}
|
|
3653
|
+
static isTargetedByRulesyncRuleDefault({
|
|
3654
|
+
rulesyncRule,
|
|
3655
|
+
toolTarget
|
|
3656
|
+
}) {
|
|
3657
|
+
const targets = rulesyncRule.getFrontmatter().targets;
|
|
3658
|
+
if (!targets) {
|
|
3659
|
+
return true;
|
|
3660
|
+
}
|
|
3661
|
+
if (targets.includes("*")) {
|
|
3662
|
+
return true;
|
|
3663
|
+
}
|
|
3664
|
+
if (targets.includes(toolTarget)) {
|
|
3165
3665
|
return true;
|
|
3166
3666
|
}
|
|
3167
3667
|
return false;
|
|
@@ -3194,8 +3694,8 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
|
|
|
3194
3694
|
validate = true
|
|
3195
3695
|
}) {
|
|
3196
3696
|
const isRoot = relativeFilePath === "AGENTS.md";
|
|
3197
|
-
const relativePath = isRoot ? "AGENTS.md" :
|
|
3198
|
-
const fileContent = await readFileContent(
|
|
3697
|
+
const relativePath = isRoot ? "AGENTS.md" : join35(".agents/memories", relativeFilePath);
|
|
3698
|
+
const fileContent = await readFileContent(join35(baseDir, relativePath));
|
|
3199
3699
|
return new _AgentsMdRule({
|
|
3200
3700
|
baseDir,
|
|
3201
3701
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -3235,7 +3735,7 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
|
|
|
3235
3735
|
};
|
|
3236
3736
|
|
|
3237
3737
|
// src/rules/amazonqcli-rule.ts
|
|
3238
|
-
import { join as
|
|
3738
|
+
import { join as join36 } from "path";
|
|
3239
3739
|
var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
|
|
3240
3740
|
static getSettablePaths() {
|
|
3241
3741
|
return {
|
|
@@ -3250,7 +3750,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
|
|
|
3250
3750
|
validate = true
|
|
3251
3751
|
}) {
|
|
3252
3752
|
const fileContent = await readFileContent(
|
|
3253
|
-
|
|
3753
|
+
join36(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
3254
3754
|
);
|
|
3255
3755
|
return new _AmazonQCliRule({
|
|
3256
3756
|
baseDir,
|
|
@@ -3290,7 +3790,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
|
|
|
3290
3790
|
};
|
|
3291
3791
|
|
|
3292
3792
|
// src/rules/augmentcode-legacy-rule.ts
|
|
3293
|
-
import { join as
|
|
3793
|
+
import { join as join37 } from "path";
|
|
3294
3794
|
var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
3295
3795
|
toRulesyncRule() {
|
|
3296
3796
|
const rulesyncFrontmatter = {
|
|
@@ -3350,8 +3850,8 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
|
3350
3850
|
}) {
|
|
3351
3851
|
const settablePaths = this.getSettablePaths();
|
|
3352
3852
|
const isRoot = relativeFilePath === settablePaths.root.relativeFilePath;
|
|
3353
|
-
const relativePath = isRoot ? settablePaths.root.relativeFilePath :
|
|
3354
|
-
const fileContent = await readFileContent(
|
|
3853
|
+
const relativePath = isRoot ? settablePaths.root.relativeFilePath : join37(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
|
|
3854
|
+
const fileContent = await readFileContent(join37(baseDir, relativePath));
|
|
3355
3855
|
return new _AugmentcodeLegacyRule({
|
|
3356
3856
|
baseDir,
|
|
3357
3857
|
relativeDirPath: isRoot ? settablePaths.root.relativeDirPath : settablePaths.nonRoot.relativeDirPath,
|
|
@@ -3364,7 +3864,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
|
3364
3864
|
};
|
|
3365
3865
|
|
|
3366
3866
|
// src/rules/augmentcode-rule.ts
|
|
3367
|
-
import { join as
|
|
3867
|
+
import { join as join38 } from "path";
|
|
3368
3868
|
var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
3369
3869
|
toRulesyncRule() {
|
|
3370
3870
|
return this.toRulesyncRuleDefault();
|
|
@@ -3396,7 +3896,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
|
3396
3896
|
validate = true
|
|
3397
3897
|
}) {
|
|
3398
3898
|
const fileContent = await readFileContent(
|
|
3399
|
-
|
|
3899
|
+
join38(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
3400
3900
|
);
|
|
3401
3901
|
const { body: content } = parseFrontmatter(fileContent);
|
|
3402
3902
|
return new _AugmentcodeRule({
|
|
@@ -3419,7 +3919,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
|
3419
3919
|
};
|
|
3420
3920
|
|
|
3421
3921
|
// src/rules/claudecode-rule.ts
|
|
3422
|
-
import { join as
|
|
3922
|
+
import { join as join39 } from "path";
|
|
3423
3923
|
var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
3424
3924
|
static getSettablePaths() {
|
|
3425
3925
|
return {
|
|
@@ -3438,8 +3938,8 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
3438
3938
|
validate = true
|
|
3439
3939
|
}) {
|
|
3440
3940
|
const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
|
|
3441
|
-
const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath :
|
|
3442
|
-
const fileContent = await readFileContent(
|
|
3941
|
+
const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join39(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
|
|
3942
|
+
const fileContent = await readFileContent(join39(baseDir, relativePath));
|
|
3443
3943
|
return new _ClaudecodeRule({
|
|
3444
3944
|
baseDir,
|
|
3445
3945
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -3479,10 +3979,10 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
3479
3979
|
};
|
|
3480
3980
|
|
|
3481
3981
|
// src/rules/cline-rule.ts
|
|
3482
|
-
import { join as
|
|
3483
|
-
import { z as
|
|
3484
|
-
var ClineRuleFrontmatterSchema =
|
|
3485
|
-
description:
|
|
3982
|
+
import { join as join40 } from "path";
|
|
3983
|
+
import { z as z17 } from "zod/mini";
|
|
3984
|
+
var ClineRuleFrontmatterSchema = z17.object({
|
|
3985
|
+
description: z17.string()
|
|
3486
3986
|
});
|
|
3487
3987
|
var ClineRule = class _ClineRule extends ToolRule {
|
|
3488
3988
|
static getSettablePaths() {
|
|
@@ -3524,7 +4024,7 @@ var ClineRule = class _ClineRule extends ToolRule {
|
|
|
3524
4024
|
validate = true
|
|
3525
4025
|
}) {
|
|
3526
4026
|
const fileContent = await readFileContent(
|
|
3527
|
-
|
|
4027
|
+
join40(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
3528
4028
|
);
|
|
3529
4029
|
return new _ClineRule({
|
|
3530
4030
|
baseDir,
|
|
@@ -3537,7 +4037,7 @@ var ClineRule = class _ClineRule extends ToolRule {
|
|
|
3537
4037
|
};
|
|
3538
4038
|
|
|
3539
4039
|
// src/rules/codexcli-rule.ts
|
|
3540
|
-
import { join as
|
|
4040
|
+
import { join as join41 } from "path";
|
|
3541
4041
|
var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
3542
4042
|
static getSettablePaths() {
|
|
3543
4043
|
return {
|
|
@@ -3556,8 +4056,8 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
3556
4056
|
validate = true
|
|
3557
4057
|
}) {
|
|
3558
4058
|
const isRoot = relativeFilePath === "AGENTS.md";
|
|
3559
|
-
const relativePath = isRoot ? "AGENTS.md" :
|
|
3560
|
-
const fileContent = await readFileContent(
|
|
4059
|
+
const relativePath = isRoot ? "AGENTS.md" : join41(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
|
|
4060
|
+
const fileContent = await readFileContent(join41(baseDir, relativePath));
|
|
3561
4061
|
return new _CodexcliRule({
|
|
3562
4062
|
baseDir,
|
|
3563
4063
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -3597,11 +4097,11 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
3597
4097
|
};
|
|
3598
4098
|
|
|
3599
4099
|
// src/rules/copilot-rule.ts
|
|
3600
|
-
import { join as
|
|
3601
|
-
import { z as
|
|
3602
|
-
var CopilotRuleFrontmatterSchema =
|
|
3603
|
-
description:
|
|
3604
|
-
applyTo:
|
|
4100
|
+
import { join as join42 } from "path";
|
|
4101
|
+
import { z as z18 } from "zod/mini";
|
|
4102
|
+
var CopilotRuleFrontmatterSchema = z18.object({
|
|
4103
|
+
description: z18.optional(z18.string()),
|
|
4104
|
+
applyTo: z18.optional(z18.string())
|
|
3605
4105
|
});
|
|
3606
4106
|
var CopilotRule = class _CopilotRule extends ToolRule {
|
|
3607
4107
|
frontmatter;
|
|
@@ -3689,11 +4189,11 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
3689
4189
|
validate = true
|
|
3690
4190
|
}) {
|
|
3691
4191
|
const isRoot = relativeFilePath === "copilot-instructions.md";
|
|
3692
|
-
const relativePath = isRoot ?
|
|
4192
|
+
const relativePath = isRoot ? join42(
|
|
3693
4193
|
this.getSettablePaths().root.relativeDirPath,
|
|
3694
4194
|
this.getSettablePaths().root.relativeFilePath
|
|
3695
|
-
) :
|
|
3696
|
-
const fileContent = await readFileContent(
|
|
4195
|
+
) : join42(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
|
|
4196
|
+
const fileContent = await readFileContent(join42(baseDir, relativePath));
|
|
3697
4197
|
if (isRoot) {
|
|
3698
4198
|
return new _CopilotRule({
|
|
3699
4199
|
baseDir,
|
|
@@ -3712,7 +4212,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
3712
4212
|
const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
|
|
3713
4213
|
if (!result.success) {
|
|
3714
4214
|
throw new Error(
|
|
3715
|
-
`Invalid frontmatter in ${
|
|
4215
|
+
`Invalid frontmatter in ${join42(baseDir, relativeFilePath)}: ${result.error.message}`
|
|
3716
4216
|
);
|
|
3717
4217
|
}
|
|
3718
4218
|
return new _CopilotRule({
|
|
@@ -3751,12 +4251,12 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
3751
4251
|
};
|
|
3752
4252
|
|
|
3753
4253
|
// src/rules/cursor-rule.ts
|
|
3754
|
-
import { basename as
|
|
3755
|
-
import { z as
|
|
3756
|
-
var CursorRuleFrontmatterSchema =
|
|
3757
|
-
description:
|
|
3758
|
-
globs:
|
|
3759
|
-
alwaysApply:
|
|
4254
|
+
import { basename as basename15, join as join43 } from "path";
|
|
4255
|
+
import { z as z19 } from "zod/mini";
|
|
4256
|
+
var CursorRuleFrontmatterSchema = z19.object({
|
|
4257
|
+
description: z19.optional(z19.string()),
|
|
4258
|
+
globs: z19.optional(z19.string()),
|
|
4259
|
+
alwaysApply: z19.optional(z19.boolean())
|
|
3760
4260
|
});
|
|
3761
4261
|
var CursorRule = class _CursorRule extends ToolRule {
|
|
3762
4262
|
frontmatter;
|
|
@@ -3881,19 +4381,19 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
3881
4381
|
validate = true
|
|
3882
4382
|
}) {
|
|
3883
4383
|
const fileContent = await readFileContent(
|
|
3884
|
-
|
|
4384
|
+
join43(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
3885
4385
|
);
|
|
3886
4386
|
const { frontmatter, body: content } = _CursorRule.parseCursorFrontmatter(fileContent);
|
|
3887
4387
|
const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
|
|
3888
4388
|
if (!result.success) {
|
|
3889
4389
|
throw new Error(
|
|
3890
|
-
`Invalid frontmatter in ${
|
|
4390
|
+
`Invalid frontmatter in ${join43(baseDir, relativeFilePath)}: ${result.error.message}`
|
|
3891
4391
|
);
|
|
3892
4392
|
}
|
|
3893
4393
|
return new _CursorRule({
|
|
3894
4394
|
baseDir,
|
|
3895
4395
|
relativeDirPath: this.getSettablePaths().nonRoot.relativeDirPath,
|
|
3896
|
-
relativeFilePath:
|
|
4396
|
+
relativeFilePath: basename15(relativeFilePath),
|
|
3897
4397
|
frontmatter: result.data,
|
|
3898
4398
|
body: content.trim(),
|
|
3899
4399
|
validate
|
|
@@ -3925,7 +4425,7 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
3925
4425
|
};
|
|
3926
4426
|
|
|
3927
4427
|
// src/rules/geminicli-rule.ts
|
|
3928
|
-
import { join as
|
|
4428
|
+
import { join as join44 } from "path";
|
|
3929
4429
|
var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
3930
4430
|
static getSettablePaths() {
|
|
3931
4431
|
return {
|
|
@@ -3944,8 +4444,8 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
3944
4444
|
validate = true
|
|
3945
4445
|
}) {
|
|
3946
4446
|
const isRoot = relativeFilePath === "GEMINI.md";
|
|
3947
|
-
const relativePath = isRoot ? "GEMINI.md" :
|
|
3948
|
-
const fileContent = await readFileContent(
|
|
4447
|
+
const relativePath = isRoot ? "GEMINI.md" : join44(".gemini/memories", relativeFilePath);
|
|
4448
|
+
const fileContent = await readFileContent(join44(baseDir, relativePath));
|
|
3949
4449
|
return new _GeminiCliRule({
|
|
3950
4450
|
baseDir,
|
|
3951
4451
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -3985,7 +4485,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
3985
4485
|
};
|
|
3986
4486
|
|
|
3987
4487
|
// src/rules/junie-rule.ts
|
|
3988
|
-
import { join as
|
|
4488
|
+
import { join as join45 } from "path";
|
|
3989
4489
|
var JunieRule = class _JunieRule extends ToolRule {
|
|
3990
4490
|
static getSettablePaths() {
|
|
3991
4491
|
return {
|
|
@@ -4004,8 +4504,8 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
4004
4504
|
validate = true
|
|
4005
4505
|
}) {
|
|
4006
4506
|
const isRoot = relativeFilePath === "guidelines.md";
|
|
4007
|
-
const relativePath = isRoot ? "guidelines.md" :
|
|
4008
|
-
const fileContent = await readFileContent(
|
|
4507
|
+
const relativePath = isRoot ? "guidelines.md" : join45(".junie/memories", relativeFilePath);
|
|
4508
|
+
const fileContent = await readFileContent(join45(baseDir, relativePath));
|
|
4009
4509
|
return new _JunieRule({
|
|
4010
4510
|
baseDir,
|
|
4011
4511
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -4045,7 +4545,7 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
4045
4545
|
};
|
|
4046
4546
|
|
|
4047
4547
|
// src/rules/kiro-rule.ts
|
|
4048
|
-
import { join as
|
|
4548
|
+
import { join as join46 } from "path";
|
|
4049
4549
|
var KiroRule = class _KiroRule extends ToolRule {
|
|
4050
4550
|
static getSettablePaths() {
|
|
4051
4551
|
return {
|
|
@@ -4060,7 +4560,7 @@ var KiroRule = class _KiroRule extends ToolRule {
|
|
|
4060
4560
|
validate = true
|
|
4061
4561
|
}) {
|
|
4062
4562
|
const fileContent = await readFileContent(
|
|
4063
|
-
|
|
4563
|
+
join46(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
4064
4564
|
);
|
|
4065
4565
|
return new _KiroRule({
|
|
4066
4566
|
baseDir,
|
|
@@ -4100,7 +4600,7 @@ var KiroRule = class _KiroRule extends ToolRule {
|
|
|
4100
4600
|
};
|
|
4101
4601
|
|
|
4102
4602
|
// src/rules/opencode-rule.ts
|
|
4103
|
-
import { join as
|
|
4603
|
+
import { join as join47 } from "path";
|
|
4104
4604
|
var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
4105
4605
|
static getSettablePaths() {
|
|
4106
4606
|
return {
|
|
@@ -4119,8 +4619,8 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
|
4119
4619
|
validate = true
|
|
4120
4620
|
}) {
|
|
4121
4621
|
const isRoot = relativeFilePath === "AGENTS.md";
|
|
4122
|
-
const relativePath = isRoot ? "AGENTS.md" :
|
|
4123
|
-
const fileContent = await readFileContent(
|
|
4622
|
+
const relativePath = isRoot ? "AGENTS.md" : join47(".opencode/memories", relativeFilePath);
|
|
4623
|
+
const fileContent = await readFileContent(join47(baseDir, relativePath));
|
|
4124
4624
|
return new _OpenCodeRule({
|
|
4125
4625
|
baseDir,
|
|
4126
4626
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -4160,7 +4660,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
|
4160
4660
|
};
|
|
4161
4661
|
|
|
4162
4662
|
// src/rules/qwencode-rule.ts
|
|
4163
|
-
import { join as
|
|
4663
|
+
import { join as join48 } from "path";
|
|
4164
4664
|
var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
4165
4665
|
static getSettablePaths() {
|
|
4166
4666
|
return {
|
|
@@ -4179,8 +4679,8 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
|
4179
4679
|
validate = true
|
|
4180
4680
|
}) {
|
|
4181
4681
|
const isRoot = relativeFilePath === "QWEN.md";
|
|
4182
|
-
const relativePath = isRoot ? "QWEN.md" :
|
|
4183
|
-
const fileContent = await readFileContent(
|
|
4682
|
+
const relativePath = isRoot ? "QWEN.md" : join48(".qwen/memories", relativeFilePath);
|
|
4683
|
+
const fileContent = await readFileContent(join48(baseDir, relativePath));
|
|
4184
4684
|
return new _QwencodeRule({
|
|
4185
4685
|
baseDir,
|
|
4186
4686
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -4217,7 +4717,7 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
|
4217
4717
|
};
|
|
4218
4718
|
|
|
4219
4719
|
// src/rules/roo-rule.ts
|
|
4220
|
-
import { join as
|
|
4720
|
+
import { join as join49 } from "path";
|
|
4221
4721
|
var RooRule = class _RooRule extends ToolRule {
|
|
4222
4722
|
static getSettablePaths() {
|
|
4223
4723
|
return {
|
|
@@ -4232,7 +4732,7 @@ var RooRule = class _RooRule extends ToolRule {
|
|
|
4232
4732
|
validate = true
|
|
4233
4733
|
}) {
|
|
4234
4734
|
const fileContent = await readFileContent(
|
|
4235
|
-
|
|
4735
|
+
join49(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
4236
4736
|
);
|
|
4237
4737
|
return new _RooRule({
|
|
4238
4738
|
baseDir,
|
|
@@ -4287,7 +4787,7 @@ var RooRule = class _RooRule extends ToolRule {
|
|
|
4287
4787
|
};
|
|
4288
4788
|
|
|
4289
4789
|
// src/rules/warp-rule.ts
|
|
4290
|
-
import { join as
|
|
4790
|
+
import { join as join50 } from "path";
|
|
4291
4791
|
var WarpRule = class _WarpRule extends ToolRule {
|
|
4292
4792
|
constructor({ fileContent, root, ...rest }) {
|
|
4293
4793
|
super({
|
|
@@ -4313,8 +4813,8 @@ var WarpRule = class _WarpRule extends ToolRule {
|
|
|
4313
4813
|
validate = true
|
|
4314
4814
|
}) {
|
|
4315
4815
|
const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
|
|
4316
|
-
const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath :
|
|
4317
|
-
const fileContent = await readFileContent(
|
|
4816
|
+
const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join50(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
|
|
4817
|
+
const fileContent = await readFileContent(join50(baseDir, relativePath));
|
|
4318
4818
|
return new _WarpRule({
|
|
4319
4819
|
baseDir,
|
|
4320
4820
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : ".warp",
|
|
@@ -4354,7 +4854,7 @@ var WarpRule = class _WarpRule extends ToolRule {
|
|
|
4354
4854
|
};
|
|
4355
4855
|
|
|
4356
4856
|
// src/rules/windsurf-rule.ts
|
|
4357
|
-
import { join as
|
|
4857
|
+
import { join as join51 } from "path";
|
|
4358
4858
|
var WindsurfRule = class _WindsurfRule extends ToolRule {
|
|
4359
4859
|
static getSettablePaths() {
|
|
4360
4860
|
return {
|
|
@@ -4369,7 +4869,7 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
|
|
|
4369
4869
|
validate = true
|
|
4370
4870
|
}) {
|
|
4371
4871
|
const fileContent = await readFileContent(
|
|
4372
|
-
|
|
4872
|
+
join51(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
4373
4873
|
);
|
|
4374
4874
|
return new _WindsurfRule({
|
|
4375
4875
|
baseDir,
|
|
@@ -4427,7 +4927,7 @@ var rulesProcessorToolTargets = [
|
|
|
4427
4927
|
"warp",
|
|
4428
4928
|
"windsurf"
|
|
4429
4929
|
];
|
|
4430
|
-
var RulesProcessorToolTargetSchema =
|
|
4930
|
+
var RulesProcessorToolTargetSchema = z20.enum(rulesProcessorToolTargets);
|
|
4431
4931
|
var RulesProcessor = class extends FeatureProcessor {
|
|
4432
4932
|
toolTarget;
|
|
4433
4933
|
simulateCommands;
|
|
@@ -4606,7 +5106,8 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
4606
5106
|
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
4607
5107
|
}
|
|
4608
5108
|
}).filter((rule) => rule !== null);
|
|
4609
|
-
|
|
5109
|
+
const isSimulated = this.simulateCommands || this.simulateSubagents;
|
|
5110
|
+
if (isSimulated && this.toolTarget === "cursor") {
|
|
4610
5111
|
toolRules.push(
|
|
4611
5112
|
new CursorRule({
|
|
4612
5113
|
baseDir: this.baseDir,
|
|
@@ -4625,6 +5126,22 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
4625
5126
|
})
|
|
4626
5127
|
);
|
|
4627
5128
|
}
|
|
5129
|
+
if (isSimulated && this.toolTarget === "roo") {
|
|
5130
|
+
toolRules.push(
|
|
5131
|
+
new RooRule({
|
|
5132
|
+
baseDir: this.baseDir,
|
|
5133
|
+
relativeDirPath: RooRule.getSettablePaths().nonRoot.relativeDirPath,
|
|
5134
|
+
relativeFilePath: "additional-conventions.md",
|
|
5135
|
+
fileContent: this.generateAdditionalConventionsSection({
|
|
5136
|
+
commands: { relativeDirPath: RooCommand.getSettablePaths().relativeDirPath },
|
|
5137
|
+
subagents: {
|
|
5138
|
+
relativeDirPath: RooSubagent.getSettablePaths().relativeDirPath
|
|
5139
|
+
}
|
|
5140
|
+
}),
|
|
5141
|
+
validate: true
|
|
5142
|
+
})
|
|
5143
|
+
);
|
|
5144
|
+
}
|
|
4628
5145
|
const rootRuleIndex = toolRules.findIndex((rule) => rule.isRoot());
|
|
4629
5146
|
if (rootRuleIndex === -1) {
|
|
4630
5147
|
return toolRules;
|
|
@@ -4678,7 +5195,12 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
4678
5195
|
case "geminicli": {
|
|
4679
5196
|
const rootRule = toolRules[rootRuleIndex];
|
|
4680
5197
|
rootRule?.setFileContent(
|
|
4681
|
-
this.generateXmlReferencesSection(toolRules) +
|
|
5198
|
+
this.generateXmlReferencesSection(toolRules) + this.generateAdditionalConventionsSection({
|
|
5199
|
+
commands: { relativeDirPath: GeminiCliCommand.getSettablePaths().relativeDirPath },
|
|
5200
|
+
subagents: {
|
|
5201
|
+
relativeDirPath: GeminiCliSubagent.getSettablePaths().relativeDirPath
|
|
5202
|
+
}
|
|
5203
|
+
}) + rootRule.getFileContent()
|
|
4682
5204
|
);
|
|
4683
5205
|
return toolRules;
|
|
4684
5206
|
}
|
|
@@ -4726,17 +5248,17 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
4726
5248
|
* Load and parse rulesync rule files from .rulesync/rules/ directory
|
|
4727
5249
|
*/
|
|
4728
5250
|
async loadRulesyncFiles() {
|
|
4729
|
-
const files = await findFilesByGlobs(
|
|
5251
|
+
const files = await findFilesByGlobs(join52(RULESYNC_RULES_DIR, "*.md"));
|
|
4730
5252
|
logger.debug(`Found ${files.length} rulesync files`);
|
|
4731
5253
|
return Promise.all(
|
|
4732
|
-
files.map((file) => RulesyncRule.fromFile({ relativeFilePath:
|
|
5254
|
+
files.map((file) => RulesyncRule.fromFile({ relativeFilePath: basename16(file) }))
|
|
4733
5255
|
);
|
|
4734
5256
|
}
|
|
4735
5257
|
async loadRulesyncFilesLegacy() {
|
|
4736
|
-
const legacyFiles = await findFilesByGlobs(
|
|
5258
|
+
const legacyFiles = await findFilesByGlobs(join52(RULESYNC_RULES_DIR_LEGACY, "*.md"));
|
|
4737
5259
|
logger.debug(`Found ${legacyFiles.length} legacy rulesync files`);
|
|
4738
5260
|
return Promise.all(
|
|
4739
|
-
legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath:
|
|
5261
|
+
legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath: basename16(file) }))
|
|
4740
5262
|
);
|
|
4741
5263
|
}
|
|
4742
5264
|
/**
|
|
@@ -4797,803 +5319,405 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
4797
5319
|
return [];
|
|
4798
5320
|
}
|
|
4799
5321
|
const rootFilePaths = await findFilesByGlobs(
|
|
4800
|
-
|
|
5322
|
+
join52(this.baseDir, root.relativeDirPath ?? ".", root.relativeFilePath)
|
|
4801
5323
|
);
|
|
4802
5324
|
return await Promise.all(
|
|
4803
5325
|
rootFilePaths.map(
|
|
4804
5326
|
(filePath) => root.fromFile({
|
|
4805
5327
|
baseDir: this.baseDir,
|
|
4806
|
-
relativeFilePath:
|
|
4807
|
-
})
|
|
4808
|
-
)
|
|
4809
|
-
);
|
|
4810
|
-
})();
|
|
4811
|
-
logger.debug(`Found ${rootToolRules.length} root tool rule files`);
|
|
4812
|
-
const nonRootToolRules = await (async () => {
|
|
4813
|
-
if (!nonRoot) {
|
|
4814
|
-
return [];
|
|
4815
|
-
}
|
|
4816
|
-
const nonRootFilePaths = await findFilesByGlobs(
|
|
4817
|
-
join49(this.baseDir, nonRoot.relativeDirPath, `*.${nonRoot.extension}`)
|
|
4818
|
-
);
|
|
4819
|
-
return await Promise.all(
|
|
4820
|
-
nonRootFilePaths.map(
|
|
4821
|
-
(filePath) => nonRoot.fromFile({
|
|
4822
|
-
baseDir: this.baseDir,
|
|
4823
|
-
relativeFilePath: basename14(filePath)
|
|
5328
|
+
relativeFilePath: basename16(filePath)
|
|
4824
5329
|
})
|
|
4825
5330
|
)
|
|
4826
5331
|
);
|
|
4827
|
-
})();
|
|
4828
|
-
logger.debug(`Found ${
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
* Load AGENTS.md rule configuration
|
|
4833
|
-
*/
|
|
4834
|
-
async loadAgentsmdRules() {
|
|
4835
|
-
const settablePaths = AgentsMdRule.getSettablePaths();
|
|
4836
|
-
return await this.loadToolRulesDefault({
|
|
4837
|
-
root: {
|
|
4838
|
-
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
4839
|
-
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
4840
|
-
fromFile: (params) => AgentsMdRule.fromFile(params)
|
|
4841
|
-
},
|
|
4842
|
-
nonRoot: {
|
|
4843
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
4844
|
-
fromFile: (params) => AgentsMdRule.fromFile(params),
|
|
4845
|
-
extension: "md"
|
|
4846
|
-
}
|
|
4847
|
-
});
|
|
4848
|
-
}
|
|
4849
|
-
async loadWarpRules() {
|
|
4850
|
-
const settablePaths = WarpRule.getSettablePaths();
|
|
4851
|
-
return await this.loadToolRulesDefault({
|
|
4852
|
-
root: {
|
|
4853
|
-
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
4854
|
-
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
4855
|
-
fromFile: (params) => WarpRule.fromFile(params)
|
|
4856
|
-
},
|
|
4857
|
-
nonRoot: {
|
|
4858
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
4859
|
-
fromFile: (params) => WarpRule.fromFile(params),
|
|
4860
|
-
extension: "md"
|
|
4861
|
-
}
|
|
4862
|
-
});
|
|
4863
|
-
}
|
|
4864
|
-
/**
|
|
4865
|
-
* Load Amazon Q Developer CLI rule configurations from .amazonq/rules/ directory
|
|
4866
|
-
*/
|
|
4867
|
-
async loadAmazonqcliRules() {
|
|
4868
|
-
const settablePaths = AmazonQCliRule.getSettablePaths();
|
|
4869
|
-
return await this.loadToolRulesDefault({
|
|
4870
|
-
nonRoot: {
|
|
4871
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
4872
|
-
fromFile: (params) => AmazonQCliRule.fromFile(params),
|
|
4873
|
-
extension: "md"
|
|
4874
|
-
}
|
|
4875
|
-
});
|
|
4876
|
-
}
|
|
4877
|
-
/**
|
|
4878
|
-
* Load AugmentCode rule configurations from .augment/rules/ directory
|
|
4879
|
-
*/
|
|
4880
|
-
async loadAugmentcodeRules() {
|
|
4881
|
-
const settablePaths = AugmentcodeRule.getSettablePaths();
|
|
4882
|
-
return await this.loadToolRulesDefault({
|
|
4883
|
-
nonRoot: {
|
|
4884
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
4885
|
-
fromFile: (params) => AugmentcodeRule.fromFile(params),
|
|
4886
|
-
extension: "md"
|
|
4887
|
-
}
|
|
4888
|
-
});
|
|
4889
|
-
}
|
|
4890
|
-
/**
|
|
4891
|
-
* Load AugmentCode legacy rule configuration from .augment-guidelines file and .augment/rules/ directory
|
|
4892
|
-
*/
|
|
4893
|
-
async loadAugmentcodeLegacyRules() {
|
|
4894
|
-
const settablePaths = AugmentcodeLegacyRule.getSettablePaths();
|
|
4895
|
-
return await this.loadToolRulesDefault({
|
|
4896
|
-
root: {
|
|
4897
|
-
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
4898
|
-
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
4899
|
-
fromFile: (params) => AugmentcodeLegacyRule.fromFile(params)
|
|
4900
|
-
},
|
|
4901
|
-
nonRoot: {
|
|
4902
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
4903
|
-
fromFile: (params) => AugmentcodeLegacyRule.fromFile(params),
|
|
4904
|
-
extension: "md"
|
|
4905
|
-
}
|
|
4906
|
-
});
|
|
4907
|
-
}
|
|
4908
|
-
/**
|
|
4909
|
-
* Load Claude Code rule configuration from CLAUDE.md file
|
|
4910
|
-
*/
|
|
4911
|
-
async loadClaudecodeRules() {
|
|
4912
|
-
const settablePaths = ClaudecodeRule.getSettablePaths();
|
|
4913
|
-
return await this.loadToolRulesDefault({
|
|
4914
|
-
root: {
|
|
4915
|
-
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
4916
|
-
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
4917
|
-
fromFile: (params) => ClaudecodeRule.fromFile(params)
|
|
4918
|
-
},
|
|
4919
|
-
nonRoot: {
|
|
4920
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
4921
|
-
fromFile: (params) => ClaudecodeRule.fromFile(params),
|
|
4922
|
-
extension: "md"
|
|
4923
|
-
}
|
|
4924
|
-
});
|
|
4925
|
-
}
|
|
4926
|
-
/**
|
|
4927
|
-
* Load Cline rule configurations from .clinerules/ directory
|
|
4928
|
-
*/
|
|
4929
|
-
async loadClineRules() {
|
|
4930
|
-
const settablePaths = ClineRule.getSettablePaths();
|
|
4931
|
-
return await this.loadToolRulesDefault({
|
|
4932
|
-
nonRoot: {
|
|
4933
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
4934
|
-
fromFile: (params) => ClineRule.fromFile(params),
|
|
4935
|
-
extension: "md"
|
|
4936
|
-
}
|
|
4937
|
-
});
|
|
4938
|
-
}
|
|
4939
|
-
/**
|
|
4940
|
-
* Load OpenAI Codex CLI rule configuration from AGENTS.md and .codex/memories/*.md files
|
|
4941
|
-
*/
|
|
4942
|
-
async loadCodexcliRules() {
|
|
4943
|
-
const settablePaths = CodexcliRule.getSettablePaths();
|
|
4944
|
-
return await this.loadToolRulesDefault({
|
|
4945
|
-
root: {
|
|
4946
|
-
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
4947
|
-
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
4948
|
-
fromFile: (params) => CodexcliRule.fromFile(params)
|
|
4949
|
-
},
|
|
4950
|
-
nonRoot: {
|
|
4951
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
4952
|
-
fromFile: (params) => CodexcliRule.fromFile(params),
|
|
4953
|
-
extension: "md"
|
|
4954
|
-
}
|
|
4955
|
-
});
|
|
4956
|
-
}
|
|
4957
|
-
/**
|
|
4958
|
-
* Load GitHub Copilot rule configuration from .github/copilot-instructions.md file
|
|
4959
|
-
*/
|
|
4960
|
-
async loadCopilotRules() {
|
|
4961
|
-
const settablePaths = CopilotRule.getSettablePaths();
|
|
4962
|
-
return await this.loadToolRulesDefault({
|
|
4963
|
-
root: {
|
|
4964
|
-
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
4965
|
-
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
4966
|
-
fromFile: (params) => CopilotRule.fromFile(params)
|
|
4967
|
-
},
|
|
4968
|
-
nonRoot: {
|
|
4969
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
4970
|
-
fromFile: (params) => CopilotRule.fromFile(params),
|
|
4971
|
-
extension: "md"
|
|
4972
|
-
}
|
|
4973
|
-
});
|
|
4974
|
-
}
|
|
4975
|
-
/**
|
|
4976
|
-
* Load Cursor rule configurations from .cursor/rules/ directory
|
|
4977
|
-
*/
|
|
4978
|
-
async loadCursorRules() {
|
|
4979
|
-
const settablePaths = CursorRule.getSettablePaths();
|
|
4980
|
-
return await this.loadToolRulesDefault({
|
|
4981
|
-
nonRoot: {
|
|
4982
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
4983
|
-
fromFile: (params) => CursorRule.fromFile(params),
|
|
4984
|
-
extension: "mdc"
|
|
4985
|
-
}
|
|
4986
|
-
});
|
|
4987
|
-
}
|
|
4988
|
-
/**
|
|
4989
|
-
* Load Gemini CLI rule configuration from GEMINI.md file
|
|
4990
|
-
*/
|
|
4991
|
-
async loadGeminicliRules() {
|
|
4992
|
-
const settablePaths = GeminiCliRule.getSettablePaths();
|
|
4993
|
-
return await this.loadToolRulesDefault({
|
|
4994
|
-
root: {
|
|
4995
|
-
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
4996
|
-
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
4997
|
-
fromFile: (params) => GeminiCliRule.fromFile(params)
|
|
4998
|
-
},
|
|
4999
|
-
nonRoot: {
|
|
5000
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5001
|
-
fromFile: (params) => GeminiCliRule.fromFile(params),
|
|
5002
|
-
extension: "md"
|
|
5003
|
-
}
|
|
5004
|
-
});
|
|
5005
|
-
}
|
|
5006
|
-
/**
|
|
5007
|
-
* Load JetBrains Junie rule configuration from .junie/guidelines.md file
|
|
5008
|
-
*/
|
|
5009
|
-
async loadJunieRules() {
|
|
5010
|
-
const settablePaths = JunieRule.getSettablePaths();
|
|
5011
|
-
return await this.loadToolRulesDefault({
|
|
5012
|
-
root: {
|
|
5013
|
-
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
5014
|
-
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
5015
|
-
fromFile: (params) => JunieRule.fromFile(params)
|
|
5016
|
-
},
|
|
5017
|
-
nonRoot: {
|
|
5018
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5019
|
-
fromFile: (params) => JunieRule.fromFile(params),
|
|
5020
|
-
extension: "md"
|
|
5021
|
-
}
|
|
5022
|
-
});
|
|
5023
|
-
}
|
|
5024
|
-
/**
|
|
5025
|
-
* Load Kiro rule configurations from .kiro/steering/ directory
|
|
5026
|
-
*/
|
|
5027
|
-
async loadKiroRules() {
|
|
5028
|
-
const settablePaths = KiroRule.getSettablePaths();
|
|
5029
|
-
return await this.loadToolRulesDefault({
|
|
5030
|
-
nonRoot: {
|
|
5031
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5032
|
-
fromFile: (params) => KiroRule.fromFile(params),
|
|
5033
|
-
extension: "md"
|
|
5332
|
+
})();
|
|
5333
|
+
logger.debug(`Found ${rootToolRules.length} root tool rule files`);
|
|
5334
|
+
const nonRootToolRules = await (async () => {
|
|
5335
|
+
if (!nonRoot) {
|
|
5336
|
+
return [];
|
|
5034
5337
|
}
|
|
5035
|
-
|
|
5338
|
+
const nonRootFilePaths = await findFilesByGlobs(
|
|
5339
|
+
join52(this.baseDir, nonRoot.relativeDirPath, `*.${nonRoot.extension}`)
|
|
5340
|
+
);
|
|
5341
|
+
return await Promise.all(
|
|
5342
|
+
nonRootFilePaths.map(
|
|
5343
|
+
(filePath) => nonRoot.fromFile({
|
|
5344
|
+
baseDir: this.baseDir,
|
|
5345
|
+
relativeFilePath: basename16(filePath)
|
|
5346
|
+
})
|
|
5347
|
+
)
|
|
5348
|
+
);
|
|
5349
|
+
})();
|
|
5350
|
+
logger.debug(`Found ${nonRootToolRules.length} non-root tool rule files`);
|
|
5351
|
+
return [...rootToolRules, ...nonRootToolRules];
|
|
5036
5352
|
}
|
|
5037
5353
|
/**
|
|
5038
|
-
* Load
|
|
5354
|
+
* Load AGENTS.md rule configuration
|
|
5039
5355
|
*/
|
|
5040
|
-
async
|
|
5041
|
-
const settablePaths =
|
|
5356
|
+
async loadAgentsmdRules() {
|
|
5357
|
+
const settablePaths = AgentsMdRule.getSettablePaths();
|
|
5042
5358
|
return await this.loadToolRulesDefault({
|
|
5043
5359
|
root: {
|
|
5044
5360
|
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
5045
5361
|
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
5046
|
-
fromFile: (params) =>
|
|
5362
|
+
fromFile: (params) => AgentsMdRule.fromFile(params)
|
|
5047
5363
|
},
|
|
5048
5364
|
nonRoot: {
|
|
5049
5365
|
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5050
|
-
fromFile: (params) =>
|
|
5366
|
+
fromFile: (params) => AgentsMdRule.fromFile(params),
|
|
5051
5367
|
extension: "md"
|
|
5052
5368
|
}
|
|
5053
5369
|
});
|
|
5054
5370
|
}
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
*/
|
|
5058
|
-
async loadQwencodeRules() {
|
|
5059
|
-
const settablePaths = QwencodeRule.getSettablePaths();
|
|
5371
|
+
async loadWarpRules() {
|
|
5372
|
+
const settablePaths = WarpRule.getSettablePaths();
|
|
5060
5373
|
return await this.loadToolRulesDefault({
|
|
5061
5374
|
root: {
|
|
5062
5375
|
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
5063
5376
|
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
5064
|
-
fromFile: (params) =>
|
|
5377
|
+
fromFile: (params) => WarpRule.fromFile(params)
|
|
5065
5378
|
},
|
|
5066
5379
|
nonRoot: {
|
|
5067
5380
|
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5068
|
-
fromFile: (params) =>
|
|
5069
|
-
extension: "md"
|
|
5070
|
-
}
|
|
5071
|
-
});
|
|
5072
|
-
}
|
|
5073
|
-
/**
|
|
5074
|
-
* Load Roo Code rule configurations from .roo/rules/ directory
|
|
5075
|
-
*/
|
|
5076
|
-
async loadRooRules() {
|
|
5077
|
-
const settablePaths = RooRule.getSettablePaths();
|
|
5078
|
-
return await this.loadToolRulesDefault({
|
|
5079
|
-
nonRoot: {
|
|
5080
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5081
|
-
fromFile: (params) => RooRule.fromFile(params),
|
|
5082
|
-
extension: "md"
|
|
5083
|
-
}
|
|
5084
|
-
});
|
|
5085
|
-
}
|
|
5086
|
-
/**
|
|
5087
|
-
* Load Windsurf rule configurations from .windsurf/rules/ directory
|
|
5088
|
-
*/
|
|
5089
|
-
async loadWindsurfRules() {
|
|
5090
|
-
const settablePaths = WindsurfRule.getSettablePaths();
|
|
5091
|
-
return await this.loadToolRulesDefault({
|
|
5092
|
-
nonRoot: {
|
|
5093
|
-
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5094
|
-
fromFile: (params) => WindsurfRule.fromFile(params),
|
|
5381
|
+
fromFile: (params) => WarpRule.fromFile(params),
|
|
5095
5382
|
extension: "md"
|
|
5096
5383
|
}
|
|
5097
5384
|
});
|
|
5098
5385
|
}
|
|
5099
|
-
/**
|
|
5100
|
-
*
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
return
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
return "";
|
|
5110
|
-
}
|
|
5111
|
-
const lines = [];
|
|
5112
|
-
lines.push(
|
|
5113
|
-
"Please also reference the following documents as needed. In this case, `@` stands for the project root directory."
|
|
5114
|
-
);
|
|
5115
|
-
lines.push("");
|
|
5116
|
-
const documentsData = {
|
|
5117
|
-
Documents: {
|
|
5118
|
-
Document: toolRulesWithoutRoot.map((rule) => {
|
|
5119
|
-
const rulesyncRule = rule.toRulesyncRule();
|
|
5120
|
-
const frontmatter = rulesyncRule.getFrontmatter();
|
|
5121
|
-
const relativePath = `@${rule.getRelativePathFromCwd()}`;
|
|
5122
|
-
const document = {
|
|
5123
|
-
Path: relativePath
|
|
5124
|
-
};
|
|
5125
|
-
if (frontmatter.description) {
|
|
5126
|
-
document.Description = frontmatter.description;
|
|
5127
|
-
}
|
|
5128
|
-
if (frontmatter.globs && frontmatter.globs.length > 0) {
|
|
5129
|
-
document.FilePatterns = frontmatter.globs.join(", ");
|
|
5130
|
-
}
|
|
5131
|
-
return document;
|
|
5132
|
-
})
|
|
5133
|
-
}
|
|
5134
|
-
};
|
|
5135
|
-
const builder = new XMLBuilder({
|
|
5136
|
-
format: true,
|
|
5137
|
-
ignoreAttributes: false,
|
|
5138
|
-
suppressEmptyNode: false
|
|
5139
|
-
});
|
|
5140
|
-
const xmlContent = builder.build(documentsData);
|
|
5141
|
-
lines.push(xmlContent);
|
|
5142
|
-
return lines.join("\n") + "\n";
|
|
5143
|
-
}
|
|
5144
|
-
generateReferencesSection(toolRules) {
|
|
5145
|
-
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot());
|
|
5146
|
-
if (toolRulesWithoutRoot.length === 0) {
|
|
5147
|
-
return "";
|
|
5148
|
-
}
|
|
5149
|
-
const lines = [];
|
|
5150
|
-
lines.push("Please also reference the following documents as needed:");
|
|
5151
|
-
lines.push("");
|
|
5152
|
-
for (const rule of toolRulesWithoutRoot) {
|
|
5153
|
-
const rulesyncRule = rule.toRulesyncRule();
|
|
5154
|
-
const frontmatter = rulesyncRule.getFrontmatter();
|
|
5155
|
-
const escapedDescription = frontmatter.description?.replace(/"/g, '\\"');
|
|
5156
|
-
const globsText = frontmatter.globs?.join(",");
|
|
5157
|
-
lines.push(
|
|
5158
|
-
`@${rule.getRelativePathFromCwd()} description: "${escapedDescription}" globs: "${globsText}"`
|
|
5159
|
-
);
|
|
5160
|
-
}
|
|
5161
|
-
return lines.join("\n") + "\n";
|
|
5162
|
-
}
|
|
5163
|
-
generateAdditionalConventionsSection({
|
|
5164
|
-
commands,
|
|
5165
|
-
subagents
|
|
5166
|
-
}) {
|
|
5167
|
-
return `# Additional Conventions Beyond the Built-in Functions
|
|
5168
|
-
|
|
5169
|
-
As this project's AI coding tool, you must follow the additional conventions below, in addition to the built-in functions.
|
|
5170
|
-
|
|
5171
|
-
${this.simulateCommands ? `## Simulated Custom Slash Commands
|
|
5172
|
-
|
|
5173
|
-
Custom slash commands allow you to define frequently-used prompts as Markdown files that you can execute.
|
|
5174
|
-
|
|
5175
|
-
### Syntax
|
|
5176
|
-
|
|
5177
|
-
Users can use following syntax to invoke a custom command.
|
|
5178
|
-
|
|
5179
|
-
\`\`\`txt
|
|
5180
|
-
s/<command> [arguments]
|
|
5181
|
-
\`\`\`
|
|
5182
|
-
|
|
5183
|
-
This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
|
|
5184
|
-
The \`s\` in \`s/\` stands for *simulate*. Because custom slash commands are not built-in, this syntax provides a pseudo way to invoke them.
|
|
5185
|
-
|
|
5186
|
-
When users call a custom slash command, you have to look for the markdown file, \`${join49(commands.relativeDirPath, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : ""}
|
|
5187
|
-
|
|
5188
|
-
${this.simulateSubagents ? `## Simulated Subagents
|
|
5189
|
-
|
|
5190
|
-
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 simulated custom slash commands simply. Simulated subagents can be called by simulated custom slash commands.
|
|
5191
|
-
|
|
5192
|
-
When users call a simulated subagent, it will look for the corresponding markdown file, \`${join49(subagents.relativeDirPath, "{subagent}.md")}\`, and execute its contents as the block of operations.` : ""}`.trim();
|
|
5193
|
-
}
|
|
5194
|
-
};
|
|
5195
|
-
|
|
5196
|
-
// src/subagents/subagents-processor.ts
|
|
5197
|
-
import { basename as basename16, join as join52 } from "path";
|
|
5198
|
-
import { z as z20 } from "zod/mini";
|
|
5199
|
-
|
|
5200
|
-
// src/subagents/claudecode-subagent.ts
|
|
5201
|
-
import { join as join51 } from "path";
|
|
5202
|
-
import { z as z19 } from "zod/mini";
|
|
5203
|
-
|
|
5204
|
-
// src/subagents/rulesync-subagent.ts
|
|
5205
|
-
import { basename as basename15, join as join50 } from "path";
|
|
5206
|
-
import { z as z18 } from "zod/mini";
|
|
5207
|
-
var RulesyncSubagentModelSchema = z18.enum(["opus", "sonnet", "haiku", "inherit"]);
|
|
5208
|
-
var RulesyncSubagentFrontmatterSchema = z18.object({
|
|
5209
|
-
targets: RulesyncTargetsSchema,
|
|
5210
|
-
name: z18.string(),
|
|
5211
|
-
description: z18.string(),
|
|
5212
|
-
claudecode: z18.optional(
|
|
5213
|
-
z18.object({
|
|
5214
|
-
model: RulesyncSubagentModelSchema
|
|
5215
|
-
})
|
|
5216
|
-
)
|
|
5217
|
-
});
|
|
5218
|
-
var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
5219
|
-
frontmatter;
|
|
5220
|
-
body;
|
|
5221
|
-
constructor({ frontmatter, body, ...rest }) {
|
|
5222
|
-
if (rest.validate !== false) {
|
|
5223
|
-
const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
5224
|
-
if (!result.success) {
|
|
5225
|
-
throw result.error;
|
|
5226
|
-
}
|
|
5227
|
-
}
|
|
5228
|
-
super({
|
|
5229
|
-
...rest
|
|
5230
|
-
});
|
|
5231
|
-
this.frontmatter = frontmatter;
|
|
5232
|
-
this.body = body;
|
|
5233
|
-
}
|
|
5234
|
-
static getSettablePaths() {
|
|
5235
|
-
return {
|
|
5236
|
-
relativeDirPath: ".rulesync/subagents"
|
|
5237
|
-
};
|
|
5238
|
-
}
|
|
5239
|
-
getFrontmatter() {
|
|
5240
|
-
return this.frontmatter;
|
|
5241
|
-
}
|
|
5242
|
-
getBody() {
|
|
5243
|
-
return this.body;
|
|
5244
|
-
}
|
|
5245
|
-
validate() {
|
|
5246
|
-
if (!this.frontmatter) {
|
|
5247
|
-
return { success: true, error: null };
|
|
5248
|
-
}
|
|
5249
|
-
const result = RulesyncSubagentFrontmatterSchema.safeParse(this.frontmatter);
|
|
5250
|
-
if (result.success) {
|
|
5251
|
-
return { success: true, error: null };
|
|
5252
|
-
} else {
|
|
5253
|
-
return { success: false, error: result.error };
|
|
5254
|
-
}
|
|
5255
|
-
}
|
|
5256
|
-
static async fromFile({
|
|
5257
|
-
relativeFilePath
|
|
5258
|
-
}) {
|
|
5259
|
-
const fileContent = await readFileContent(join50(RULESYNC_SUBAGENTS_DIR, relativeFilePath));
|
|
5260
|
-
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
5261
|
-
const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
5262
|
-
if (!result.success) {
|
|
5263
|
-
throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
|
|
5264
|
-
}
|
|
5265
|
-
const filename = basename15(relativeFilePath);
|
|
5266
|
-
return new _RulesyncSubagent({
|
|
5267
|
-
baseDir: ".",
|
|
5268
|
-
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
5269
|
-
relativeFilePath: filename,
|
|
5270
|
-
frontmatter: result.data,
|
|
5271
|
-
body: content.trim(),
|
|
5272
|
-
fileContent
|
|
5273
|
-
});
|
|
5274
|
-
}
|
|
5275
|
-
};
|
|
5276
|
-
|
|
5277
|
-
// src/subagents/claudecode-subagent.ts
|
|
5278
|
-
var ClaudecodeSubagentFrontmatterSchema = z19.object({
|
|
5279
|
-
name: z19.string(),
|
|
5280
|
-
description: z19.string(),
|
|
5281
|
-
model: z19.optional(z19.enum(["opus", "sonnet", "haiku", "inherit"]))
|
|
5282
|
-
});
|
|
5283
|
-
var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
5284
|
-
frontmatter;
|
|
5285
|
-
body;
|
|
5286
|
-
constructor({ frontmatter, body, ...rest }) {
|
|
5287
|
-
if (rest.validate !== false) {
|
|
5288
|
-
const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
5289
|
-
if (!result.success) {
|
|
5290
|
-
throw result.error;
|
|
5291
|
-
}
|
|
5292
|
-
}
|
|
5293
|
-
super({
|
|
5294
|
-
...rest
|
|
5295
|
-
});
|
|
5296
|
-
this.frontmatter = frontmatter;
|
|
5297
|
-
this.body = body;
|
|
5298
|
-
}
|
|
5299
|
-
static getSettablePaths() {
|
|
5300
|
-
return {
|
|
5301
|
-
relativeDirPath: ".claude/agents"
|
|
5302
|
-
};
|
|
5303
|
-
}
|
|
5304
|
-
getFrontmatter() {
|
|
5305
|
-
return this.frontmatter;
|
|
5306
|
-
}
|
|
5307
|
-
getBody() {
|
|
5308
|
-
return this.body;
|
|
5309
|
-
}
|
|
5310
|
-
toRulesyncSubagent() {
|
|
5311
|
-
const rulesyncFrontmatter = {
|
|
5312
|
-
targets: ["claudecode"],
|
|
5313
|
-
name: this.frontmatter.name,
|
|
5314
|
-
description: this.frontmatter.description,
|
|
5315
|
-
...this.frontmatter.model && {
|
|
5316
|
-
claudecode: {
|
|
5317
|
-
model: this.frontmatter.model
|
|
5318
|
-
}
|
|
5386
|
+
/**
|
|
5387
|
+
* Load Amazon Q Developer CLI rule configurations from .amazonq/rules/ directory
|
|
5388
|
+
*/
|
|
5389
|
+
async loadAmazonqcliRules() {
|
|
5390
|
+
const settablePaths = AmazonQCliRule.getSettablePaths();
|
|
5391
|
+
return await this.loadToolRulesDefault({
|
|
5392
|
+
nonRoot: {
|
|
5393
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5394
|
+
fromFile: (params) => AmazonQCliRule.fromFile(params),
|
|
5395
|
+
extension: "md"
|
|
5319
5396
|
}
|
|
5320
|
-
};
|
|
5321
|
-
const fileContent = stringifyFrontmatter(this.body, rulesyncFrontmatter);
|
|
5322
|
-
return new RulesyncSubagent({
|
|
5323
|
-
frontmatter: rulesyncFrontmatter,
|
|
5324
|
-
body: this.body,
|
|
5325
|
-
baseDir: this.baseDir,
|
|
5326
|
-
relativeDirPath: ".rulesync/subagents",
|
|
5327
|
-
relativeFilePath: this.getRelativeFilePath(),
|
|
5328
|
-
fileContent,
|
|
5329
|
-
validate: true
|
|
5330
5397
|
});
|
|
5331
5398
|
}
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
const body = rulesyncSubagent.getBody();
|
|
5344
|
-
const fileContent = stringifyFrontmatter(body, claudecodeFrontmatter);
|
|
5345
|
-
return new _ClaudecodeSubagent({
|
|
5346
|
-
baseDir,
|
|
5347
|
-
frontmatter: claudecodeFrontmatter,
|
|
5348
|
-
body,
|
|
5349
|
-
relativeDirPath: ".claude/agents",
|
|
5350
|
-
relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
|
|
5351
|
-
fileContent,
|
|
5352
|
-
validate
|
|
5399
|
+
/**
|
|
5400
|
+
* Load AugmentCode rule configurations from .augment/rules/ directory
|
|
5401
|
+
*/
|
|
5402
|
+
async loadAugmentcodeRules() {
|
|
5403
|
+
const settablePaths = AugmentcodeRule.getSettablePaths();
|
|
5404
|
+
return await this.loadToolRulesDefault({
|
|
5405
|
+
nonRoot: {
|
|
5406
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5407
|
+
fromFile: (params) => AugmentcodeRule.fromFile(params),
|
|
5408
|
+
extension: "md"
|
|
5409
|
+
}
|
|
5353
5410
|
});
|
|
5354
5411
|
}
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
const
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5412
|
+
/**
|
|
5413
|
+
* Load AugmentCode legacy rule configuration from .augment-guidelines file and .augment/rules/ directory
|
|
5414
|
+
*/
|
|
5415
|
+
async loadAugmentcodeLegacyRules() {
|
|
5416
|
+
const settablePaths = AugmentcodeLegacyRule.getSettablePaths();
|
|
5417
|
+
return await this.loadToolRulesDefault({
|
|
5418
|
+
root: {
|
|
5419
|
+
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
5420
|
+
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
5421
|
+
fromFile: (params) => AugmentcodeLegacyRule.fromFile(params)
|
|
5422
|
+
},
|
|
5423
|
+
nonRoot: {
|
|
5424
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5425
|
+
fromFile: (params) => AugmentcodeLegacyRule.fromFile(params),
|
|
5426
|
+
extension: "md"
|
|
5427
|
+
}
|
|
5428
|
+
});
|
|
5365
5429
|
}
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5430
|
+
/**
|
|
5431
|
+
* Load Claude Code rule configuration from CLAUDE.md file
|
|
5432
|
+
*/
|
|
5433
|
+
async loadClaudecodeRules() {
|
|
5434
|
+
const settablePaths = ClaudecodeRule.getSettablePaths();
|
|
5435
|
+
return await this.loadToolRulesDefault({
|
|
5436
|
+
root: {
|
|
5437
|
+
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
5438
|
+
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
5439
|
+
fromFile: (params) => ClaudecodeRule.fromFile(params)
|
|
5440
|
+
},
|
|
5441
|
+
nonRoot: {
|
|
5442
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5443
|
+
fromFile: (params) => ClaudecodeRule.fromFile(params),
|
|
5444
|
+
extension: "md"
|
|
5445
|
+
}
|
|
5370
5446
|
});
|
|
5371
5447
|
}
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
return new _ClaudecodeSubagent({
|
|
5384
|
-
baseDir,
|
|
5385
|
-
relativeDirPath: ".claude/agents",
|
|
5386
|
-
relativeFilePath,
|
|
5387
|
-
frontmatter: result.data,
|
|
5388
|
-
body: content.trim(),
|
|
5389
|
-
fileContent,
|
|
5390
|
-
validate
|
|
5448
|
+
/**
|
|
5449
|
+
* Load Cline rule configurations from .clinerules/ directory
|
|
5450
|
+
*/
|
|
5451
|
+
async loadClineRules() {
|
|
5452
|
+
const settablePaths = ClineRule.getSettablePaths();
|
|
5453
|
+
return await this.loadToolRulesDefault({
|
|
5454
|
+
nonRoot: {
|
|
5455
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5456
|
+
fromFile: (params) => ClineRule.fromFile(params),
|
|
5457
|
+
extension: "md"
|
|
5458
|
+
}
|
|
5391
5459
|
});
|
|
5392
5460
|
}
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
constructor({
|
|
5411
|
-
baseDir = ".",
|
|
5412
|
-
toolTarget
|
|
5413
|
-
}) {
|
|
5414
|
-
super({ baseDir });
|
|
5415
|
-
this.toolTarget = SubagentsProcessorToolTargetSchema.parse(toolTarget);
|
|
5461
|
+
/**
|
|
5462
|
+
* Load OpenAI Codex CLI rule configuration from AGENTS.md and .codex/memories/*.md files
|
|
5463
|
+
*/
|
|
5464
|
+
async loadCodexcliRules() {
|
|
5465
|
+
const settablePaths = CodexcliRule.getSettablePaths();
|
|
5466
|
+
return await this.loadToolRulesDefault({
|
|
5467
|
+
root: {
|
|
5468
|
+
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
5469
|
+
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
5470
|
+
fromFile: (params) => CodexcliRule.fromFile(params)
|
|
5471
|
+
},
|
|
5472
|
+
nonRoot: {
|
|
5473
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5474
|
+
fromFile: (params) => CodexcliRule.fromFile(params),
|
|
5475
|
+
extension: "md"
|
|
5476
|
+
}
|
|
5477
|
+
});
|
|
5416
5478
|
}
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
const
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
case "copilot":
|
|
5433
|
-
if (!CopilotSubagent.isTargetedByRulesyncSubagent(rulesyncSubagent)) {
|
|
5434
|
-
return null;
|
|
5435
|
-
}
|
|
5436
|
-
return CopilotSubagent.fromRulesyncSubagent({
|
|
5437
|
-
baseDir: this.baseDir,
|
|
5438
|
-
relativeDirPath: RulesyncSubagent.getSettablePaths().relativeDirPath,
|
|
5439
|
-
rulesyncSubagent
|
|
5440
|
-
});
|
|
5441
|
-
case "cursor":
|
|
5442
|
-
if (!CursorSubagent.isTargetedByRulesyncSubagent(rulesyncSubagent)) {
|
|
5443
|
-
return null;
|
|
5444
|
-
}
|
|
5445
|
-
return CursorSubagent.fromRulesyncSubagent({
|
|
5446
|
-
baseDir: this.baseDir,
|
|
5447
|
-
relativeDirPath: RulesyncSubagent.getSettablePaths().relativeDirPath,
|
|
5448
|
-
rulesyncSubagent
|
|
5449
|
-
});
|
|
5450
|
-
case "codexcli":
|
|
5451
|
-
if (!CodexCliSubagent.isTargetedByRulesyncSubagent(rulesyncSubagent)) {
|
|
5452
|
-
return null;
|
|
5453
|
-
}
|
|
5454
|
-
return CodexCliSubagent.fromRulesyncSubagent({
|
|
5455
|
-
baseDir: this.baseDir,
|
|
5456
|
-
relativeDirPath: RulesyncSubagent.getSettablePaths().relativeDirPath,
|
|
5457
|
-
rulesyncSubagent
|
|
5458
|
-
});
|
|
5459
|
-
default:
|
|
5460
|
-
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
5479
|
+
/**
|
|
5480
|
+
* Load GitHub Copilot rule configuration from .github/copilot-instructions.md file
|
|
5481
|
+
*/
|
|
5482
|
+
async loadCopilotRules() {
|
|
5483
|
+
const settablePaths = CopilotRule.getSettablePaths();
|
|
5484
|
+
return await this.loadToolRulesDefault({
|
|
5485
|
+
root: {
|
|
5486
|
+
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
5487
|
+
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
5488
|
+
fromFile: (params) => CopilotRule.fromFile(params)
|
|
5489
|
+
},
|
|
5490
|
+
nonRoot: {
|
|
5491
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5492
|
+
fromFile: (params) => CopilotRule.fromFile(params),
|
|
5493
|
+
extension: "md"
|
|
5461
5494
|
}
|
|
5462
|
-
})
|
|
5463
|
-
return toolSubagents;
|
|
5495
|
+
});
|
|
5464
5496
|
}
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
const
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
continue;
|
|
5497
|
+
/**
|
|
5498
|
+
* Load Cursor rule configurations from .cursor/rules/ directory
|
|
5499
|
+
*/
|
|
5500
|
+
async loadCursorRules() {
|
|
5501
|
+
const settablePaths = CursorRule.getSettablePaths();
|
|
5502
|
+
return await this.loadToolRulesDefault({
|
|
5503
|
+
nonRoot: {
|
|
5504
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5505
|
+
fromFile: (params) => CursorRule.fromFile(params),
|
|
5506
|
+
extension: "mdc"
|
|
5476
5507
|
}
|
|
5477
|
-
|
|
5478
|
-
}
|
|
5479
|
-
return rulesyncSubagents;
|
|
5508
|
+
});
|
|
5480
5509
|
}
|
|
5481
5510
|
/**
|
|
5482
|
-
*
|
|
5483
|
-
* Load and parse rulesync subagent files from .rulesync/subagents/ directory
|
|
5511
|
+
* Load Gemini CLI rule configuration from GEMINI.md file
|
|
5484
5512
|
*/
|
|
5485
|
-
async
|
|
5486
|
-
const
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
}
|
|
5498
|
-
logger.info(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
|
|
5499
|
-
const rulesyncSubagents = [];
|
|
5500
|
-
for (const mdFile of mdFiles) {
|
|
5501
|
-
const filepath = join52(subagentsDir, mdFile);
|
|
5502
|
-
try {
|
|
5503
|
-
const rulesyncSubagent = await RulesyncSubagent.fromFile({
|
|
5504
|
-
relativeFilePath: mdFile,
|
|
5505
|
-
validate: true
|
|
5506
|
-
});
|
|
5507
|
-
rulesyncSubagents.push(rulesyncSubagent);
|
|
5508
|
-
logger.debug(`Successfully loaded subagent: ${mdFile}`);
|
|
5509
|
-
} catch (error) {
|
|
5510
|
-
logger.warn(`Failed to load subagent file ${filepath}:`, error);
|
|
5511
|
-
continue;
|
|
5513
|
+
async loadGeminicliRules() {
|
|
5514
|
+
const settablePaths = GeminiCliRule.getSettablePaths();
|
|
5515
|
+
return await this.loadToolRulesDefault({
|
|
5516
|
+
root: {
|
|
5517
|
+
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
5518
|
+
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
5519
|
+
fromFile: (params) => GeminiCliRule.fromFile(params)
|
|
5520
|
+
},
|
|
5521
|
+
nonRoot: {
|
|
5522
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5523
|
+
fromFile: (params) => GeminiCliRule.fromFile(params),
|
|
5524
|
+
extension: "md"
|
|
5512
5525
|
}
|
|
5513
|
-
}
|
|
5514
|
-
if (rulesyncSubagents.length === 0) {
|
|
5515
|
-
logger.debug(`No valid subagents found in ${subagentsDir}`);
|
|
5516
|
-
return [];
|
|
5517
|
-
}
|
|
5518
|
-
logger.info(`Successfully loaded ${rulesyncSubagents.length} rulesync subagents`);
|
|
5519
|
-
return rulesyncSubagents;
|
|
5526
|
+
});
|
|
5520
5527
|
}
|
|
5521
5528
|
/**
|
|
5522
|
-
*
|
|
5523
|
-
* Load tool-specific subagent configurations and parse them into ToolSubagent instances
|
|
5529
|
+
* Load JetBrains Junie rule configuration from .junie/guidelines.md file
|
|
5524
5530
|
*/
|
|
5525
|
-
async
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5531
|
+
async loadJunieRules() {
|
|
5532
|
+
const settablePaths = JunieRule.getSettablePaths();
|
|
5533
|
+
return await this.loadToolRulesDefault({
|
|
5534
|
+
root: {
|
|
5535
|
+
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
5536
|
+
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
5537
|
+
fromFile: (params) => JunieRule.fromFile(params)
|
|
5538
|
+
},
|
|
5539
|
+
nonRoot: {
|
|
5540
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5541
|
+
fromFile: (params) => JunieRule.fromFile(params),
|
|
5542
|
+
extension: "md"
|
|
5543
|
+
}
|
|
5544
|
+
});
|
|
5538
5545
|
}
|
|
5539
5546
|
/**
|
|
5540
|
-
* Load
|
|
5547
|
+
* Load Kiro rule configurations from .kiro/steering/ directory
|
|
5541
5548
|
*/
|
|
5542
|
-
async
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5549
|
+
async loadKiroRules() {
|
|
5550
|
+
const settablePaths = KiroRule.getSettablePaths();
|
|
5551
|
+
return await this.loadToolRulesDefault({
|
|
5552
|
+
nonRoot: {
|
|
5553
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5554
|
+
fromFile: (params) => KiroRule.fromFile(params),
|
|
5555
|
+
extension: "md"
|
|
5556
|
+
}
|
|
5546
5557
|
});
|
|
5547
5558
|
}
|
|
5548
5559
|
/**
|
|
5549
|
-
* Load
|
|
5560
|
+
* Load OpenCode rule configuration from AGENTS.md file and .opencode/memories/*.md files
|
|
5550
5561
|
*/
|
|
5551
|
-
async
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5562
|
+
async loadOpencodeRules() {
|
|
5563
|
+
const settablePaths = OpenCodeRule.getSettablePaths();
|
|
5564
|
+
return await this.loadToolRulesDefault({
|
|
5565
|
+
root: {
|
|
5566
|
+
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
5567
|
+
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
5568
|
+
fromFile: (params) => OpenCodeRule.fromFile(params)
|
|
5569
|
+
},
|
|
5570
|
+
nonRoot: {
|
|
5571
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5572
|
+
fromFile: (params) => OpenCodeRule.fromFile(params),
|
|
5573
|
+
extension: "md"
|
|
5574
|
+
}
|
|
5555
5575
|
});
|
|
5556
5576
|
}
|
|
5557
5577
|
/**
|
|
5558
|
-
* Load
|
|
5578
|
+
* Load Qwen Code rule configuration from QWEN.md file and .qwen/memories/*.md files
|
|
5559
5579
|
*/
|
|
5560
|
-
async
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5580
|
+
async loadQwencodeRules() {
|
|
5581
|
+
const settablePaths = QwencodeRule.getSettablePaths();
|
|
5582
|
+
return await this.loadToolRulesDefault({
|
|
5583
|
+
root: {
|
|
5584
|
+
relativeDirPath: settablePaths.root.relativeDirPath,
|
|
5585
|
+
relativeFilePath: settablePaths.root.relativeFilePath,
|
|
5586
|
+
fromFile: (params) => QwencodeRule.fromFile(params)
|
|
5587
|
+
},
|
|
5588
|
+
nonRoot: {
|
|
5589
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5590
|
+
fromFile: (params) => QwencodeRule.fromFile(params),
|
|
5591
|
+
extension: "md"
|
|
5592
|
+
}
|
|
5564
5593
|
});
|
|
5565
5594
|
}
|
|
5566
5595
|
/**
|
|
5567
|
-
* Load
|
|
5596
|
+
* Load Roo Code rule configurations from .roo/rules/ directory
|
|
5568
5597
|
*/
|
|
5569
|
-
async
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5598
|
+
async loadRooRules() {
|
|
5599
|
+
const settablePaths = RooRule.getSettablePaths();
|
|
5600
|
+
return await this.loadToolRulesDefault({
|
|
5601
|
+
nonRoot: {
|
|
5602
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5603
|
+
fromFile: (params) => RooRule.fromFile(params),
|
|
5604
|
+
extension: "md"
|
|
5605
|
+
}
|
|
5573
5606
|
});
|
|
5574
5607
|
}
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
const
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5608
|
+
/**
|
|
5609
|
+
* Load Windsurf rule configurations from .windsurf/rules/ directory
|
|
5610
|
+
*/
|
|
5611
|
+
async loadWindsurfRules() {
|
|
5612
|
+
const settablePaths = WindsurfRule.getSettablePaths();
|
|
5613
|
+
return await this.loadToolRulesDefault({
|
|
5614
|
+
nonRoot: {
|
|
5615
|
+
relativeDirPath: settablePaths.nonRoot.relativeDirPath,
|
|
5616
|
+
fromFile: (params) => WindsurfRule.fromFile(params),
|
|
5617
|
+
extension: "md"
|
|
5618
|
+
}
|
|
5619
|
+
});
|
|
5583
5620
|
}
|
|
5584
5621
|
/**
|
|
5585
5622
|
* Implementation of abstract method from FeatureProcessor
|
|
5586
5623
|
* Return the tool targets that this processor supports
|
|
5587
5624
|
*/
|
|
5588
|
-
static getToolTargets({
|
|
5589
|
-
|
|
5590
|
-
}
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5625
|
+
static getToolTargets() {
|
|
5626
|
+
return rulesProcessorToolTargets;
|
|
5627
|
+
}
|
|
5628
|
+
generateXmlReferencesSection(toolRules) {
|
|
5629
|
+
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot());
|
|
5630
|
+
if (toolRulesWithoutRoot.length === 0) {
|
|
5631
|
+
return "";
|
|
5632
|
+
}
|
|
5633
|
+
const lines = [];
|
|
5634
|
+
lines.push(
|
|
5635
|
+
"Please also reference the following documents as needed. In this case, `@` stands for the project root directory."
|
|
5636
|
+
);
|
|
5637
|
+
lines.push("");
|
|
5638
|
+
const documentsData = {
|
|
5639
|
+
Documents: {
|
|
5640
|
+
Document: toolRulesWithoutRoot.map((rule) => {
|
|
5641
|
+
const rulesyncRule = rule.toRulesyncRule();
|
|
5642
|
+
const frontmatter = rulesyncRule.getFrontmatter();
|
|
5643
|
+
const relativePath = `@${rule.getRelativePathFromCwd()}`;
|
|
5644
|
+
const document = {
|
|
5645
|
+
Path: relativePath
|
|
5646
|
+
};
|
|
5647
|
+
if (frontmatter.description) {
|
|
5648
|
+
document.Description = frontmatter.description;
|
|
5649
|
+
}
|
|
5650
|
+
if (frontmatter.globs && frontmatter.globs.length > 0) {
|
|
5651
|
+
document.FilePatterns = frontmatter.globs.join(", ");
|
|
5652
|
+
}
|
|
5653
|
+
return document;
|
|
5654
|
+
})
|
|
5655
|
+
}
|
|
5656
|
+
};
|
|
5657
|
+
const builder = new XMLBuilder({
|
|
5658
|
+
format: true,
|
|
5659
|
+
ignoreAttributes: false,
|
|
5660
|
+
suppressEmptyNode: false
|
|
5661
|
+
});
|
|
5662
|
+
const xmlContent = builder.build(documentsData);
|
|
5663
|
+
lines.push(xmlContent);
|
|
5664
|
+
return lines.join("\n") + "\n";
|
|
5665
|
+
}
|
|
5666
|
+
generateReferencesSection(toolRules) {
|
|
5667
|
+
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot());
|
|
5668
|
+
if (toolRulesWithoutRoot.length === 0) {
|
|
5669
|
+
return "";
|
|
5670
|
+
}
|
|
5671
|
+
const lines = [];
|
|
5672
|
+
lines.push("Please also reference the following documents as needed:");
|
|
5673
|
+
lines.push("");
|
|
5674
|
+
for (const rule of toolRulesWithoutRoot) {
|
|
5675
|
+
const rulesyncRule = rule.toRulesyncRule();
|
|
5676
|
+
const frontmatter = rulesyncRule.getFrontmatter();
|
|
5677
|
+
const escapedDescription = frontmatter.description?.replace(/"/g, '\\"');
|
|
5678
|
+
const globsText = frontmatter.globs?.join(",");
|
|
5679
|
+
lines.push(
|
|
5680
|
+
`@${rule.getRelativePathFromCwd()} description: "${escapedDescription}" globs: "${globsText}"`
|
|
5594
5681
|
);
|
|
5595
5682
|
}
|
|
5596
|
-
return
|
|
5683
|
+
return lines.join("\n") + "\n";
|
|
5684
|
+
}
|
|
5685
|
+
generateAdditionalConventionsSection({
|
|
5686
|
+
commands,
|
|
5687
|
+
subagents
|
|
5688
|
+
}) {
|
|
5689
|
+
const overview = `# Additional Conventions Beyond the Built-in Functions
|
|
5690
|
+
|
|
5691
|
+
As this project's AI coding tool, you must follow the additional conventions below, in addition to the built-in functions.`;
|
|
5692
|
+
const commandsSection = `## Simulated Custom Slash Commands
|
|
5693
|
+
|
|
5694
|
+
Custom slash commands allow you to define frequently-used prompts as Markdown files that you can execute.
|
|
5695
|
+
|
|
5696
|
+
### Syntax
|
|
5697
|
+
|
|
5698
|
+
Users can use following syntax to invoke a custom command.
|
|
5699
|
+
|
|
5700
|
+
\`\`\`txt
|
|
5701
|
+
s/<command> [arguments]
|
|
5702
|
+
\`\`\`
|
|
5703
|
+
|
|
5704
|
+
This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
|
|
5705
|
+
The \`s\` in \`s/\` stands for *simulate*. Because custom slash commands are not built-in, this syntax provides a pseudo way to invoke them.
|
|
5706
|
+
|
|
5707
|
+
When users call a custom slash command, you have to look for the markdown file, \`${join52(commands.relativeDirPath, "{command}.md")}\`, then execute the contents of that file as the block of operations.`;
|
|
5708
|
+
const subagentsSection = `## Simulated Subagents
|
|
5709
|
+
|
|
5710
|
+
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.
|
|
5711
|
+
|
|
5712
|
+
When users call a simulated subagent, it will look for the corresponding markdown file, \`${join52(subagents.relativeDirPath, "{subagent}.md")}\`, and execute its contents as the block of operations.
|
|
5713
|
+
|
|
5714
|
+
For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join52(subagents.relativeDirPath, "planner.md")}\`, and execute its contents as the block of operations.`;
|
|
5715
|
+
const result = [
|
|
5716
|
+
overview,
|
|
5717
|
+
...this.simulateCommands && CommandsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [commandsSection] : [],
|
|
5718
|
+
...this.simulateSubagents && SubagentsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [subagentsSection] : []
|
|
5719
|
+
].join("\n\n");
|
|
5720
|
+
return result;
|
|
5597
5721
|
}
|
|
5598
5722
|
};
|
|
5599
5723
|
|
|
@@ -5798,6 +5922,7 @@ var gitignoreCommand = async () => {
|
|
|
5798
5922
|
"**/GEMINI.md",
|
|
5799
5923
|
"**/.gemini/memories/",
|
|
5800
5924
|
"**/.gemini/commands/",
|
|
5925
|
+
"**/.gemini/subagents/",
|
|
5801
5926
|
"**/QWEN.md",
|
|
5802
5927
|
"**/.qwen/memories/",
|
|
5803
5928
|
"**/.aiexclude",
|
|
@@ -5815,6 +5940,7 @@ var gitignoreCommand = async () => {
|
|
|
5815
5940
|
"**/.cursor/mcp.json",
|
|
5816
5941
|
"**/.cline/mcp.json",
|
|
5817
5942
|
"**/.roo/mcp.json",
|
|
5943
|
+
"**/.roo/subagents/",
|
|
5818
5944
|
"**/.vscode/mcp.json",
|
|
5819
5945
|
"**/.github/commands/",
|
|
5820
5946
|
"**/.github/subagents/",
|
|
@@ -5839,8 +5965,8 @@ var gitignoreCommand = async () => {
|
|
|
5839
5965
|
}
|
|
5840
5966
|
const newContent = gitignoreContent ? `${gitignoreContent.trimEnd()}
|
|
5841
5967
|
|
|
5842
|
-
${linesToAdd.join("")}
|
|
5843
|
-
` : `${linesToAdd.join("")}
|
|
5968
|
+
${linesToAdd.join("\n")}
|
|
5969
|
+
` : `${linesToAdd.join("\n")}
|
|
5844
5970
|
`;
|
|
5845
5971
|
await writeFileContent(gitignorePath, newContent);
|
|
5846
5972
|
logger.success(`Added ${linesToAdd.length} rules to .gitignore:`);
|
|
@@ -6036,7 +6162,7 @@ var getVersion = async () => {
|
|
|
6036
6162
|
const packageJson = await readJsonFile(packageJsonPath);
|
|
6037
6163
|
return packageJson.version;
|
|
6038
6164
|
} catch {
|
|
6039
|
-
return "0.
|
|
6165
|
+
return "0.76.0";
|
|
6040
6166
|
}
|
|
6041
6167
|
};
|
|
6042
6168
|
var main = async () => {
|