Skip to content

v0.9.x: port REPL output::*/splash::* through RoomSink #327

@spytensor

Description

@spytensor

Context

#326 introduced RoomSink and threaded Arc<dyn RoomSink> through the runtime, but only routed CrepEvent rendering through it. Roughly 117 stdout sites in src/repl.rs and 67 in src/repl/splash.rs still call output::ok/warn/bad/hint/system/tool_trace, print_help, and print_home directly. As long as those bypass the sink, no TUI host can render them, so the runtime can only ever be partially embedded.

This issue extends RoomEvent with the small set of variants needed to model those events and ports every call site over. Behaviour stays identical because StdoutSink keeps doing the same output::* / print_home formatting it does today.

Acceptance Criteria

  • AC-1: RoomEvent gains Banner(String) for multi-line splash/home/help output and reuses existing Notice { level, text } for one-line system notices.
  • AC-2: Every output::ok/warn/bad/hint/system/tool_trace caller in src/repl.rs, src/repl/turn.rs, src/repl/sessions.rs, src/repl/show.rs, and other repl/*.rs modules now goes through sink.emit(RoomEvent::Notice { ... }).
  • AC-3: splash::print_home and splash::print_help either go through sink.emit(RoomEvent::Banner(...)) or are refactored to return String that the caller emits.
  • AC-4: StdoutSink::emit for Notice and Banner produces byte-for-byte identical output to the legacy direct print path (verified by tests that compare the rendered string).
  • AC-5: A new unit test asserts that emitting one notice of each level through StdoutSink produces the same string the legacy output::ok/warn/bad/hint/system produces.
  • AC-6: cargo fmt --all -- --check, cargo clippy --all-targets --all-features -- -D warnings, and cargo test --all-features --locked all pass.

Required Evidence

  • Code diff showing every output::* / splash::print_home / splash::print_help caller in the REPL paths routed through the sink.
  • A grep against src/repl/ confirming no direct output::* calls remain inside the runtime (diagnostic and slash-command paths excepted if explicitly scoped).
  • Unit tests asserting StdoutSink byte-for-byte parity for the new variants.
  • Validation commands and their output.

Non-goals

  • Porting work::render_card, status::StatusRegion, or permission_prompt::* — tracked in separate issues so this work can run in parallel.
  • Writing a TuiSink or any ratatui-side renderer.
  • Changing what cr start displays — output must remain byte-for-byte identical.

Tracker Update Required

The completing PR must list which RoomEvent variants were added, the count of migrated call sites, and confirm cr start output parity.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:clicr command surfacearea:consoleConsole snapshot, control surface, and dashboard data planearea:conversationPublic transcript, host conversation, and internal delegation visibilityarea:tuiFull-screen terminal UI and ratatui consolecodex-readyCodex may pick up autonomouslyenhancementNew feature or requestpriority:highTruth-in-advertising or locked-spec gapsize:M1-3 daysstatus:readyReady to be picked up

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions