navi-code TUI: render schedule_recall lifecycle (recall_update)
The scheduler/orchestrator already push RecallUpdate (wire type
"recall_update") for the schedule_recall lifecycle, but the TUI had no
mapping or renderer — every event fell to the unknown-event catch-all and
rendered as a raw dict dump. Wire it into a dedicated card.

- chat_model: add a "recall" ChatItem kind and a recall_update branch
  (before the catch-all) that keeps the wire fields in meta.
- chat_panel _item_msg: reconstruct {"type": "recall_update", **meta}
  for a recall item so the registry sees it.
- renderers/recall.py: new RecallRenderer — a compact, color-coded card
  per action (⏰ scheduled/info, ▶ fired·resuming/accent, ✕ cancelled/error,
  ↻ skipped/warning, ↻ rescheduled/info) showing call_type and a trimmed
  trigger_at. Registered before the generic renderers.
- tests: 10 tests covering accepts, each action's title/border color,
  trigger formatting, empty body, chat_model mapping, and _item_msg
  round-trip.

MVP only — the self-instruction (additional_context_message) is not on the
wire, so it remains visible in the schedule_recall tool-call card above;
extending RecallUpdate.to_wire to carry it is a follow-up.

Co-Authored-By: Claude <noreply@anthropic.com>
1 parent b912f2c commit 3573e293c4f26996ddf4fd711285a1319ee86fa9
@Eugene Sukhodolskiy Eugene Sukhodolskiy authored 7 hours ago
Showing 5 changed files
View
clients/terminal/tui/chat_model.py
View
clients/terminal/tui/renderers/__init__.py
View
clients/terminal/tui/renderers/recall.py 0 → 100644
View
clients/terminal/tui/widgets/chat_panel.py
View
tests/clients/test_recall_renderer.py 0 → 100644