Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c85f6bd701 |
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "ratatoskr"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
description = "Worldtree Conversation API debug TUI — multi-pane observability dashboard"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
|
||||
+35
-3
@@ -214,6 +214,33 @@ class TuiPresenterState:
|
||||
class RatatoskrApp(App[int]):
|
||||
"""Textual TUI shell — single chat pane."""
|
||||
|
||||
# Issue #12 follow-up: anchor layout so Input never moves.
|
||||
# Pre-fix: every widget was auto-stacked. RichLog grew with content,
|
||||
# thinking-current toggled display 0↔N rows per thinking-run — both pushed
|
||||
# Input around mid-turn. Fix: dock the chrome to the top/bottom edges and
|
||||
# let RichLog (the only `1fr` widget) absorb all layout reflows internally
|
||||
# via its scroll viewport, so screen-relative positions stay stable.
|
||||
DEFAULT_CSS = """
|
||||
#thinking-current {
|
||||
dock: top;
|
||||
height: auto;
|
||||
}
|
||||
#transcript {
|
||||
height: 1fr;
|
||||
}
|
||||
#prompt {
|
||||
dock: bottom;
|
||||
}
|
||||
#identity {
|
||||
dock: bottom;
|
||||
height: 1;
|
||||
}
|
||||
#hint {
|
||||
dock: bottom;
|
||||
height: 1;
|
||||
}
|
||||
"""
|
||||
|
||||
BINDINGS: ClassVar[list[Binding]] = [
|
||||
Binding("ctrl+c", "interrupt", "Cancel / Exit", priority=True),
|
||||
Binding("ctrl+d", "quit", "Exit immediately", priority=True),
|
||||
@@ -243,6 +270,14 @@ class RatatoskrApp(App[int]):
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Header()
|
||||
# Issue #12 follow-up: thinking-current sits at the TOP under Header (via
|
||||
# DEFAULT_CSS `dock: top`). Pre-fix it lived between hint and Footer in
|
||||
# the auto-stacked flow, so its display=True/False toggle per
|
||||
# thinking-run pushed Input + identity + hint up/down on every cycle.
|
||||
# Docking top + RichLog filling middle stabilises Input's screen
|
||||
# position; thinking-current grows/shrinks under Header where the
|
||||
# reflow doesn't affect anything else.
|
||||
yield Static("", id="thinking-current")
|
||||
# markup=False so labeled lines like "[cancel_failed] ..." render verbatim
|
||||
# (Rich would otherwise interpret square-bracket spans as style markup and
|
||||
# strip them). The post-Done markdown render uses Markdown() directly which
|
||||
@@ -255,9 +290,6 @@ class RatatoskrApp(App[int]):
|
||||
# always-visible.
|
||||
yield Static("", id="identity")
|
||||
yield Static(self.HINT_IDLE, id="hint")
|
||||
# Issue #12: live thinking widget — hidden by default, shown per-delta
|
||||
# during a thinking run, cleared+hidden at turn terminal.
|
||||
yield Static("", id="thinking-current")
|
||||
yield Footer()
|
||||
|
||||
async def on_mount(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user