@sigitcode-old / sigit / commits / aa548fb
Fork 1

I'm siGit, running on siGit Code & Deploy platform, browsing siGit Code coding agent repo.

Move the startup check results from the splash into the chat info lines

The splash now shows the wordmark and caption only. The checks still gate it, and their results print under the quote as Account, Models, Workspace and Tools lines. The static rainbow banner in the chat history is gone, since the splash already shows it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Seto Elkahfi committed Oct 28, 2026 at 09:31 UTC aa548fbe88000090a9b4d9277b583d445862e71a
2 files changed +17 -93
crates/cli/src/chat.rs
+17 -92
@@ -529,9 +529,9 @@ mod tui {
529 };
530 use crate::program_status::{Reporter, Status};
531 use crate::session_store::SessionEntry;
532 - use crate::splash::{self, BANNER_ART, Phase, Splash, Wordmark};
532 + use crate::splash::{self, Phase, Splash, Wordmark};
533 use crate::startup::{
534 - self, CHECK_ROWS, Check, Checks, Report, account_check, models_check, tools_check,
534 + self, Check, Checks, Report, account_check, models_check, tools_check,
535 workspace_check,
536 };
537 use ratatui::{
@@ -551,8 +551,6 @@ mod tui {
551 User,
552 Assistant,
553 System,
554 - /// rainbow-colored banner art
555 - Banner,
554 /// a collapsible tool-call entry (`text` holds the title line)
555 Tool,
556 }
@@ -602,16 +600,6 @@ mod tui {
600 }
601 }
602
605 - fn banner(text: impl Into<String>) -> Self {
606 - Self {
607 - role: Role::Banner,
608 - text: text.into(),
609 - think_block: None,
610 - tool_detail: None,
611 - tool_result: None,
612 - }
613 - }
614 -
603 fn tool_call(title: impl Into<String>, detail: impl Into<String>) -> Self {
604 Self {
605 role: Role::Tool,
@@ -1133,16 +1121,20 @@ mod tui {
1121 }
1122 }
1123
1136 - /// switch to chat phase and show the welcome banner
1124 + /// switch to chat phase and show the welcome notes
1125 fn finish_loading(&mut self) {
1126 self.is_loading = false;
1139 - for line in BANNER_ART.lines() {
1140 - self.messages.push(ChatMessage::banner(line));
1141 - }
1142 - self.messages.push(ChatMessage::system(""));
1127 self.messages.push(ChatMessage::system(
1128 "In this world, nothing can be said to be certain, except death and taxes. ~ Pak Sigit",
1129 ));
1130 + for (label, check) in self.checks.rows() {
1131 + match check {
1132 + Check::Ok(d) | Check::Note(d) | Check::Warn(d) => self
1133 + .messages
1134 + .push(ChatMessage::system(format!("{label}: {d}"))),
1135 + Check::Pending => {}
1136 + }
1137 + }
1138 if self.backend.is_remote() {
1139 self.messages.push(ChatMessage::system(format!(
1140 "Current model: {}",
@@ -2267,11 +2259,10 @@ mod tui {
2259 }
2260 }
2261
2270 - /// The launch splash: the wordmark with the startup checks under it. Too
2271 - /// small a terminal gets the caption and the checks without the art.
2262 + /// The launch splash: the wordmark with a caption under it. The startup
2263 + /// checks still gate it, and their results land in the chat's info lines.
2264 + /// Too small a terminal gets the caption without the art.
2265 fn render_splash(frame: &mut Frame, app: &App, area: ratatui::layout::Rect) {
2273 - const SPINNER: &[&str] = &["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"];
2274 - const CHECKS: u16 = CHECK_ROWS as u16;
2266 let now = std::time::Instant::now();
2267 let reduced = app.splash.reduced();
2268 let tc = app.splash.truecolor;
@@ -2284,14 +2275,14 @@ mod tui {
2275 let exit = app.splash.exit_progress(now);
2276 let vis = 1.0 - exit;
2277
2287 - // caption, a gap, the checklist
2278 + // the wordmark, a gap, the caption
2279 let art = app
2280 .splash
2281 .banner
2282 .size(area.width)
2292 - .filter(|(_, h)| area.height >= h + 2 + 1 + CHECKS);
2283 + .filter(|(_, h)| area.height >= h + 2);
2284 let art_h = art.map_or(0, |(_, h)| h + 1);
2294 - let total = art_h + 1 + 1 + CHECKS;
2285 + let total = art_h + 1;
2286 let top = area.y + area.height.saturating_sub(total) / 2;
2287 let rect = |y: u16, h: u16| ratatui::layout::Rect::new(area.x, y, area.width, h);
2288
@@ -2315,56 +2306,6 @@ mod tui {
2306 )))
2307 .alignment(ratatui::layout::Alignment::Center);
2308 frame.render_widget(caption, rect(caption_y, 1));
2318 -
2319 - // The checklist fades in once the flame has caught.
2320 - let shown = vis * ((ms - 700.0) / 300.0).clamp(0.0, 1.0);
2321 - if shown <= 0.0 {
2322 - return;
2323 - }
2324 - let spin = SPINNER[(ms as usize / 100) % SPINNER.len()];
2325 - let rows: Vec<(String, Line)> = app
2326 - .checks
2327 - .rows()
2328 - .into_iter()
2329 - .map(|(label, check)| {
2330 - let (glyph, detail, glyph_rgb, detail_rgb) = match check {
2331 - Check::Pending => (spin, "…".to_string(), splash::EMBER, splash::MUTED),
2332 - Check::Ok(d) => ("✓", d.clone(), splash::INK, splash::INK),
2333 - Check::Note(d) => ("·", d.clone(), splash::MUTED, splash::MUTED),
2334 - Check::Warn(d) => ("!", d.clone(), splash::EMBER, splash::EMBER),
2335 - };
2336 - let line = Line::from(vec![
2337 - Span::styled(
2338 - format!("{glyph} "),
2339 - Style::default().fg(splash::fade(glyph_rgb, shown, tc)),
2340 - ),
2341 - Span::styled(
2342 - format!("{label:<9} "),
2343 - Style::default().fg(splash::fade(splash::MUTED, shown, tc)),
2344 - ),
2345 - Span::styled(
2346 - detail.clone(),
2347 - Style::default().fg(splash::fade(detail_rgb, shown, tc)),
2348 - ),
2349 - ]);
2350 - (format!("{glyph} {label:<9} {detail}"), line)
2351 - })
2352 - .collect();
2353 - // One left edge for every line, centred as a block.
2354 - let width = rows
2355 - .iter()
2356 - .map(|(plain, _)| plain.chars().count())
2357 - .max()
2358 - .unwrap_or(0) as u16;
2359 - let x = area.x + area.width.saturating_sub(width) / 2;
2360 - for (i, (_, line)) in rows.into_iter().enumerate() {
2361 - let y = caption_y + 2 + i as u16;
2362 - if y >= area.y + area.height {
2363 - break;
2364 - }
2365 - let r = ratatui::layout::Rect::new(x, y, area.width.saturating_sub(x - area.x), 1);
2366 - frame.render_widget(Paragraph::new(line), r);
2367 - }
2309 }
2310
2311 fn render_loading_title(frame: &mut Frame, app: &App, area: ratatui::layout::Rect) {
@@ -2563,22 +2504,6 @@ mod tui {
2504 lines.push(Line::from(Span::styled(format!(" {entry_line}"), dim)));
2505 }
2506 }
2566 - Role::Banner => {
2567 - let palette = [
2568 - Color::Red,
2569 - Color::Yellow,
2570 - Color::Green,
2571 - Color::Cyan,
2572 - Color::Blue,
2573 - Color::Magenta,
2574 - ];
2575 - let mut spans = Vec::new();
2576 - for (i, ch) in msg.text.chars().enumerate() {
2577 - let color = palette[i % palette.len()];
2578 - spans.push(Span::styled(ch.to_string(), Style::default().fg(color)));
2579 - }
2580 - lines.push(Line::from(spans));
2581 - }
2507 Role::System => {
2508 for text_line in msg.text.split('\n') {
2509 let trimmed = text_line.trim();
crates/cli/src/splash.rs
-1
@@ -54,7 +54,6 @@ const RAMP: [Rgb; 4] = [
54 ];
55 pub(crate) const INK: Rgb = [0xf3, 0xf4, 0xf6];
56 pub(crate) const MUTED: Rgb = [0x6b, 0x72, 0x80];
57 -pub(crate) const EMBER: Rgb = RAMP[2];
57
58 /// Heat per digit. 0 and 9 are the densest in the art, 7 and 1 the thinnest.
59 const HEAT: [f32; 10] = [1.0, 0.2, 0.45, 0.55, 0.5, 0.4, 0.65, 0.15, 0.8, 1.0];