fix: add browser tool group and rulesFiles property to roomodes schema

- Add "browser" to ToolGroup enum (deprecated but accepted for backward compat)
- Add RuleFile definition with relativePath and content properties
- Add optional rulesFiles array property to CustomMode
- Add 6 new tests covering browser groups and rulesFiles validation
This commit is contained in:
Roo Code 2026-02-27 22:07:39 +00:00
parent cfc8a556cf
commit d399085caf
2 changed files with 138 additions and 2 deletions

View file

@ -18,8 +18,8 @@
"definitions": {
"ToolGroup": {
"type": "string",
"enum": ["read", "edit", "command", "mcp", "modes"],
"description": "A tool group name that grants the mode access to a set of tools."
"enum": ["read", "edit", "browser", "command", "mcp", "modes"],
"description": "A tool group name that grants the mode access to a set of tools. Note: 'browser' is deprecated but still accepted for backward compatibility."
},
"GroupOptions": {
"type": "object",
@ -48,6 +48,22 @@
"description": "A tool group permission entry. Either a simple tool group name string, or a [toolGroupName, options] tuple for groups with file restrictions.",
"oneOf": [{ "$ref": "#/definitions/ToolGroup" }, { "$ref": "#/definitions/GroupEntryTuple" }]
},
"RuleFile": {
"type": "object",
"description": "A rules file associated with a mode, used during import/export.",
"required": ["relativePath", "content"],
"additionalProperties": false,
"properties": {
"relativePath": {
"type": "string",
"description": "The relative file path for the rules file."
},
"content": {
"type": "string",
"description": "The text content of the rules file."
}
}
},
"CustomMode": {
"type": "object",
"description": "A custom mode definition.",
@ -92,6 +108,13 @@
"type": "string",
"enum": ["global", "project"],
"description": "Where this mode was defined. Automatically set by Roo Code."
},
"rulesFiles": {
"type": "array",
"description": "Rules files associated with this mode, used during import/export.",
"items": {
"$ref": "#/definitions/RuleFile"
}
}
}
}

View file

@ -273,6 +273,119 @@ describe("roomodes JSON schema", () => {
expect(valid).toBe(true)
})
it("should accept the browser tool group (deprecated but valid)", () => {
const config = {
customModes: [
{
slug: "browser-mode",
name: "Browser Mode",
roleDefinition: "A mode that uses the browser tool group.",
groups: ["read", "browser", "command"],
},
],
}
const valid = validate(config)
expect(validate.errors).toBeNull()
expect(valid).toBe(true)
})
it("should accept a browser tuple group entry", () => {
const config = {
customModes: [
{
slug: "browser-tuple",
name: "Browser Tuple",
roleDefinition: "A mode with browser tuple.",
groups: [["browser", { fileRegex: "\\.html$", description: "HTML files only" }]],
},
],
}
const valid = validate(config)
expect(validate.errors).toBeNull()
expect(valid).toBe(true)
})
it("should accept a mode with rulesFiles", () => {
const config = {
customModes: [
{
slug: "rules-mode",
name: "Rules Mode",
roleDefinition: "A mode with rules files.",
groups: ["read"],
rulesFiles: [
{
relativePath: "rule1.md",
content: "# Rule 1\nFollow this rule.",
},
{
relativePath: "subfolder/rule2.md",
content: "# Rule 2\nFollow this other rule.",
},
],
},
],
}
const valid = validate(config)
expect(validate.errors).toBeNull()
expect(valid).toBe(true)
})
it("should accept a mode with empty rulesFiles array", () => {
const config = {
customModes: [
{
slug: "empty-rules",
name: "Empty Rules",
roleDefinition: "A mode with empty rules files.",
groups: ["read"],
rulesFiles: [],
},
],
}
const valid = validate(config)
expect(validate.errors).toBeNull()
expect(valid).toBe(true)
})
it("should reject rulesFiles entries missing required fields", () => {
const config = {
customModes: [
{
slug: "bad-rules",
name: "Bad Rules",
roleDefinition: "A mode with invalid rules files.",
groups: ["read"],
rulesFiles: [{ relativePath: "rule1.md" }],
},
],
}
const valid = validate(config)
expect(valid).toBe(false)
})
it("should reject rulesFiles entries with extra properties", () => {
const config = {
customModes: [
{
slug: "extra-rules",
name: "Extra Rules",
roleDefinition: "A mode with extra rule properties.",
groups: ["read"],
rulesFiles: [{ relativePath: "rule1.md", content: "content", extra: true }],
},
],
}
const valid = validate(config)
expect(valid).toBe(false)
})
it("should accept multiple modes", () => {
const config = {
customModes: [