Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.5.3] - 2026-02-13

### Added
- **Roo Code IDE Support** - Added support for the Roo Code VS Code extension (#32)
- Instructions installed to `.roo/rules/*.md`
- Cross-platform detection via VS Code globalStorage (`rooveterinaryinc.roo-cline`)
- Package system support for instructions, MCP servers, commands, and resources
- Project-level MCP config at `.roo/mcp.json`
- Slash commands at `.roo/commands/`
- Global and project scope support
- IDE capability registry entry for Roo Code
- Component detector recognizes `.roo/rules/` directories

## [0.5.2] - 2026-02-13

### Added
Expand Down
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ ai-config-kit/
│ ├── cursor.py # Cursor (.cursor/rules/*.mdc)
│ ├── cline.py # Cline (.clinerules/*.md)
│ ├── kiro.py # Kiro (.kiro/steering/*.md)
│ ├── roo.py # Roo Code (.roo/rules/*.md)
│ ├── winsurf.py # Windsurf (.windsurf/rules/*.md)
│ ├── copilot.py # GitHub Copilot (.github/instructions/*.md)
│ └── detector.py # Tool detection logic
Expand Down Expand Up @@ -396,6 +397,7 @@ Different IDEs support different component types:
- **Cline**: Instructions and resources only
- **Cursor**: Instructions and resources only
- **Kiro**: Instructions and resources only
- **Roo Code**: Instructions, MCP, commands, and resources
- **Windsurf**: Instructions and resources only
- **GitHub Copilot**: Instructions only

Expand All @@ -406,6 +408,7 @@ Components are translated to IDE-specific formats:
- **Claude Code**: `.md` files in `.claude/rules/`, `.claude/hooks/`, `.claude/commands/`
- **Cline**: `.md` files in `.clinerules/`
- **Cursor**: `.mdc` files in `.cursor/rules/`
- **Roo Code**: `.md` files in `.roo/rules/`, `.roo/commands/`
- **Kiro**: `.md` files in `.kiro/steering/`
- **Windsurf**: `.md` files in `.windsurf/rules/`
- **GitHub Copilot**: `.md` files in `.github/instructions/`
Expand Down
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**Works with:** Claude Code • Claude Desktop • Cline • Cursor • GitHub Copilot • Kiro • Windsurf
**Works with:** Claude Code • Claude Desktop • Cline • Cursor • GitHub Copilot • Kiro • Roo Code • Windsurf

</div>

Expand Down Expand Up @@ -258,16 +258,16 @@ Any IDE-specific content from Git repositories:

Complete configuration bundles with multiple component types:

| Component | Claude | Cline | Cursor | Kiro | Windsurf | Copilot |
|-----------|--------|-------|--------|------|----------|---------|
| Instructions | `.claude/rules/` | `.clinerules/` | `.cursor/rules/` | `.kiro/steering/` | `.windsurf/rules/` | `.github/instructions/` |
| MCP Servers | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ |
| Hooks | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Commands | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Skills | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Workflows | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
| Memory Files | ✅ (CLAUDE.md) | ❌ | ❌ | ❌ | ❌ | ❌ |
| Resources | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Component | Claude | Cline | Cursor | Kiro | Roo Code | Windsurf | Copilot |
|-----------|--------|-------|--------|------|----------|----------|---------|
| Instructions | `.claude/rules/` | `.clinerules/` | `.cursor/rules/` | `.kiro/steering/` | `.roo/rules/` | `.windsurf/rules/` | `.github/instructions/` |
| MCP Servers | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ |
| Hooks | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Commands | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
| Skills | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Workflows | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
| Memory Files | ✅ (CLAUDE.md) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Resources | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |

### MCP Server Configurations

Expand All @@ -287,7 +287,7 @@ Model Context Protocol server setups for enhanced AI capabilities:

- Python 3.10 or higher
- Git (for cloning template repositories)
- One of: Claude Code, Claude Desktop, Cline, Cursor, GitHub Copilot, Kiro, or Windsurf
- One of: Claude Code, Claude Desktop, Cline, Cursor, GitHub Copilot, Kiro, Roo Code, or Windsurf

### Install AI Config Kit

Expand Down
2 changes: 1 addition & 1 deletion aiconfigkit/ai_tools/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class AITool(ABC):
"""
Abstract base class for AI coding tool integrations.

Each AI tool (Cline, Cursor, Copilot, Kiro, Winsurf, Claude) implements this interface
Each AI tool (Cline, Cursor, Copilot, Kiro, Roo Code, Winsurf, Claude) implements this interface
to provide tool-specific installation logic.
"""

Expand Down
24 changes: 24 additions & 0 deletions aiconfigkit/ai_tools/capability_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,30 @@ def supports_component(self, component_type: ComponentType) -> bool:
"MCP configured globally via cline_mcp_settings.json, no project-level MCP support."
),
),
AIToolType.ROO: IDECapability(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Add Roo translator before marking package install support

Registering AIToolType.ROO in the capability registry makes Roo look fully supported for package installation, but install_package() always calls get_translator(target_ide) and aiconfigkit/ai_tools/translator.py#get_translator has no Roo entry, so --ide roo now fails with ValueError before any components are installed. This is a hard failure for the new Roo package flow and should be fixed by adding a Roo translator (or gating Roo out of this path until one exists).

Useful? React with 👍 / 👎.

tool_type=AIToolType.ROO,
tool_name="Roo Code",
supported_components={
ComponentType.INSTRUCTION,
ComponentType.MCP_SERVER,
ComponentType.COMMAND,
ComponentType.RESOURCE,
},
instructions_directory=".roo/rules/",
instruction_file_extension=".md",
supports_project_scope=True,
supports_global_scope=True,
mcp_config_path=None, # Global MCP via globalStorage cline_mcp_settings.json
mcp_project_config_path=".roo/mcp.json",
hooks_directory=None, # Hooks not supported
commands_directory=".roo/commands/",
notes=(
"Roo Code uses .md files in .roo/rules/ directory (recursive). "
"Mode-specific rules in .roo/rules-{mode-slug}/. "
"MCP configured via .roo/mcp.json (project) or globalStorage (global). "
"Slash commands in .roo/commands/. Global rules at ~/.roo/rules/."
),
),
AIToolType.COPILOT: IDECapability(
tool_type=AIToolType.COPILOT,
tool_name="GitHub Copilot",
Expand Down
3 changes: 3 additions & 0 deletions aiconfigkit/ai_tools/detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from aiconfigkit.ai_tools.copilot import CopilotTool
from aiconfigkit.ai_tools.cursor import CursorTool
from aiconfigkit.ai_tools.kiro import KiroTool
from aiconfigkit.ai_tools.roo import RooTool
from aiconfigkit.ai_tools.winsurf import WinsurfTool
from aiconfigkit.core.models import AIToolType

Expand All @@ -24,6 +25,7 @@ def __init__(self) -> None:
AIToolType.CLAUDE: ClaudeTool(),
AIToolType.KIRO: KiroTool(),
AIToolType.CLINE: ClineTool(),
AIToolType.ROO: RooTool(),
}

