From 93b795a7051f8b7cd40d583968346dd74977d089 Mon Sep 17 00:00:00 2001 From: Roo Code Date: Sat, 19 Jul 2025 01:20:45 +0000 Subject: [PATCH] fix: add JSON schema for custom modes YAML validation - Created custom-modes.schema.json with complete schema matching Zod types - Added yamlValidation contribution to package.json for .roomodes and custom_modes.yaml - Includes support for description field which was missing from VS Code validation Fixes #5938 --- src/package.json | 11 ++- src/schemas/custom-modes.schema.json | 105 +++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 src/schemas/custom-modes.schema.json diff --git a/src/package.json b/src/package.json index b6602e5d8e..b1573d7a0b 100644 --- a/src/package.json +++ b/src/package.json @@ -388,7 +388,16 @@ "description": "%settings.autoImportSettingsPath.description%" } } - } + }, + "yamlValidation": [ + { + "fileMatch": [ + ".roomodes", + "custom_modes.yaml" + ], + "url": "./schemas/custom-modes.schema.json" + } + ] }, "scripts": { "lint": "eslint . --ext=ts --max-warnings=0", diff --git a/src/schemas/custom-modes.schema.json b/src/schemas/custom-modes.schema.json new file mode 100644 index 0000000000..3936959387 --- /dev/null +++ b/src/schemas/custom-modes.schema.json @@ -0,0 +1,105 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Custom Modes Configuration", + "description": "Schema for Roo Code custom modes configuration files (.roomodes and custom_modes.yaml)", + "type": "object", + "properties": { + "customModes": { + "type": "array", + "description": "Array of custom mode configurations", + "items": { + "$ref": "#/definitions/modeConfig" + }, + "uniqueItems": true + } + }, + "required": ["customModes"], + "additionalProperties": false, + "definitions": { + "modeConfig": { + "type": "object", + "description": "Configuration for a single custom mode", + "properties": { + "slug": { + "type": "string", + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Unique identifier for the mode (letters, numbers, and dashes only)" + }, + "name": { + "type": "string", + "minLength": 1, + "description": "Display name for the mode" + }, + "roleDefinition": { + "type": "string", + "minLength": 1, + "description": "Detailed description of the mode's role and capabilities" + }, + "whenToUse": { + "type": "string", + "description": "Description of when this mode should be used" + }, + "description": { + "type": "string", + "description": "Brief description of what the mode does" + }, + "customInstructions": { + "type": "string", + "description": "Additional custom instructions for the mode" + }, + "groups": { + "type": "array", + "description": "Tool groups and permissions for this mode", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/toolGroup" + }, + { + "type": "array", + "items": [ + { + "$ref": "#/definitions/toolGroup" + }, + { + "$ref": "#/definitions/groupOptions" + } + ], + "minItems": 2, + "maxItems": 2 + } + ] + }, + "uniqueItems": true + }, + "source": { + "type": "string", + "enum": ["global", "project"], + "description": "Source of the mode configuration" + } + }, + "required": ["slug", "name", "roleDefinition", "groups"], + "additionalProperties": false + }, + "toolGroup": { + "type": "string", + "enum": ["read", "edit", "browser", "command", "mcp", "modes"], + "description": "Available tool groups" + }, + "groupOptions": { + "type": "object", + "description": "Options for a tool group", + "properties": { + "fileRegex": { + "type": "string", + "description": "Regular expression pattern to match files this group can access" + }, + "description": { + "type": "string", + "description": "Description of what files this pattern matches" + } + }, + "additionalProperties": false + } + } +}