9d469d5c67
Issue #4: Textual TUI shell — the interactive primary presenter (design-brief §1, §5). Single chat-pane App[int] subclass + sync run_tui(args) entry. Composes existing sessions + sse_client modules (no forked API-consumption code, per design-brief §8b). Six FN blocks: run_tui, RatatoskrApp class + on_mount + on_unmount, on_input_submitted, _stream_turn_worker, _render_event_to_log, action_interrupt, action_quit, _cancel_via_sse. Nine hard invariants codifying: - INV-001: lazy-import boundary so cli.py STILL doesn't import textual at module scope (issue #3's INV-001 carried forward) - INV-002: session-identity-always-visible footer (`<agent> · …<tail8>`) with explicit `<unknown>` carve-out for --session without --agent - INV-003: two-stage Ctrl-C state machine (idle/streaming/cancelling) per design-brief §8c - INV-005: markdown default-on with --raw opt-out; deliberately produces streaming-deltas + post-Done markdown re-render (accepted v1 trade-off, Static-then-commit refactor deferred) - INV-007: one AsyncClient per app lifetime - INV-008: mid-session errors → idle (don't exit); only initial session-create errors exit Concurrent in-place amendment of issue #3's contract: - --send becomes optional; when omitted, send_content=None is the TUI-mode marker - --raw flag added to ParsedArgs - main dispatches via lazy `from ratatoskr.tui import run_tui` when send_content is None - _parse_args + main TESTS sections updated (no_send_marks_tui_mode replaces usage_no_send; new raw_flag_default_false / raw_flag_set / no_send_dispatches_to_tui) Volva paraphrase round on issue #4: 5 findings, all amended. (1) INV-002 `<unknown>` carve-out wording. (2) Idle "Ctrl-C twice to exit" hint kept per design-brief §8c's conservative-by-design rationale; INV-003 spells out the intentional one-press-from-idle discrepancy. (3) Markdown double-render trade-off made explicit in INV-005. (4) Submit-during-streaming now writes `[busy] turn in flight; input ignored` (visible notice, not silent swallow). (5) `{!r:.200}` format spec kept with explanatory inline comment. Both contracts drift-check clean. prd: pinned to issue #4 body SHA b1e73e7d2e3dd453 at 2026-05-21T06:21:37+00:00.