def detect_installed_tools(self) -> list[AITool]:
Expand Down Expand Up @@ -84,6 +86,7 @@ def get_primary_tool(self) -> Optional[AITool]:
AIToolType.CLAUDE,
AIToolType.KIRO,
AIToolType.CLINE,
AIToolType.ROO,
]

for tool_type in priority:
Expand Down
110 changes: 110 additions & 0 deletions aiconfigkit/ai_tools/roo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
"""Roo Code AI tool integration."""

from pathlib import Path

from aiconfigkit.ai_tools.base import AITool
from aiconfigkit.core.models import AIToolType
from aiconfigkit.utils.paths import get_roo_config_dir


class RooTool(AITool):
"""Integration for Roo Code AI coding tool (VS Code extension).

Roo Code (formerly Roo Cline) uses .roo/rules/ directory at the project root
for AI instructions. Files are .md (Markdown) and are read recursively in
alphabetical order by filename. Numeric prefixes control load order.

Mode-specific rules can be placed in .roo/rules-{mode-slug}/ directories.
Project-level MCP config is at .roo/mcp.json.

Detection is based on the VS Code extension rooveterinaryinc.roo-cline
globalStorage directory.
"""

@property
def tool_type(self) -> AIToolType:
"""Return the AI tool type identifier."""
return AIToolType.ROO

@property
def tool_name(self) -> str:
"""Return human-readable tool name."""
return "Roo Code"

def is_installed(self) -> bool:
"""
Check if Roo Code is installed on the system.

Checks for existence of the Roo Code VS Code extension globalStorage directory
(rooveterinaryinc.roo-cline).

Returns:
True if Roo Code is detected
"""
try:
config_dir = get_roo_config_dir()
return config_dir.exists()
except Exception:
return False

def get_instructions_directory(self) -> Path:
"""
Get the directory where Roo Code global instructions should be installed.

Roo Code supports global rules at ~/.roo/rules/.

Returns:
Path to Roo Code global instructions directory

Raises:
FileNotFoundError: If Roo Code is not installed
"""
if not self.is_installed():
raise FileNotFoundError(f"{self.tool_name} is not installed")
from aiconfigkit.utils.paths import get_home_directory

