Skip to main content

Adding a New IDE Parser

swAItch is designed to make adding new IDE support straightforward. You only need to:
  1. Add an enum value
  2. Add data paths
  3. Implement one class
  4. Register it

Step 1: Add the IDE Type

In models.py, add a new value to the IDEType enum:
class IDEType(str, Enum):
    CURSOR = "cursor"
    WINDSURF = "windsurf"        # ← add yours

Step 2: Add Data Paths

In config.py, add the IDE’s data paths to IDEPaths:
@dataclass(frozen=True)
class IDEPaths:
    # ... existing paths ...
    windsurf_cascade: Path = field(init=False)

    def __post_init__(self) -> None:
        # ... existing init ...
        object.__setattr__(
            self,
            "windsurf_cascade",
            home / ".codeium" / "windsurf" / "cascade",
        )

Step 3: Implement the Parser

Create a new file in parsers/ that extends BaseParser:
# parsers/windsurf.py
from swaitch.parsers.base import BaseParser
from swaitch.models import IDEType, IDESource, Conversation

class WindsurfParser(BaseParser):

    @property
    def ide_type(self) -> IDEType:
        return IDEType.WINDSURF

    @property
    def display_name(self) -> str:
        return "Windsurf"

    def detect(self) -> IDESource:
        """Check if Windsurf data exists on this system."""
        path = config.paths.windsurf_cascade
        if path.is_dir():
            return IDESource(
                ide=self.ide_type,
                name=self.display_name,
                data_path=str(path),
                status=SourceStatus.AVAILABLE,
                conversation_count=self._count(),
            )
        return IDESource(
            ide=self.ide_type,
            name=self.display_name,
            data_path=str(path),
            status=SourceStatus.NOT_FOUND,
        )

    def get_watch_paths(self) -> list[Path]:
        """Return directories to monitor for changes."""
        if config.paths.windsurf_cascade.is_dir():
            return [config.paths.windsurf_cascade]
        return []

    def list_conversation_ids(self) -> list[str]:
        """List conversation IDs from Windsurf's data files."""
        # Your implementation here
        ...

    def get_conversation(self, conversation_id: str) -> Conversation:
        """Fetch full conversation by ID."""
        # Your implementation here
        ...

Step 4: Register It

In server.py, add one line to _build_registry():
def _build_registry() -> ParserRegistry:
    registry = ParserRegistry()
    registry.register(CursorParser())
    registry.register(WindsurfParser())      # ← add this
    return registry
That’s it! The MCP tools, file watcher, and everything else automatically pick up the new parser.

Tips

Implement invalidate_cache() if your parser caches data. The file watcher calls this when files change.
Return SourceStatus.NOT_FOUND from detect() if the IDE isn’t installed. Never raise exceptions from detection.
list_conversation_ids() should ideally return results sorted by recency if the underlying storage supports it easily.
Use the metadata dict on Conversation and ChatMessage to pass IDE-specific info that doesn’t fit the standard model.