Skip to content

feat: add correct JSON schema for .roomodes configuration files#11791

Open
roomote[bot] wants to merge 4 commits intomainfrom
feature/fix-roomodes-json-schema
Open

feat: add correct JSON schema for .roomodes configuration files#11791
roomote[bot] wants to merge 4 commits intomainfrom
feature/fix-roomodes-json-schema

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Feb 27, 2026

Related GitHub Issue

Closes: #11790

Description

This PR attempts to address Issue #11790 by adding a correct JSON Schema (draft-07) for .roomodes configuration files that accurately reflects the actual internal types defined in packages/types/src/mode.ts.

The existing SchemaStore schema at https://www.schemastore.org/roomodes.json has several discrepancies with the actual format Roo Code uses:

  1. Missing properties: The schema lacked description and source on CustomMode
  2. Wrong groups format: The schema used { type: "edit", allowedPaths: [...] } but Roo Code uses tuple format ["edit", { fileRegex: "...", description: "..." }]
  3. Property naming mismatch: allowedPaths/disallowedPaths vs fileRegex/description

Key implementation details:

  • Created schemas/roomodes.json with draft-07 syntax (using items array + additionalItems: false for tuple validation)
  • All CustomMode properties are represented: slug, name, roleDefinition, whenToUse, description, customInstructions, groups, source
  • GroupEntry is modeled as oneOf: either a simple tool group string enum or a [ToolGroup, GroupOptions] tuple
  • All five tool groups supported: read, edit, command, mcp, modes

A follow-up PR to SchemaStore to update their copy would be a natural next step.

Feedback and guidance are welcome.

Test Procedure

  • Added 18 tests in src/utils/__tests__/roomodes-schema.spec.ts using ajv to validate the schema
  • Tests cover: minimal configs, full configs with all optional properties, the built-in architect mode with tuple-style edit groups, various invalid configs (missing required fields, invalid slugs, unknown tool groups, extra properties, invalid source values, oversized tuples)
  • Run tests: cd src && npx vitest run utils/__tests__/roomodes-schema.spec.ts
  • All 18 tests pass

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes.
  • Documentation Impact: No documentation updates are required beyond the schema itself.
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Documentation Updates

  • No user-facing documentation updates are required. The schema file itself serves as documentation.

Additional Notes

  • Added ajv as a dev dependency in src/package.json for schema validation in tests.
  • The schema uses JSON Schema draft-07 for broad compatibility with tooling (yaml-language-server, VS Code, etc.).

Interactively review PR in Roo Code Cloud

Adds schemas/roomodes.json that accurately reflects the actual .roomodes
format as defined in packages/types/src/mode.ts. The schema supports:

- All CustomMode properties including optional description and source
- Tuple-style group entries like ["edit", { fileRegex, description }]
- All five tool groups: read, edit, command, mcp, modes

Also adds comprehensive tests validating the schema against valid and
invalid configurations.

Closes #11790
@algorhythm85
Copy link

algorhythm85 commented Feb 27, 2026

@roomote There are things missing from the proposed schema:

  1. Doesn't allow browser as a value for groups items
  2. Doesn't allow rulesFiles property

"definitions": {
"ToolGroup": {
"type": "string",
"enum": ["read", "edit", "command", "mcp", "modes"],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"enum": ["read", "edit", "command", "mcp", "modes"],
"enum": ["read", "edit", "command", "mcp", "modes", "browser"],

@algorhythm85
Copy link

@roomote are you able to implement my suggestions?

@roomote
Copy link
Contributor Author

roomote bot commented Feb 27, 2026

Fixaroo Clock   See task

Fixed the reported issues: added browser to the ToolGroup enum and added the rulesFiles optional property (with RuleFile definition) to CustomMode. All 24 tests pass.

View commit | Revert commit

- 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
"RuleFile": {
"type": "object",
"description": "A rules file associated with a mode, used during import/export.",
"required": ["relativePath", "content"],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@roomote Is content supposed to be required?

Copy link
Contributor Author

@roomote roomote bot Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixaroo Clock   See task

Made content optional in the RuleFile schema definition -- only relativePath remains required. All 25 tests pass.

View commit | Revert commit

The content property in RuleFile is now optional, matching the
defensive runtime check in CustomModesManager that handles missing
content. Only relativePath remains required.
@algorhythm85
Copy link

@roomote LGTM

@roomote
Copy link
Contributor Author

roomote bot commented Feb 27, 2026

Fixaroo Clock   See task

All 25 tests pass locally. Marked PR as ready for review.

@roomote roomote bot marked this pull request as ready for review February 27, 2026 23:18
@dosubot dosubot bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Feb 27, 2026
@algorhythm85
Copy link

@roomote should the JSON schema be dynamically generated in case the typescript types change?

@roomote
Copy link
Contributor Author

roomote bot commented Mar 2, 2026

Proofessor Clock   See task

Converted the static JSON schema to be dynamically generated from the Zod types via zod-to-json-schema. A drift-detection test ensures the checked-in schema stays in sync when types change. All local checks passed (lint, type-check, 26 tests).

View commit | Revert commit

Replace the hand-crafted schemas/roomodes.json with one generated from
the Zod schemas in packages/types/src/mode.ts using zod-to-json-schema.
This ensures the schema stays in sync when TypeScript types change.

- Add zod-to-json-schema dev dependency to packages/types
- Create packages/types/scripts/generate-roomodes-schema.ts
- Add generate:schema npm script to packages/types
- Add drift-detection test in packages/types to catch schema/type mismatches
- Update existing AJV validation tests with documentation comment
@algorhythm85
Copy link

@mrubens @cte @jr @hannesrudolph @daniel-lxs Any thoughts on this? Concerns?

Personally I prefer the structure in the currently published JSON schema (always been tough for me to wrap my head around "array of arrays" in YAML), but didn't want to introduce any breaking changes by proposing modifications to the typescript types/interfaces

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] .roomodes doesn't align with published JSON schema

2 participants