use ratatui::style::{Modifier, Style};
use ratatui::text::{Line, Span};
use crate::localization::MessageId;
use crate::palette;
use crate::tui::app::App;
pub fn lines(app: &App) -> Vec<Line<'static>> {
let mut lines = Vec::new();
lines.push(Line::from(Span::styled(
app.tr(MessageId::OnboardTrustTitle).to_string(),
Style::default()
.fg(palette::WHALE_INFO)
.add_modifier(Modifier::BOLD),
)));
lines.push(Line::from(""));
lines.push(Line::from(Span::styled(
app.tr(MessageId::OnboardTrustQuestion).to_string(),
Style::default().fg(palette::TEXT_PRIMARY),
)));
lines.push(Line::from(Span::styled(
format!(
"{}{}",
app.tr(MessageId::OnboardTrustLocationPrefix),
crate::utils::display_path(&app.workspace)
),
Style::default().fg(palette::TEXT_MUTED),
)));
lines.push(Line::from(""));
lines.push(Line::from(Span::styled(
app.tr(MessageId::OnboardTrustRiskHint).to_string(),
Style::default().fg(palette::TEXT_MUTED),
)));
lines.push(Line::from(Span::styled(
app.tr(MessageId::OnboardTrustEffectHint).to_string(),
Style::default().fg(palette::TEXT_MUTED),
)));
if let Some(message) = app.status_message.as_deref() {
lines.push(Line::from(""));
lines.push(Line::from(Span::styled(
message.to_string(),
Style::default().fg(palette::STATUS_WARNING),
)));
}
lines.push(Line::from(""));
lines.push(Line::from(vec![
Span::styled(
app.tr(MessageId::OnboardTrustFooterPrefix).to_string(),
Style::default().fg(palette::TEXT_MUTED),
),
Span::styled(
"1/Y",
Style::default()
.fg(palette::TEXT_PRIMARY)
.add_modifier(Modifier::BOLD),
),
Span::styled(
app.tr(MessageId::OnboardTrustFooterMiddle).to_string(),
Style::default().fg(palette::TEXT_MUTED),
),
Span::styled(
"2/N/Esc",
Style::default()
.fg(palette::TEXT_PRIMARY)
.add_modifier(Modifier::BOLD),
),
Span::styled(
app.tr(MessageId::OnboardTrustFooterSuffix).to_string(),
Style::default().fg(palette::TEXT_MUTED),
),
]));
lines
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::Config;
use crate::tui::app::TuiOptions;
use std::path::PathBuf;
#[test]
fn prompt_names_the_workspace_boundary_and_effects() {
let options = TuiOptions {
model: "test-model".to_string(),
workspace: PathBuf::from("workspace-fixture"),
config_path: None,
config_profile: None,
allow_shell: false,
use_alt_screen: true,
use_mouse_capture: false,
use_bracketed_paste: true,
max_subagents: 1,
skills_dir: PathBuf::from("."),
memory_path: PathBuf::from("memory.md"),
notes_path: PathBuf::from("notes.txt"),
mcp_config_path: PathBuf::from("mcp.json"),
use_memory: false,
start_in_agent_mode: false,
skip_onboarding: true,
yolo: false,
resume_session_id: None,
initial_input: None,
};
let mut app = App::new(options, &Config::default());
app.ui_locale = crate::localization::Locale::En;
let body = lines(&app)
.into_iter()
.flat_map(|line| line.spans.into_iter().map(|span| span.content.to_string()))
.collect::<Vec<_>>()
.join("\n");
assert!(body.contains("Know this workspace"));
assert!(body.contains("instructions and files"));
assert!(body.contains("prompt injection"));
assert!(body.contains("tools and hooks"));
assert!(body.contains("1/Y"));
assert!(body.contains("2/N/Esc"));
}
}