from typing import Tuple def init_logger(debug: bool | None) -> PyLogger: ... def codemp_init() -> Client: ... class PyLogger: async def message(self) -> str | None: ... class CodempTextChange: start_incl: int end_excl: int content: str def is_deletion(self) -> bool: ... def is_addition(self) -> bool: ... def is_empty(self) -> bool: ... def apply(self, txt: str) -> str: ... def from_diff(self, before: str, after: str) -> CodempTextChange: ... def index_to_rowcol(self, txt: str, index: int) -> Tuple[int, int]: ... class CodempBufferController: def content(self) -> str: ... def send(self, start: int, end: int, txt: str) -> None: ... async def try_recv(self) -> CodempTextChange | None: ... async def recv(self) -> CodempTextChange: ... async def poll(self) -> None: ... class CodempCursor: start: Tuple[int, int] end: Tuple[int, int] buffer: str user: str # can be an empty string class CodempCursorController: def send(self, path: str, start: Tuple[int, int], end: Tuple[int, int]) -> None: ... def try_recv(self) -> CodempCursor | None: ... async def recv(self) -> CodempCursor: ... async def poll(self) -> None: ... class CodempWorkspace: async def create(self, path: str) -> None: ... async def attach(self, path: str) -> CodempBufferController: ... async def fetch_buffers(self) -> None: ... async def fetch_users(self) -> None: ... async def list_buffer_users(self, path: str) -> list[str]: ... async def delete(self, path: str) -> None: ... def id(self) -> str: ... def cursor(self) -> CodempCursorController: ... def buffer_by_name(self, path: str) -> CodempBufferController: ... def filetree(self) -> list[str]: ... class Client: def __init__(self) -> None: ... async def connect(self, host: str) -> None: ... async def login(self, user: str, password: str, workspace: str | None) -> None: ... async def join_workspace(self, workspace: str) -> CodempWorkspace: ... async def get_workspace(self, id: str) -> CodempWorkspace: ... async def user_id(self) -> str: ...