> ## Documentation Index
> Fetch the complete documentation index at: https://www.swaitch.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Adding Parsers

> How to add support for a new IDE in swAItch

# 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:

```python theme={null}
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`:

```python theme={null}
@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`:

```python theme={null}
# 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()`:

```python theme={null}
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

<AccordionGroup>
  <Accordion title="Use caching">
    Implement `invalidate_cache()` if your parser caches data. The file watcher calls this when files change.
  </Accordion>

  <Accordion title="Handle missing data gracefully">
    Return `SourceStatus.NOT_FOUND` from `detect()` if the IDE isn't installed. Never raise exceptions from detection.
  </Accordion>

  <Accordion title="Sort by recency">
    `list_conversation_ids()` should ideally return results sorted by recency if the underlying storage supports it easily.
  </Accordion>

  <Accordion title="Include metadata">
    Use the `metadata` dict on `Conversation` and `ChatMessage` to pass IDE-specific info that doesn't fit the standard model.
  </Accordion>
</AccordionGroup>