global_dir = get_home_directory() / ".roo" / "rules"
global_dir.mkdir(parents=True, exist_ok=True)
return global_dir

def get_instruction_file_extension(self) -> str:
"""
Get the file extension for Roo Code instructions.

Roo Code uses markdown (.md) files in the .roo/rules/ directory.

Returns:
File extension including the dot
"""
return ".md"

def get_project_instructions_directory(self, project_root: Path) -> Path:
"""
Get the directory for project-specific Roo Code instructions.

Roo Code stores project-specific rules in .roo/rules/ directory at the
project root. It reads .md files recursively from this directory.
Numeric prefixes (e.g., 01-coding-standards.md) control load order.

Args:
project_root: Path to the project root directory

Returns:
Path to project instructions directory (.roo/rules/)
"""
instructions_dir = project_root / ".roo" / "rules"
instructions_dir.mkdir(parents=True, exist_ok=True)
return instructions_dir

def get_mcp_config_path(self) -> Path:
"""
Get the path to the MCP configuration file for Roo Code.

Roo Code stores project-level MCP config at .roo/mcp.json.
Global MCP config is at the globalStorage settings directory.

Returns:
Path to global MCP configuration file
"""
config_dir = get_roo_config_dir()
return config_dir / "settings" / "cline_mcp_settings.json"
1 change: 1 addition & 0 deletions aiconfigkit/core/component_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ class ComponentDetector:
".windsurf/rules": "windsurf",
".kiro/steering": "kiro",
".clinerules": "cline",
".roo/rules": "roo",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Detect Roo rule files recursively during package creation

Adding .roo/rules here routes Roo instructions through _detect_instructions(), but that function only uses recursive traversal for Copilot and otherwise calls iterdir(), so nested Roo rule files are silently skipped. Roo rules are documented in this change as recursive, so package creation from projects using subdirectories under .roo/rules/ will miss instructions.

Useful? React with 👍 / 👎.

".github/instructions": "copilot",
}

Expand Down
3 changes: 2 additions & 1 deletion aiconfigkit/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class AIToolType(Enum):
CLAUDE = "claude"
KIRO = "kiro"
CLINE = "cline"
ROO = "roo"


class ConflictResolution(Enum):
Expand Down Expand Up @@ -415,7 +416,7 @@ def __post_init__(self) -> None:
"""Validate template file data."""
if not self.path:
raise ValueError("Template file path cannot be empty")
valid_ides = ["all", "cursor", "claude", "windsurf", "copilot", "kiro", "cline"]
valid_ides = ["all", "cursor", "claude", "windsurf", "copilot", "kiro", "cline", "roo"]
if self.ide not in valid_ides:
raise ValueError(f"Invalid IDE type: {self.ide}. Must be one of {valid_ides}")

Expand Down
23 changes: 23 additions & 0 deletions aiconfigkit/utils/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,29 @@ def get_cline_config_dir() -> Path:
raise OSError(f"Unsupported operating system: {os.name}")


def get_roo_config_dir() -> Path:
"""Get Roo Code (VS Code extension) configuration directory based on platform."""
home = get_home_directory()

if os.name == "nt": # Windows
return home / "AppData" / "Roaming" / "Code" / "User" / "globalStorage" / "rooveterinaryinc.roo-cline"
elif os.name == "posix":
if "darwin" in os.uname().sysname.lower(): # macOS
return (
home
/ "Library"
/ "Application Support"
/ "Code"
/ "User"
/ "globalStorage"
/ "rooveterinaryinc.roo-cline"
)
else: # Linux
return home / ".config" / "Code" / "User" / "globalStorage" / "rooveterinaryinc.roo-cline"

raise OSError(f"Unsupported operating system: {os.name}")


def get_claude_config_dir() -> Path:
"""Get Claude Code configuration directory based on platform."""
home = get_home_directory()
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"

[project]
name = "ai-config-kit"
version = "0.5.2"
version = "0.5.3"
description = "Distribute and sync AI coding assistant configurations across teams"
readme = "README.md"
authors = [{ name = "Troy Larson", email = "troy@calvinware.com" }]
requires-python = ">=3.10"
license = { text = "MIT License" }
keywords = ["cli", "ai", "config", "mcp", "cursor", "copilot", "claude", "cline", "kiro", "windsurf"]
keywords = ["cli", "ai", "config", "mcp", "cursor", "copilot", "claude", "cline", "kiro", "roo", "windsurf"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
Expand Down
Loading
Loading