rulesync 7.12.0 → 7.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-WAWBAZPA.js → chunk-VAGOPUDS.js} +245 -240
- package/dist/cli/index.cjs +245 -240
- package/dist/cli/index.js +2 -2
- package/dist/index.cjs +244 -239
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -906,7 +906,7 @@ var ToolCommand = class extends AiFile {
|
|
|
906
906
|
|
|
907
907
|
// src/features/commands/simulated-command.ts
|
|
908
908
|
var SimulatedCommandFrontmatterSchema = z4.object({
|
|
909
|
-
description: z4.string()
|
|
909
|
+
description: z4.optional(z4.string())
|
|
910
910
|
});
|
|
911
911
|
var SimulatedCommand = class _SimulatedCommand extends ToolCommand {
|
|
912
912
|
frontmatter;
|
|
@@ -1093,7 +1093,7 @@ var RulesyncFile = class extends AiFile {
|
|
|
1093
1093
|
// src/features/commands/rulesync-command.ts
|
|
1094
1094
|
var RulesyncCommandFrontmatterSchema = z5.looseObject({
|
|
1095
1095
|
targets: z5._default(RulesyncTargetsSchema, ["*"]),
|
|
1096
|
-
description: z5.string()
|
|
1096
|
+
description: z5.optional(z5.string())
|
|
1097
1097
|
});
|
|
1098
1098
|
var RulesyncCommand = class _RulesyncCommand extends RulesyncFile {
|
|
1099
1099
|
frontmatter;
|
|
@@ -1181,7 +1181,7 @@ var AntigravityWorkflowFrontmatterSchema = z6.looseObject({
|
|
|
1181
1181
|
turbo: z6.optional(z6.boolean())
|
|
1182
1182
|
});
|
|
1183
1183
|
var AntigravityCommandFrontmatterSchema = z6.looseObject({
|
|
1184
|
-
description: z6.string(),
|
|
1184
|
+
description: z6.optional(z6.string()),
|
|
1185
1185
|
// Support for workflow-specific configuration
|
|
1186
1186
|
...AntigravityWorkflowFrontmatterSchema.shape
|
|
1187
1187
|
});
|
|
@@ -1354,7 +1354,7 @@ ${body}${turboDirective}`;
|
|
|
1354
1354
|
import { join as join8 } from "path";
|
|
1355
1355
|
import { z as z7 } from "zod/mini";
|
|
1356
1356
|
var ClaudecodeCommandFrontmatterSchema = z7.looseObject({
|
|
1357
|
-
description: z7.string(),
|
|
1357
|
+
description: z7.optional(z7.string()),
|
|
1358
1358
|
"allowed-tools": z7.optional(z7.union([z7.string(), z7.array(z7.string())])),
|
|
1359
1359
|
"argument-hint": z7.optional(z7.string()),
|
|
1360
1360
|
model: z7.optional(z7.string()),
|
|
@@ -1509,8 +1509,7 @@ var ClineCommand = class _ClineCommand extends ToolCommand {
|
|
|
1509
1509
|
}
|
|
1510
1510
|
toRulesyncCommand() {
|
|
1511
1511
|
const rulesyncFrontmatter = {
|
|
1512
|
-
targets: ["*"]
|
|
1513
|
-
description: ""
|
|
1512
|
+
targets: ["*"]
|
|
1514
1513
|
};
|
|
1515
1514
|
return new RulesyncCommand({
|
|
1516
1515
|
baseDir: process.cwd(),
|
|
@@ -1595,8 +1594,7 @@ var CodexcliCommand = class _CodexcliCommand extends ToolCommand {
|
|
|
1595
1594
|
}
|
|
1596
1595
|
toRulesyncCommand() {
|
|
1597
1596
|
const rulesyncFrontmatter = {
|
|
1598
|
-
targets: ["*"]
|
|
1599
|
-
description: ""
|
|
1597
|
+
targets: ["*"]
|
|
1600
1598
|
};
|
|
1601
1599
|
return new RulesyncCommand({
|
|
1602
1600
|
baseDir: ".",
|
|
@@ -1674,7 +1672,7 @@ import { join as join11 } from "path";
|
|
|
1674
1672
|
import { z as z8 } from "zod/mini";
|
|
1675
1673
|
var CopilotCommandFrontmatterSchema = z8.looseObject({
|
|
1676
1674
|
mode: z8.optional(z8.string()),
|
|
1677
|
-
description: z8.string()
|
|
1675
|
+
description: z8.optional(z8.string())
|
|
1678
1676
|
});
|
|
1679
1677
|
var CopilotCommand = class _CopilotCommand extends ToolCommand {
|
|
1680
1678
|
frontmatter;
|
|
@@ -1857,7 +1855,7 @@ var CursorCommand = class _CursorCommand extends ToolCommand {
|
|
|
1857
1855
|
return this.frontmatter;
|
|
1858
1856
|
}
|
|
1859
1857
|
toRulesyncCommand() {
|
|
1860
|
-
const { description
|
|
1858
|
+
const { description, ...restFields } = this.frontmatter;
|
|
1861
1859
|
const rulesyncFrontmatter = {
|
|
1862
1860
|
targets: ["*"],
|
|
1863
1861
|
description,
|
|
@@ -2051,7 +2049,7 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
|
|
|
2051
2049
|
}
|
|
2052
2050
|
return {
|
|
2053
2051
|
...result.data,
|
|
2054
|
-
description: result.data.description
|
|
2052
|
+
description: result.data.description
|
|
2055
2053
|
};
|
|
2056
2054
|
} catch (error) {
|
|
2057
2055
|
throw new Error(
|
|
@@ -2073,7 +2071,7 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
|
|
|
2073
2071
|
const { description, prompt: _prompt, ...restFields } = this.frontmatter;
|
|
2074
2072
|
const rulesyncFrontmatter = {
|
|
2075
2073
|
targets: ["geminicli"],
|
|
2076
|
-
description
|
|
2074
|
+
description,
|
|
2077
2075
|
// Preserve extra fields in geminicli section (excluding prompt which is the body)
|
|
2078
2076
|
...Object.keys(restFields).length > 0 && { geminicli: restFields }
|
|
2079
2077
|
};
|
|
@@ -2102,8 +2100,9 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
|
|
|
2102
2100
|
prompt: rulesyncCommand.getBody(),
|
|
2103
2101
|
...geminicliFields
|
|
2104
2102
|
};
|
|
2105
|
-
const
|
|
2106
|
-
|
|
2103
|
+
const descriptionLine = geminiFrontmatter.description !== void 0 ? `description = "${geminiFrontmatter.description}"
|
|
2104
|
+
` : "";
|
|
2105
|
+
const tomlContent = `${descriptionLine}prompt = """
|
|
2107
2106
|
${geminiFrontmatter.prompt}
|
|
2108
2107
|
"""`;
|
|
2109
2108
|
const paths = this.getSettablePaths({ global });
|
|
@@ -2173,8 +2172,7 @@ var KiloCommand = class _KiloCommand extends ToolCommand {
|
|
|
2173
2172
|
}
|
|
2174
2173
|
toRulesyncCommand() {
|
|
2175
2174
|
const rulesyncFrontmatter = {
|
|
2176
|
-
targets: ["*"]
|
|
2177
|
-
description: ""
|
|
2175
|
+
targets: ["*"]
|
|
2178
2176
|
};
|
|
2179
2177
|
return new RulesyncCommand({
|
|
2180
2178
|
baseDir: process.cwd(),
|
|
@@ -2254,8 +2252,7 @@ var KiroCommand = class _KiroCommand extends ToolCommand {
|
|
|
2254
2252
|
}
|
|
2255
2253
|
toRulesyncCommand() {
|
|
2256
2254
|
const rulesyncFrontmatter = {
|
|
2257
|
-
targets: ["*"]
|
|
2258
|
-
description: ""
|
|
2255
|
+
targets: ["*"]
|
|
2259
2256
|
};
|
|
2260
2257
|
return new RulesyncCommand({
|
|
2261
2258
|
baseDir: process.cwd(),
|
|
@@ -2329,7 +2326,7 @@ var KiroCommand = class _KiroCommand extends ToolCommand {
|
|
|
2329
2326
|
import { join as join17 } from "path";
|
|
2330
2327
|
import { optional as optional2, z as z11 } from "zod/mini";
|
|
2331
2328
|
var OpenCodeCommandFrontmatterSchema = z11.looseObject({
|
|
2332
|
-
description: z11.string(),
|
|
2329
|
+
description: z11.optional(z11.string()),
|
|
2333
2330
|
agent: optional2(z11.string()),
|
|
2334
2331
|
subtask: optional2(z11.boolean()),
|
|
2335
2332
|
model: optional2(z11.string())
|
|
@@ -2469,7 +2466,7 @@ var OpenCodeCommand = class _OpenCodeCommand extends ToolCommand {
|
|
|
2469
2466
|
import { join as join18 } from "path";
|
|
2470
2467
|
import { optional as optional3, z as z12 } from "zod/mini";
|
|
2471
2468
|
var RooCommandFrontmatterSchema = z12.looseObject({
|
|
2472
|
-
description: z12.string(),
|
|
2469
|
+
description: z12.optional(z12.string()),
|
|
2473
2470
|
"argument-hint": optional3(z12.string())
|
|
2474
2471
|
});
|
|
2475
2472
|
var RooCommand = class _RooCommand extends ToolCommand {
|
|
@@ -3008,7 +3005,7 @@ var HookDefinitionSchema = z14.looseObject({
|
|
|
3008
3005
|
type: z14.optional(z14.enum(["command", "prompt"])),
|
|
3009
3006
|
timeout: z14.optional(z14.number()),
|
|
3010
3007
|
matcher: z14.optional(safeString),
|
|
3011
|
-
prompt: z14.optional(
|
|
3008
|
+
prompt: z14.optional(safeString),
|
|
3012
3009
|
loop_limit: z14.optional(z14.nullable(z14.number())),
|
|
3013
3010
|
name: z14.optional(safeString),
|
|
3014
3011
|
description: z14.optional(safeString)
|
|
@@ -3060,7 +3057,7 @@ var OPENCODE_HOOK_EVENTS = [
|
|
|
3060
3057
|
var COPILOT_HOOK_EVENTS = [
|
|
3061
3058
|
"sessionStart",
|
|
3062
3059
|
"sessionEnd",
|
|
3063
|
-
"
|
|
3060
|
+
"beforeSubmitPrompt",
|
|
3064
3061
|
"preToolUse",
|
|
3065
3062
|
"postToolUse",
|
|
3066
3063
|
"afterError"
|
|
@@ -3171,7 +3168,7 @@ var CANONICAL_TO_OPENCODE_EVENT_NAMES = {
|
|
|
3171
3168
|
var CANONICAL_TO_COPILOT_EVENT_NAMES = {
|
|
3172
3169
|
sessionStart: "sessionStart",
|
|
3173
3170
|
sessionEnd: "sessionEnd",
|
|
3174
|
-
|
|
3171
|
+
beforeSubmitPrompt: "userPromptSubmitted",
|
|
3175
3172
|
preToolUse: "preToolUse",
|
|
3176
3173
|
postToolUse: "postToolUse",
|
|
3177
3174
|
afterError: "errorOccurred"
|
|
@@ -3199,6 +3196,107 @@ var GEMINICLI_TO_CANONICAL_EVENT_NAMES = Object.fromEntries(
|
|
|
3199
3196
|
// src/features/hooks/claudecode-hooks.ts
|
|
3200
3197
|
import { join as join21 } from "path";
|
|
3201
3198
|
|
|
3199
|
+
// src/features/hooks/tool-hooks-converter.ts
|
|
3200
|
+
function isToolMatcherEntry(x) {
|
|
3201
|
+
if (x === null || typeof x !== "object") {
|
|
3202
|
+
return false;
|
|
3203
|
+
}
|
|
3204
|
+
if ("matcher" in x && typeof x.matcher !== "string") {
|
|
3205
|
+
return false;
|
|
3206
|
+
}
|
|
3207
|
+
if ("hooks" in x && !Array.isArray(x.hooks)) {
|
|
3208
|
+
return false;
|
|
3209
|
+
}
|
|
3210
|
+
return true;
|
|
3211
|
+
}
|
|
3212
|
+
function canonicalToToolHooks({
|
|
3213
|
+
config,
|
|
3214
|
+
toolOverrideHooks,
|
|
3215
|
+
converterConfig
|
|
3216
|
+
}) {
|
|
3217
|
+
const supported = new Set(converterConfig.supportedEvents);
|
|
3218
|
+
const sharedHooks = {};
|
|
3219
|
+
for (const [event, defs] of Object.entries(config.hooks)) {
|
|
3220
|
+
if (supported.has(event)) {
|
|
3221
|
+
sharedHooks[event] = defs;
|
|
3222
|
+
}
|
|
3223
|
+
}
|
|
3224
|
+
const effectiveHooks = {
|
|
3225
|
+
...sharedHooks,
|
|
3226
|
+
...toolOverrideHooks
|
|
3227
|
+
};
|
|
3228
|
+
const result = {};
|
|
3229
|
+
for (const [eventName, definitions] of Object.entries(effectiveHooks)) {
|
|
3230
|
+
const toolEventName = converterConfig.canonicalToToolEventNames[eventName] ?? eventName;
|
|
3231
|
+
const byMatcher = /* @__PURE__ */ new Map();
|
|
3232
|
+
for (const def of definitions) {
|
|
3233
|
+
const key = def.matcher ?? "";
|
|
3234
|
+
const list = byMatcher.get(key);
|
|
3235
|
+
if (list) list.push(def);
|
|
3236
|
+
else byMatcher.set(key, [def]);
|
|
3237
|
+
}
|
|
3238
|
+
const entries = [];
|
|
3239
|
+
for (const [matcherKey, defs] of byMatcher) {
|
|
3240
|
+
const hooks = defs.map((def) => {
|
|
3241
|
+
const commandText = def.command;
|
|
3242
|
+
const trimmedCommand = typeof commandText === "string" ? commandText.trimStart() : void 0;
|
|
3243
|
+
const shouldPrefix = typeof trimmedCommand === "string" && !trimmedCommand.startsWith("$") && (!converterConfig.prefixDotRelativeCommandsOnly || trimmedCommand.startsWith("."));
|
|
3244
|
+
const command = shouldPrefix && typeof trimmedCommand === "string" ? `${converterConfig.projectDirVar}/${trimmedCommand.replace(/^\.\//, "")}` : def.command;
|
|
3245
|
+
return {
|
|
3246
|
+
type: def.type ?? "command",
|
|
3247
|
+
...command !== void 0 && command !== null && { command },
|
|
3248
|
+
...def.timeout !== void 0 && def.timeout !== null && { timeout: def.timeout },
|
|
3249
|
+
...def.prompt !== void 0 && def.prompt !== null && { prompt: def.prompt }
|
|
3250
|
+
};
|
|
3251
|
+
});
|
|
3252
|
+
entries.push(matcherKey ? { matcher: matcherKey, hooks } : { hooks });
|
|
3253
|
+
}
|
|
3254
|
+
result[toolEventName] = entries;
|
|
3255
|
+
}
|
|
3256
|
+
return result;
|
|
3257
|
+
}
|
|
3258
|
+
function toolHooksToCanonical({
|
|
3259
|
+
hooks,
|
|
3260
|
+
converterConfig
|
|
3261
|
+
}) {
|
|
3262
|
+
if (hooks === null || hooks === void 0 || typeof hooks !== "object") {
|
|
3263
|
+
return {};
|
|
3264
|
+
}
|
|
3265
|
+
const canonical = {};
|
|
3266
|
+
for (const [toolEventName, matcherEntries] of Object.entries(hooks)) {
|
|
3267
|
+
const eventName = converterConfig.toolToCanonicalEventNames[toolEventName] ?? toolEventName;
|
|
3268
|
+
if (!Array.isArray(matcherEntries)) continue;
|
|
3269
|
+
const defs = [];
|
|
3270
|
+
for (const rawEntry of matcherEntries) {
|
|
3271
|
+
if (!isToolMatcherEntry(rawEntry)) continue;
|
|
3272
|
+
const hookDefs = rawEntry.hooks ?? [];
|
|
3273
|
+
for (const h of hookDefs) {
|
|
3274
|
+
const cmd = typeof h.command === "string" ? h.command : void 0;
|
|
3275
|
+
const command = typeof cmd === "string" && cmd.includes(`${converterConfig.projectDirVar}/`) ? cmd.replace(
|
|
3276
|
+
new RegExp(
|
|
3277
|
+
`^${converterConfig.projectDirVar.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\/?`
|
|
3278
|
+
),
|
|
3279
|
+
"./"
|
|
3280
|
+
) : cmd;
|
|
3281
|
+
const hookType = h.type === "command" || h.type === "prompt" ? h.type : "command";
|
|
3282
|
+
const timeout = typeof h.timeout === "number" ? h.timeout : void 0;
|
|
3283
|
+
const prompt = typeof h.prompt === "string" ? h.prompt : void 0;
|
|
3284
|
+
defs.push({
|
|
3285
|
+
type: hookType,
|
|
3286
|
+
...command !== void 0 && command !== null && { command },
|
|
3287
|
+
...timeout !== void 0 && timeout !== null && { timeout },
|
|
3288
|
+
...prompt !== void 0 && prompt !== null && { prompt },
|
|
3289
|
+
...rawEntry.matcher !== void 0 && rawEntry.matcher !== null && rawEntry.matcher !== "" && { matcher: rawEntry.matcher }
|
|
3290
|
+
});
|
|
3291
|
+
}
|
|
3292
|
+
}
|
|
3293
|
+
if (defs.length > 0) {
|
|
3294
|
+
canonical[eventName] = defs;
|
|
3295
|
+
}
|
|
3296
|
+
}
|
|
3297
|
+
return canonical;
|
|
3298
|
+
}
|
|
3299
|
+
|
|
3202
3300
|
// src/types/tool-file.ts
|
|
3203
3301
|
var ToolFile = class extends AiFile {
|
|
3204
3302
|
};
|
|
@@ -3289,91 +3387,13 @@ var ToolHooks = class extends ToolFile {
|
|
|
3289
3387
|
};
|
|
3290
3388
|
|
|
3291
3389
|
// src/features/hooks/claudecode-hooks.ts
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
}
|
|
3300
|
-
const effectiveHooks = {
|
|
3301
|
-
...sharedHooks,
|
|
3302
|
-
...config.claudecode?.hooks
|
|
3303
|
-
};
|
|
3304
|
-
const claude = {};
|
|
3305
|
-
for (const [eventName, definitions] of Object.entries(effectiveHooks)) {
|
|
3306
|
-
const claudeEventName = CANONICAL_TO_CLAUDE_EVENT_NAMES[eventName] ?? eventName;
|
|
3307
|
-
const byMatcher = /* @__PURE__ */ new Map();
|
|
3308
|
-
for (const def of definitions) {
|
|
3309
|
-
const key = def.matcher ?? "";
|
|
3310
|
-
const list = byMatcher.get(key);
|
|
3311
|
-
if (list) list.push(def);
|
|
3312
|
-
else byMatcher.set(key, [def]);
|
|
3313
|
-
}
|
|
3314
|
-
const entries = [];
|
|
3315
|
-
for (const [matcherKey, defs] of byMatcher) {
|
|
3316
|
-
const hooks = defs.map((def) => {
|
|
3317
|
-
const command = def.command !== void 0 && def.command !== null && !def.command.startsWith("$") ? `$CLAUDE_PROJECT_DIR/${def.command.replace(/^\.\//, "")}` : def.command;
|
|
3318
|
-
return {
|
|
3319
|
-
type: def.type ?? "command",
|
|
3320
|
-
...command !== void 0 && command !== null && { command },
|
|
3321
|
-
...def.timeout !== void 0 && def.timeout !== null && { timeout: def.timeout },
|
|
3322
|
-
...def.prompt !== void 0 && def.prompt !== null && { prompt: def.prompt }
|
|
3323
|
-
};
|
|
3324
|
-
});
|
|
3325
|
-
entries.push(matcherKey ? { matcher: matcherKey, hooks } : { hooks });
|
|
3326
|
-
}
|
|
3327
|
-
claude[claudeEventName] = entries;
|
|
3328
|
-
}
|
|
3329
|
-
return claude;
|
|
3330
|
-
}
|
|
3331
|
-
function isClaudeMatcherEntry(x) {
|
|
3332
|
-
if (x === null || typeof x !== "object") {
|
|
3333
|
-
return false;
|
|
3334
|
-
}
|
|
3335
|
-
if ("matcher" in x && typeof x.matcher !== "string") {
|
|
3336
|
-
return false;
|
|
3337
|
-
}
|
|
3338
|
-
if ("hooks" in x && !Array.isArray(x.hooks)) {
|
|
3339
|
-
return false;
|
|
3340
|
-
}
|
|
3341
|
-
return true;
|
|
3342
|
-
}
|
|
3343
|
-
function claudeHooksToCanonical(claudeHooks) {
|
|
3344
|
-
if (claudeHooks === null || claudeHooks === void 0 || typeof claudeHooks !== "object") {
|
|
3345
|
-
return {};
|
|
3346
|
-
}
|
|
3347
|
-
const canonical = {};
|
|
3348
|
-
for (const [claudeEventName, matcherEntries] of Object.entries(claudeHooks)) {
|
|
3349
|
-
const eventName = CLAUDE_TO_CANONICAL_EVENT_NAMES[claudeEventName] ?? claudeEventName;
|
|
3350
|
-
if (!Array.isArray(matcherEntries)) continue;
|
|
3351
|
-
const defs = [];
|
|
3352
|
-
for (const rawEntry of matcherEntries) {
|
|
3353
|
-
if (!isClaudeMatcherEntry(rawEntry)) continue;
|
|
3354
|
-
const entry = rawEntry;
|
|
3355
|
-
const hooks = entry.hooks ?? [];
|
|
3356
|
-
for (const h of hooks) {
|
|
3357
|
-
const cmd = typeof h.command === "string" ? h.command : void 0;
|
|
3358
|
-
const command = typeof cmd === "string" && cmd.includes("$CLAUDE_PROJECT_DIR/") ? cmd.replace(/^\$CLAUDE_PROJECT_DIR\/?/, "./") : cmd;
|
|
3359
|
-
const hookType = h.type === "command" || h.type === "prompt" ? h.type : "command";
|
|
3360
|
-
const timeout = typeof h.timeout === "number" ? h.timeout : void 0;
|
|
3361
|
-
const prompt = typeof h.prompt === "string" ? h.prompt : void 0;
|
|
3362
|
-
defs.push({
|
|
3363
|
-
type: hookType,
|
|
3364
|
-
...command !== void 0 && command !== null && { command },
|
|
3365
|
-
...timeout !== void 0 && timeout !== null && { timeout },
|
|
3366
|
-
...prompt !== void 0 && prompt !== null && { prompt },
|
|
3367
|
-
...entry.matcher !== void 0 && entry.matcher !== null && entry.matcher !== "" && { matcher: entry.matcher }
|
|
3368
|
-
});
|
|
3369
|
-
}
|
|
3370
|
-
}
|
|
3371
|
-
if (defs.length > 0) {
|
|
3372
|
-
canonical[eventName] = defs;
|
|
3373
|
-
}
|
|
3374
|
-
}
|
|
3375
|
-
return canonical;
|
|
3376
|
-
}
|
|
3390
|
+
var CLAUDE_CONVERTER_CONFIG = {
|
|
3391
|
+
supportedEvents: CLAUDE_HOOK_EVENTS,
|
|
3392
|
+
canonicalToToolEventNames: CANONICAL_TO_CLAUDE_EVENT_NAMES,
|
|
3393
|
+
toolToCanonicalEventNames: CLAUDE_TO_CANONICAL_EVENT_NAMES,
|
|
3394
|
+
projectDirVar: "$CLAUDE_PROJECT_DIR",
|
|
3395
|
+
prefixDotRelativeCommandsOnly: true
|
|
3396
|
+
};
|
|
3377
3397
|
var ClaudecodeHooks = class _ClaudecodeHooks extends ToolHooks {
|
|
3378
3398
|
constructor(params) {
|
|
3379
3399
|
super({
|
|
@@ -3425,7 +3445,11 @@ var ClaudecodeHooks = class _ClaudecodeHooks extends ToolHooks {
|
|
|
3425
3445
|
);
|
|
3426
3446
|
}
|
|
3427
3447
|
const config = rulesyncHooks.getJson();
|
|
3428
|
-
const claudeHooks =
|
|
3448
|
+
const claudeHooks = canonicalToToolHooks({
|
|
3449
|
+
config,
|
|
3450
|
+
toolOverrideHooks: config.claudecode?.hooks,
|
|
3451
|
+
converterConfig: CLAUDE_CONVERTER_CONFIG
|
|
3452
|
+
});
|
|
3429
3453
|
const merged = { ...settings, hooks: claudeHooks };
|
|
3430
3454
|
const fileContent = JSON.stringify(merged, null, 2);
|
|
3431
3455
|
return new _ClaudecodeHooks({
|
|
@@ -3448,7 +3472,10 @@ var ClaudecodeHooks = class _ClaudecodeHooks extends ToolHooks {
|
|
|
3448
3472
|
}
|
|
3449
3473
|
);
|
|
3450
3474
|
}
|
|
3451
|
-
const hooks =
|
|
3475
|
+
const hooks = toolHooksToCanonical({
|
|
3476
|
+
hooks: settings.hooks,
|
|
3477
|
+
converterConfig: CLAUDE_CONVERTER_CONFIG
|
|
3478
|
+
});
|
|
3452
3479
|
return this.toRulesyncHooksDefault({
|
|
3453
3480
|
fileContent: JSON.stringify({ version: 1, hooks }, null, 2)
|
|
3454
3481
|
});
|
|
@@ -3757,91 +3784,12 @@ var CursorHooks = class _CursorHooks extends ToolHooks {
|
|
|
3757
3784
|
|
|
3758
3785
|
// src/features/hooks/factorydroid-hooks.ts
|
|
3759
3786
|
import { join as join24 } from "path";
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
}
|
|
3767
|
-
}
|
|
3768
|
-
const effectiveHooks = {
|
|
3769
|
-
...sharedHooks,
|
|
3770
|
-
...config.factorydroid?.hooks
|
|
3771
|
-
};
|
|
3772
|
-
const result = {};
|
|
3773
|
-
for (const [eventName, definitions] of Object.entries(effectiveHooks)) {
|
|
3774
|
-
const pascalEventName = CANONICAL_TO_FACTORYDROID_EVENT_NAMES[eventName] ?? eventName;
|
|
3775
|
-
const byMatcher = /* @__PURE__ */ new Map();
|
|
3776
|
-
for (const def of definitions) {
|
|
3777
|
-
const key = def.matcher ?? "";
|
|
3778
|
-
const list = byMatcher.get(key);
|
|
3779
|
-
if (list) list.push(def);
|
|
3780
|
-
else byMatcher.set(key, [def]);
|
|
3781
|
-
}
|
|
3782
|
-
const entries = [];
|
|
3783
|
-
for (const [matcherKey, defs] of byMatcher) {
|
|
3784
|
-
const hooks = defs.map((def) => {
|
|
3785
|
-
const command = def.command !== void 0 && def.command !== null && !def.command.startsWith("$") ? `$FACTORY_PROJECT_DIR/${def.command.replace(/^\.\//, "")}` : def.command;
|
|
3786
|
-
return {
|
|
3787
|
-
type: def.type ?? "command",
|
|
3788
|
-
...command !== void 0 && command !== null && { command },
|
|
3789
|
-
...def.timeout !== void 0 && def.timeout !== null && { timeout: def.timeout },
|
|
3790
|
-
...def.prompt !== void 0 && def.prompt !== null && { prompt: def.prompt }
|
|
3791
|
-
};
|
|
3792
|
-
});
|
|
3793
|
-
entries.push(matcherKey ? { matcher: matcherKey, hooks } : { hooks });
|
|
3794
|
-
}
|
|
3795
|
-
result[pascalEventName] = entries;
|
|
3796
|
-
}
|
|
3797
|
-
return result;
|
|
3798
|
-
}
|
|
3799
|
-
function isFactorydroidMatcherEntry(x) {
|
|
3800
|
-
if (x === null || typeof x !== "object") {
|
|
3801
|
-
return false;
|
|
3802
|
-
}
|
|
3803
|
-
if ("matcher" in x && typeof x.matcher !== "string") {
|
|
3804
|
-
return false;
|
|
3805
|
-
}
|
|
3806
|
-
if ("hooks" in x && !Array.isArray(x.hooks)) {
|
|
3807
|
-
return false;
|
|
3808
|
-
}
|
|
3809
|
-
return true;
|
|
3810
|
-
}
|
|
3811
|
-
function factorydroidHooksToCanonical(hooks) {
|
|
3812
|
-
if (hooks === null || hooks === void 0 || typeof hooks !== "object") {
|
|
3813
|
-
return {};
|
|
3814
|
-
}
|
|
3815
|
-
const canonical = {};
|
|
3816
|
-
for (const [pascalEventName, matcherEntries] of Object.entries(hooks)) {
|
|
3817
|
-
const eventName = FACTORYDROID_TO_CANONICAL_EVENT_NAMES[pascalEventName] ?? pascalEventName;
|
|
3818
|
-
if (!Array.isArray(matcherEntries)) continue;
|
|
3819
|
-
const defs = [];
|
|
3820
|
-
for (const rawEntry of matcherEntries) {
|
|
3821
|
-
if (!isFactorydroidMatcherEntry(rawEntry)) continue;
|
|
3822
|
-
const entry = rawEntry;
|
|
3823
|
-
const hookDefs = entry.hooks ?? [];
|
|
3824
|
-
for (const h of hookDefs) {
|
|
3825
|
-
const cmd = typeof h.command === "string" ? h.command : void 0;
|
|
3826
|
-
const command = typeof cmd === "string" && cmd.includes("$FACTORY_PROJECT_DIR/") ? cmd.replace(/^\$FACTORY_PROJECT_DIR\/?/, "./") : cmd;
|
|
3827
|
-
const hookType = h.type === "command" || h.type === "prompt" ? h.type : "command";
|
|
3828
|
-
const timeout = typeof h.timeout === "number" ? h.timeout : void 0;
|
|
3829
|
-
const prompt = typeof h.prompt === "string" ? h.prompt : void 0;
|
|
3830
|
-
defs.push({
|
|
3831
|
-
type: hookType,
|
|
3832
|
-
...command !== void 0 && command !== null && { command },
|
|
3833
|
-
...timeout !== void 0 && timeout !== null && { timeout },
|
|
3834
|
-
...prompt !== void 0 && prompt !== null && { prompt },
|
|
3835
|
-
...entry.matcher !== void 0 && entry.matcher !== null && entry.matcher !== "" && { matcher: entry.matcher }
|
|
3836
|
-
});
|
|
3837
|
-
}
|
|
3838
|
-
}
|
|
3839
|
-
if (defs.length > 0) {
|
|
3840
|
-
canonical[eventName] = defs;
|
|
3841
|
-
}
|
|
3842
|
-
}
|
|
3843
|
-
return canonical;
|
|
3844
|
-
}
|
|
3787
|
+
var FACTORYDROID_CONVERTER_CONFIG = {
|
|
3788
|
+
supportedEvents: FACTORYDROID_HOOK_EVENTS,
|
|
3789
|
+
canonicalToToolEventNames: CANONICAL_TO_FACTORYDROID_EVENT_NAMES,
|
|
3790
|
+
toolToCanonicalEventNames: FACTORYDROID_TO_CANONICAL_EVENT_NAMES,
|
|
3791
|
+
projectDirVar: "$FACTORY_PROJECT_DIR"
|
|
3792
|
+
};
|
|
3845
3793
|
var FactorydroidHooks = class _FactorydroidHooks extends ToolHooks {
|
|
3846
3794
|
constructor(params) {
|
|
3847
3795
|
super({
|
|
@@ -3893,7 +3841,11 @@ var FactorydroidHooks = class _FactorydroidHooks extends ToolHooks {
|
|
|
3893
3841
|
);
|
|
3894
3842
|
}
|
|
3895
3843
|
const config = rulesyncHooks.getJson();
|
|
3896
|
-
const factorydroidHooks =
|
|
3844
|
+
const factorydroidHooks = canonicalToToolHooks({
|
|
3845
|
+
config,
|
|
3846
|
+
toolOverrideHooks: config.factorydroid?.hooks,
|
|
3847
|
+
converterConfig: FACTORYDROID_CONVERTER_CONFIG
|
|
3848
|
+
});
|
|
3897
3849
|
const merged = { ...settings, hooks: factorydroidHooks };
|
|
3898
3850
|
const fileContent = JSON.stringify(merged, null, 2);
|
|
3899
3851
|
return new _FactorydroidHooks({
|
|
@@ -3916,7 +3868,10 @@ var FactorydroidHooks = class _FactorydroidHooks extends ToolHooks {
|
|
|
3916
3868
|
}
|
|
3917
3869
|
);
|
|
3918
3870
|
}
|
|
3919
|
-
const hooks =
|
|
3871
|
+
const hooks = toolHooksToCanonical({
|
|
3872
|
+
hooks: settings.hooks,
|
|
3873
|
+
converterConfig: FACTORYDROID_CONVERTER_CONFIG
|
|
3874
|
+
});
|
|
3920
3875
|
return this.toRulesyncHooksDefault({
|
|
3921
3876
|
fileContent: JSON.stringify({ version: 1, hooks }, null, 2)
|
|
3922
3877
|
});
|
|
@@ -3967,7 +3922,10 @@ function canonicalToGeminicliHooks(config) {
|
|
|
3967
3922
|
const entries = [];
|
|
3968
3923
|
for (const [matcherKey, defs] of byMatcher) {
|
|
3969
3924
|
const hooks = defs.map((def) => {
|
|
3970
|
-
const
|
|
3925
|
+
const commandText = def.command;
|
|
3926
|
+
const trimmedCommand = typeof commandText === "string" ? commandText.trimStart() : void 0;
|
|
3927
|
+
const shouldPrefix = typeof trimmedCommand === "string" && !trimmedCommand.startsWith("$") && trimmedCommand.startsWith(".");
|
|
3928
|
+
const command = shouldPrefix && typeof trimmedCommand === "string" ? `$GEMINI_PROJECT_DIR/${trimmedCommand.replace(/^\.\//, "")}` : def.command;
|
|
3971
3929
|
return {
|
|
3972
3930
|
type: def.type ?? "command",
|
|
3973
3931
|
...command !== void 0 && command !== null && { command },
|
|
@@ -7444,7 +7402,7 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
7444
7402
|
};
|
|
7445
7403
|
|
|
7446
7404
|
// src/features/rules/rules-processor.ts
|
|
7447
|
-
import { basename as basename10, join as join113, relative as relative5 } from "path";
|
|
7405
|
+
import { basename as basename10, dirname as dirname3, join as join113, relative as relative5 } from "path";
|
|
7448
7406
|
import { encode } from "@toon-format/toon";
|
|
7449
7407
|
import { z as z54 } from "zod/mini";
|
|
7450
7408
|
|
|
@@ -10713,7 +10671,7 @@ var ToolSubagent = class extends ToolFile {
|
|
|
10713
10671
|
// src/features/subagents/simulated-subagent.ts
|
|
10714
10672
|
var SimulatedSubagentFrontmatterSchema = z39.object({
|
|
10715
10673
|
name: z39.string(),
|
|
10716
|
-
description: z39.string()
|
|
10674
|
+
description: z39.optional(z39.string())
|
|
10717
10675
|
});
|
|
10718
10676
|
var SimulatedSubagent = class extends ToolSubagent {
|
|
10719
10677
|
frontmatter;
|
|
@@ -10937,7 +10895,7 @@ import { z as z40 } from "zod/mini";
|
|
|
10937
10895
|
var RulesyncSubagentFrontmatterSchema = z40.looseObject({
|
|
10938
10896
|
targets: z40._default(RulesyncTargetsSchema, ["*"]),
|
|
10939
10897
|
name: z40.string(),
|
|
10940
|
-
description: z40.string()
|
|
10898
|
+
description: z40.optional(z40.string())
|
|
10941
10899
|
});
|
|
10942
10900
|
var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
10943
10901
|
frontmatter;
|
|
@@ -11008,7 +10966,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
11008
10966
|
// src/features/subagents/claudecode-subagent.ts
|
|
11009
10967
|
var ClaudecodeSubagentFrontmatterSchema = z41.looseObject({
|
|
11010
10968
|
name: z41.string(),
|
|
11011
|
-
description: z41.string(),
|
|
10969
|
+
description: z41.optional(z41.string()),
|
|
11012
10970
|
model: z41.optional(z41.string()),
|
|
11013
10971
|
tools: z41.optional(z41.union([z41.string(), z41.array(z41.string())])),
|
|
11014
10972
|
permissionMode: z41.optional(z41.string()),
|
|
@@ -11218,7 +11176,7 @@ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
|
|
|
11218
11176
|
const rulesyncFrontmatter = {
|
|
11219
11177
|
targets: ["codexcli"],
|
|
11220
11178
|
name,
|
|
11221
|
-
description
|
|
11179
|
+
description,
|
|
11222
11180
|
// Only include codexcli section if there are fields
|
|
11223
11181
|
...Object.keys(codexcliSection).length > 0 && { codexcli: codexcliSection }
|
|
11224
11182
|
};
|
|
@@ -11331,7 +11289,7 @@ import { z as z43 } from "zod/mini";
|
|
|
11331
11289
|
var REQUIRED_TOOL = "agent/runSubagent";
|
|
11332
11290
|
var CopilotSubagentFrontmatterSchema = z43.looseObject({
|
|
11333
11291
|
name: z43.string(),
|
|
11334
|
-
description: z43.string(),
|
|
11292
|
+
description: z43.optional(z43.string()),
|
|
11335
11293
|
tools: z43.optional(z43.union([z43.string(), z43.array(z43.string())]))
|
|
11336
11294
|
});
|
|
11337
11295
|
var normalizeTools = (tools) => {
|
|
@@ -11496,7 +11454,7 @@ import { join as join85 } from "path";
|
|
|
11496
11454
|
import { z as z44 } from "zod/mini";
|
|
11497
11455
|
var CursorSubagentFrontmatterSchema = z44.looseObject({
|
|
11498
11456
|
name: z44.string(),
|
|
11499
|
-
description: z44.string()
|
|
11457
|
+
description: z44.optional(z44.string())
|
|
11500
11458
|
});
|
|
11501
11459
|
var CursorSubagent = class _CursorSubagent extends ToolSubagent {
|
|
11502
11460
|
frontmatter;
|
|
@@ -11701,7 +11659,7 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
|
|
|
11701
11659
|
const rulesyncFrontmatter = {
|
|
11702
11660
|
targets: ["kiro"],
|
|
11703
11661
|
name,
|
|
11704
|
-
description: description ??
|
|
11662
|
+
description: description ?? void 0,
|
|
11705
11663
|
// Only include kiro section if there are fields
|
|
11706
11664
|
...Object.keys(kiroSection).length > 0 && { kiro: kiroSection }
|
|
11707
11665
|
};
|
|
@@ -11812,7 +11770,7 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
|
|
|
11812
11770
|
import { basename as basename8, join as join87 } from "path";
|
|
11813
11771
|
import { z as z46 } from "zod/mini";
|
|
11814
11772
|
var OpenCodeSubagentFrontmatterSchema = z46.looseObject({
|
|
11815
|
-
description: z46.string(),
|
|
11773
|
+
description: z46.optional(z46.string()),
|
|
11816
11774
|
mode: z46._default(z46.string(), "subagent"),
|
|
11817
11775
|
name: z46.optional(z46.string())
|
|
11818
11776
|
});
|
|
@@ -12642,7 +12600,7 @@ var globStrategy = {
|
|
|
12642
12600
|
},
|
|
12643
12601
|
exportRulesyncData: ({ description, ...frontmatter }) => ({
|
|
12644
12602
|
globs: parseGlobsString(frontmatter.globs),
|
|
12645
|
-
description
|
|
12603
|
+
description,
|
|
12646
12604
|
antigravity: frontmatter
|
|
12647
12605
|
})
|
|
12648
12606
|
};
|
|
@@ -12654,7 +12612,7 @@ var manualStrategy = {
|
|
|
12654
12612
|
}),
|
|
12655
12613
|
exportRulesyncData: ({ description, ...frontmatter }) => ({
|
|
12656
12614
|
globs: [],
|
|
12657
|
-
description
|
|
12615
|
+
description,
|
|
12658
12616
|
antigravity: frontmatter
|
|
12659
12617
|
})
|
|
12660
12618
|
};
|
|
@@ -12666,7 +12624,7 @@ var alwaysOnStrategy = {
|
|
|
12666
12624
|
}),
|
|
12667
12625
|
exportRulesyncData: ({ description, ...frontmatter }) => ({
|
|
12668
12626
|
globs: ["**/*"],
|
|
12669
|
-
description
|
|
12627
|
+
description,
|
|
12670
12628
|
antigravity: frontmatter
|
|
12671
12629
|
})
|
|
12672
12630
|
};
|
|
@@ -12679,7 +12637,7 @@ var modelDecisionStrategy = {
|
|
|
12679
12637
|
}),
|
|
12680
12638
|
exportRulesyncData: ({ description, ...frontmatter }) => ({
|
|
12681
12639
|
globs: [],
|
|
12682
|
-
description
|
|
12640
|
+
description,
|
|
12683
12641
|
antigravity: frontmatter
|
|
12684
12642
|
})
|
|
12685
12643
|
};
|
|
@@ -12694,7 +12652,7 @@ var unknownStrategy = {
|
|
|
12694
12652
|
},
|
|
12695
12653
|
exportRulesyncData: ({ description, ...frontmatter }) => ({
|
|
12696
12654
|
globs: frontmatter.globs ? parseGlobsString(frontmatter.globs) : ["**/*"],
|
|
12697
|
-
description
|
|
12655
|
+
description,
|
|
12698
12656
|
antigravity: frontmatter
|
|
12699
12657
|
})
|
|
12700
12658
|
};
|
|
@@ -12716,7 +12674,7 @@ var inferenceStrategy = {
|
|
|
12716
12674
|
},
|
|
12717
12675
|
exportRulesyncData: ({ description, ...frontmatter }) => ({
|
|
12718
12676
|
globs: frontmatter.globs ? parseGlobsString(frontmatter.globs) : ["**/*"],
|
|
12719
|
-
description
|
|
12677
|
+
description,
|
|
12720
12678
|
antigravity: frontmatter
|
|
12721
12679
|
})
|
|
12722
12680
|
};
|
|
@@ -12846,7 +12804,6 @@ var AntigravityRule = class _AntigravityRule extends ToolRule {
|
|
|
12846
12804
|
const strategy = STRATEGIES.find((s) => s.canHandle(this.frontmatter.trigger));
|
|
12847
12805
|
let rulesyncData = {
|
|
12848
12806
|
globs: [],
|
|
12849
|
-
description: "",
|
|
12850
12807
|
antigravity: this.frontmatter
|
|
12851
12808
|
};
|
|
12852
12809
|
if (strategy) {
|
|
@@ -12916,7 +12873,6 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
|
12916
12873
|
const rulesyncFrontmatter = {
|
|
12917
12874
|
root: this.isRoot(),
|
|
12918
12875
|
targets: ["*"],
|
|
12919
|
-
description: "",
|
|
12920
12876
|
globs: this.isRoot() ? ["**/*"] : []
|
|
12921
12877
|
};
|
|
12922
12878
|
return new RulesyncRule({
|
|
@@ -13091,6 +13047,12 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
|
|
|
13091
13047
|
relativeDirPath: ".",
|
|
13092
13048
|
relativeFilePath: "CLAUDE.md"
|
|
13093
13049
|
},
|
|
13050
|
+
alternativeRoots: [
|
|
13051
|
+
{
|
|
13052
|
+
relativeDirPath: ".claude",
|
|
13053
|
+
relativeFilePath: "CLAUDE.md"
|
|
13054
|
+
}
|
|
13055
|
+
],
|
|
13094
13056
|
nonRoot: {
|
|
13095
13057
|
relativeDirPath: buildToolPath(".claude", "memories", excludeToolDir)
|
|
13096
13058
|
}
|
|
@@ -13100,18 +13062,19 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
|
|
|
13100
13062
|
baseDir = process.cwd(),
|
|
13101
13063
|
relativeFilePath,
|
|
13102
13064
|
validate = true,
|
|
13103
|
-
global = false
|
|
13065
|
+
global = false,
|
|
13066
|
+
relativeDirPath: overrideDirPath
|
|
13104
13067
|
}) {
|
|
13105
13068
|
const paths = this.getSettablePaths({ global });
|
|
13106
13069
|
const isRoot = relativeFilePath === paths.root.relativeFilePath;
|
|
13107
13070
|
if (isRoot) {
|
|
13108
|
-
const
|
|
13071
|
+
const rootDirPath = overrideDirPath ?? paths.root.relativeDirPath;
|
|
13109
13072
|
const fileContent2 = await readFileContent(
|
|
13110
|
-
join95(baseDir, paths.root.
|
|
13073
|
+
join95(baseDir, rootDirPath, paths.root.relativeFilePath)
|
|
13111
13074
|
);
|
|
13112
13075
|
return new _ClaudecodeLegacyRule({
|
|
13113
13076
|
baseDir,
|
|
13114
|
-
relativeDirPath:
|
|
13077
|
+
relativeDirPath: rootDirPath,
|
|
13115
13078
|
relativeFilePath: paths.root.relativeFilePath,
|
|
13116
13079
|
fileContent: fileContent2,
|
|
13117
13080
|
validate,
|
|
@@ -13206,6 +13169,12 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
13206
13169
|
relativeDirPath: ".",
|
|
13207
13170
|
relativeFilePath: "CLAUDE.md"
|
|
13208
13171
|
},
|
|
13172
|
+
alternativeRoots: [
|
|
13173
|
+
{
|
|
13174
|
+
relativeDirPath: ".claude",
|
|
13175
|
+
relativeFilePath: "CLAUDE.md"
|
|
13176
|
+
}
|
|
13177
|
+
],
|
|
13209
13178
|
nonRoot: {
|
|
13210
13179
|
relativeDirPath: buildToolPath(".claude", "rules", excludeToolDir)
|
|
13211
13180
|
}
|
|
@@ -13238,17 +13207,19 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
13238
13207
|
baseDir = process.cwd(),
|
|
13239
13208
|
relativeFilePath,
|
|
13240
13209
|
validate = true,
|
|
13241
|
-
global = false
|
|
13210
|
+
global = false,
|
|
13211
|
+
relativeDirPath: overrideDirPath
|
|
13242
13212
|
}) {
|
|
13243
13213
|
const paths = this.getSettablePaths({ global });
|
|
13244
13214
|
const isRoot = relativeFilePath === paths.root.relativeFilePath;
|
|
13245
13215
|
if (isRoot) {
|
|
13216
|
+
const rootDirPath = overrideDirPath ?? paths.root.relativeDirPath;
|
|
13246
13217
|
const fileContent2 = await readFileContent(
|
|
13247
|
-
join96(baseDir,
|
|
13218
|
+
join96(baseDir, rootDirPath, paths.root.relativeFilePath)
|
|
13248
13219
|
);
|
|
13249
13220
|
return new _ClaudecodeRule({
|
|
13250
13221
|
baseDir,
|
|
13251
|
-
relativeDirPath:
|
|
13222
|
+
relativeDirPath: rootDirPath,
|
|
13252
13223
|
relativeFilePath: paths.root.relativeFilePath,
|
|
13253
13224
|
frontmatter: {},
|
|
13254
13225
|
body: fileContent2.trim(),
|
|
@@ -15605,35 +15576,62 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
15605
15576
|
const settablePaths = factory.class.getSettablePaths({
|
|
15606
15577
|
global: this.global
|
|
15607
15578
|
});
|
|
15579
|
+
const resolveRelativeDirPath = (filePath) => {
|
|
15580
|
+
const dirName = dirname3(relative5(this.baseDir, filePath));
|
|
15581
|
+
return dirName === "" ? "." : dirName;
|
|
15582
|
+
};
|
|
15583
|
+
const findFilesWithFallback = async (primaryGlob, alternativeRoots, buildAltGlob) => {
|
|
15584
|
+
const primaryFilePaths = await findFilesByGlobs(primaryGlob);
|
|
15585
|
+
if (primaryFilePaths.length > 0) {
|
|
15586
|
+
return primaryFilePaths;
|
|
15587
|
+
}
|
|
15588
|
+
if (alternativeRoots) {
|
|
15589
|
+
return findFilesByGlobs(alternativeRoots.map(buildAltGlob));
|
|
15590
|
+
}
|
|
15591
|
+
return [];
|
|
15592
|
+
};
|
|
15608
15593
|
const rootToolRules = await (async () => {
|
|
15609
15594
|
if (!settablePaths.root) {
|
|
15610
15595
|
return [];
|
|
15611
15596
|
}
|
|
15612
|
-
const
|
|
15597
|
+
const uniqueRootFilePaths = await findFilesWithFallback(
|
|
15613
15598
|
join113(
|
|
15614
15599
|
this.baseDir,
|
|
15615
15600
|
settablePaths.root.relativeDirPath ?? ".",
|
|
15616
15601
|
settablePaths.root.relativeFilePath
|
|
15617
|
-
)
|
|
15602
|
+
),
|
|
15603
|
+
settablePaths.alternativeRoots,
|
|
15604
|
+
(alt) => join113(this.baseDir, alt.relativeDirPath, alt.relativeFilePath)
|
|
15618
15605
|
);
|
|
15619
15606
|
if (forDeletion) {
|
|
15620
|
-
return
|
|
15621
|
-
(filePath)
|
|
15607
|
+
return uniqueRootFilePaths.map((filePath) => {
|
|
15608
|
+
const relativeDirPath = resolveRelativeDirPath(filePath);
|
|
15609
|
+
checkPathTraversal({
|
|
15610
|
+
relativePath: relativeDirPath,
|
|
15611
|
+
intendedRootDir: this.baseDir
|
|
15612
|
+
});
|
|
15613
|
+
return factory.class.forDeletion({
|
|
15622
15614
|
baseDir: this.baseDir,
|
|
15623
|
-
relativeDirPath
|
|
15615
|
+
relativeDirPath,
|
|
15624
15616
|
relativeFilePath: basename10(filePath),
|
|
15625
15617
|
global: this.global
|
|
15626
|
-
})
|
|
15627
|
-
).filter((rule) => rule.isDeletable());
|
|
15618
|
+
});
|
|
15619
|
+
}).filter((rule) => rule.isDeletable());
|
|
15628
15620
|
}
|
|
15629
15621
|
return await Promise.all(
|
|
15630
|
-
|
|
15631
|
-
(filePath)
|
|
15622
|
+
uniqueRootFilePaths.map((filePath) => {
|
|
15623
|
+
const relativeDirPath = resolveRelativeDirPath(filePath);
|
|
15624
|
+
checkPathTraversal({
|
|
15625
|
+
relativePath: relativeDirPath,
|
|
15626
|
+
intendedRootDir: this.baseDir
|
|
15627
|
+
});
|
|
15628
|
+
return factory.class.fromFile({
|
|
15632
15629
|
baseDir: this.baseDir,
|
|
15633
15630
|
relativeFilePath: basename10(filePath),
|
|
15631
|
+
relativeDirPath,
|
|
15634
15632
|
global: this.global
|
|
15635
|
-
})
|
|
15636
|
-
)
|
|
15633
|
+
});
|
|
15634
|
+
})
|
|
15637
15635
|
);
|
|
15638
15636
|
})();
|
|
15639
15637
|
logger.debug(`Found ${rootToolRules.length} root tool rule files`);
|
|
@@ -15647,17 +15645,24 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
15647
15645
|
if (!settablePaths.root) {
|
|
15648
15646
|
return [];
|
|
15649
15647
|
}
|
|
15650
|
-
const
|
|
15651
|
-
join113(this.baseDir, settablePaths.root.relativeDirPath ?? ".", "CLAUDE.local.md")
|
|
15648
|
+
const uniqueLocalRootFilePaths = await findFilesWithFallback(
|
|
15649
|
+
join113(this.baseDir, settablePaths.root.relativeDirPath ?? ".", "CLAUDE.local.md"),
|
|
15650
|
+
settablePaths.alternativeRoots,
|
|
15651
|
+
(alt) => join113(this.baseDir, alt.relativeDirPath, "CLAUDE.local.md")
|
|
15652
15652
|
);
|
|
15653
|
-
return
|
|
15654
|
-
(filePath)
|
|
15653
|
+
return uniqueLocalRootFilePaths.map((filePath) => {
|
|
15654
|
+
const relativeDirPath = resolveRelativeDirPath(filePath);
|
|
15655
|
+
checkPathTraversal({
|
|
15656
|
+
relativePath: relativeDirPath,
|
|
15657
|
+
intendedRootDir: this.baseDir
|
|
15658
|
+
});
|
|
15659
|
+
return factory.class.forDeletion({
|
|
15655
15660
|
baseDir: this.baseDir,
|
|
15656
|
-
relativeDirPath
|
|
15661
|
+
relativeDirPath,
|
|
15657
15662
|
relativeFilePath: basename10(filePath),
|
|
15658
15663
|
global: this.global
|
|
15659
|
-
})
|
|
15660
|
-
).filter((rule) => rule.isDeletable());
|
|
15664
|
+
});
|
|
15665
|
+
}).filter((rule) => rule.isDeletable());
|
|
15661
15666
|
})();
|
|
15662
15667
|
logger.debug(`Found ${localRootToolRules.length} local root tool rule files for deletion`);
|
|
15663
15668
|
const nonRootToolRules = await (async () => {
|