Add custom SVG exporter, remove Rich from screenshot rendering

- Created svg_exporter.py with direct pyte-to-SVG rendering
- Eliminates Rich's export_svg() quirks (clip path count mismatch)
- Added 63 comprehensive tests for SVG exporter
- Removed Rich imports from local_server.py, terminal_session.py,
  app_session.py, and cli.py
- Replaced RichHandler with standard logging.basicConfig
- Replaced @rich.repr.auto with standard __repr__ methods
- Rich is no longer directly imported (still transitive via textual-serve)

Bump version to 0.3.0
This commit is contained in:
GitHub Copilot
2026-01-24 17:11:20 +00:00
parent d4acdbb4f1
commit d5a060d6aa
9 changed files with 934 additions and 165 deletions
+3 -7
View File
@@ -11,7 +11,6 @@ from enum import Enum, auto
from time import monotonic
from typing import TYPE_CHECKING
import rich.repr
from importlib_metadata import version
from . import constants
@@ -41,7 +40,6 @@ class ProcessState(Enum):
return self.name
@rich.repr.auto(angular=True)
class AppSession(Session):
"""Runs a single app process."""
@@ -128,11 +126,9 @@ class AppSession(Session):
"""Check if the app session is still running."""
return self._state == ProcessState.RUNNING
def __rich_repr__(self) -> rich.repr.Result:
yield self.command
yield "id", self.session_id
if self._process is not None:
yield "returncode", self._process.returncode, None
def __repr__(self) -> str:
returncode = self._process.returncode if self._process else None
return f"<AppSession {self.command!r} id={self.session_id!r} returncode={returncode}>"
async def open(self, width: int = 80, height: int = 24) -> None:
"""Open the process."""