Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c85f6bd701 |
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "ratatoskr"
|
name = "ratatoskr"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
description = "Worldtree Conversation API debug TUI — multi-pane observability dashboard"
|
description = "Worldtree Conversation API debug TUI — multi-pane observability dashboard"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|||||||
+35
-3
@@ -214,6 +214,33 @@ class TuiPresenterState:
|
|||||||
class RatatoskrApp(App[int]):
|
class RatatoskrApp(App[int]):
|
||||||
"""Textual TUI shell — single chat pane."""
|
"""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]] = [
|
BINDINGS: ClassVar[list[Binding]] = [
|
||||||
Binding("ctrl+c", "interrupt", "Cancel / Exit", priority=True),
|
Binding("ctrl+c", "interrupt", "Cancel / Exit", priority=True),
|
||||||
Binding("ctrl+d", "quit", "Exit immediately", priority=True),
|
Binding("ctrl+d", "quit", "Exit immediately", priority=True),
|
||||||
@@ -243,6 +270,14 @@ class RatatoskrApp(App[int]):
|
|||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Header()
|
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
|
# markup=False so labeled lines like "[cancel_failed] ..." render verbatim
|
||||||
# (Rich would otherwise interpret square-bracket spans as style markup and
|
# (Rich would otherwise interpret square-bracket spans as style markup and
|
||||||
# strip them). The post-Done markdown render uses Markdown() directly which
|
# strip them). The post-Done markdown render uses Markdown() directly which
|
||||||
@@ -255,9 +290,6 @@ class RatatoskrApp(App[int]):
|
|||||||
# always-visible.
|
# always-visible.
|
||||||
yield Static("", id="identity")
|
yield Static("", id="identity")
|
||||||
yield Static(self.HINT_IDLE, id="hint")
|
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()
|
yield Footer()
|
||||||
|
|
||||||
async def on_mount(self) -> None:
|
async def on_mount(self) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user