"""Workspace file tree with git status (Rust-backed).""" from __future__ import annotations import re from dataclasses import dataclass from .rust_session import ( git_status, rust_available, workspace_files, workspace_tree, ) _GIT_LINE = re.compile(r"^([ MADRCU?!]{1,2})\s+(.+)$") @dataclass class WorkspacePanel: tree_md: str git_md: str file_choices: list[str] preview_md: str def parse_git_dirty(git_status_text: str) -> dict[str, str]: """Map repo-relative path to a one-character git status marker.""" markers: dict[str, str] = {} for line in git_status_text.splitlines(): m = _GIT_LINE.match(line.strip()) if not m: continue status, path = m.group(1).strip(), m.group(2).strip() if " -> " in path: path = path.split(" -> ")[-1].strip() mark = status.replace(" ", "") markers[path] = mark[-1] if mark else "?" return markers def _preview_md(path: str, content: str) -> str: lang = "python" if path.endswith(".py") else "" return f"**`{path}`**\n```{lang}\n{content}\n```" def build_workspace_panel( workspace: str, selected: str | None = None, *, depth: int = 3, files: dict[str, str] | None = None, ) -> WorkspacePanel: """Build git header, ASCII tree, file picker choices, and file preview.""" if not rust_available(): return WorkspacePanel( tree_md="_smolcode_core not installed_", git_md="", file_choices=[], preview_md="", ) git_text = git_status(workspace) git_lines = git_text.splitlines() git_md = "\n".join(git_lines[:6]) if git_lines else "_not a git repository_" tree_body = workspace_tree(workspace, depth=depth) tree_md = f"```\n{tree_body}\n```" if files is None: files = workspace_files(workspace) dirty = parse_git_dirty(git_text) file_choices: list[str] = [] for path in sorted(files): mark = dirty.get(path, "") label = f"{mark} {path}" if mark else path file_choices.append(label) preview_md = "" if selected: clean = selected if len(selected) > 2 and selected[1] == " " and selected[0] in "MADRCU?!": clean = selected[2:] content = files.get(clean, "") if content: preview_md = _preview_md(clean, content) return WorkspacePanel( tree_md=tree_md, git_md=git_md, file_choices=file_choices, preview_md=preview_md, )