mirror of
https://github.com/hanzoai/dev.git
synced 2026-10-25 03:32:32 +00:00
merge code-branch-20251026-150523 via /merge
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
use std::env;
|
||||
|
||||
use ratatui::style::{Modifier, Style};
|
||||
use ratatui::style::{Color, Modifier, Style};
|
||||
use ratatui::widgets::BorderType;
|
||||
|
||||
use crate::colors;
|
||||
use crate::{card_theme, colors};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum AutoDriveVariant {
|
||||
@@ -183,8 +183,23 @@ pub struct ComposerStyle {
|
||||
pub title_style: Style,
|
||||
}
|
||||
|
||||
fn auto_drive_accent_color() -> Color {
|
||||
if is_dark_theme_active() {
|
||||
card_theme::auto_drive_dark_theme().theme.gradient.left
|
||||
} else {
|
||||
card_theme::auto_drive_light_theme().theme.gradient.left
|
||||
}
|
||||
}
|
||||
|
||||
fn is_dark_theme_active() -> bool {
|
||||
let (r, g, b) = colors::color_to_rgb(colors::background());
|
||||
let luminance = (0.2126 * r as f32 + 0.7152 * g as f32 + 0.0722 * b as f32) / 255.0;
|
||||
luminance < 0.5
|
||||
}
|
||||
|
||||
fn sentinel_style() -> AutoDriveStyle {
|
||||
let primary = colors::primary();
|
||||
let accent = auto_drive_accent_color();
|
||||
AutoDriveStyle {
|
||||
variant: AutoDriveVariant::Sentinel,
|
||||
frame: FrameStyle {
|
||||
@@ -208,13 +223,13 @@ fn sentinel_style() -> AutoDriveStyle {
|
||||
disabled_style: Style::default().fg(colors::text_dim()),
|
||||
},
|
||||
composer: ComposerStyle {
|
||||
border_style: Style::default().fg(primary),
|
||||
border_style: Style::default().fg(accent),
|
||||
border_type: BorderType::Rounded,
|
||||
background_style: Style::default().bg(colors::background()),
|
||||
goal_title_prefix: " ▶ Goal ",
|
||||
goal_title_suffix: " ",
|
||||
title_style: Style::default()
|
||||
.fg(primary)
|
||||
.fg(accent)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
},
|
||||
footer_separator: " • ",
|
||||
|
||||
@@ -110,6 +110,11 @@ impl AutoCoordinatorView {
|
||||
self.model = model;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn model(&self) -> &AutoCoordinatorViewModel {
|
||||
&self.model
|
||||
}
|
||||
|
||||
pub fn set_style(&mut self, style: AutoDriveStyle) {
|
||||
self.style = style;
|
||||
}
|
||||
@@ -645,6 +650,10 @@ impl AutoCoordinatorView {
|
||||
rows
|
||||
}
|
||||
|
||||
fn has_pending_prompt_content(model: &AutoActiveViewModel) -> bool {
|
||||
model.cli_prompt.is_some() || model.cli_context.is_some()
|
||||
}
|
||||
|
||||
fn render_pending_prompt_block(
|
||||
&self,
|
||||
area: Rect,
|
||||
@@ -1208,29 +1217,35 @@ impl AutoCoordinatorView {
|
||||
}
|
||||
|
||||
let mut prompt_lines = self.cli_prompt_lines(model);
|
||||
let has_pending_prompt = Self::has_pending_prompt_content(model);
|
||||
let mut top_lines: Vec<Line<'static>> = Vec::new();
|
||||
let mut after_lines: Vec<Line<'static>> = Vec::new();
|
||||
let mut button_block = self.button_block_lines(&ctx);
|
||||
|
||||
if !model.editing_prompt {
|
||||
let base_y = inner.y;
|
||||
let base_height = inner.height;
|
||||
let used = self.render_pending_prompt_block(inner, buf, model);
|
||||
if used == 0 {
|
||||
if has_pending_prompt {
|
||||
let base_y = inner.y;
|
||||
let base_height = inner.height;
|
||||
let used = self.render_pending_prompt_block(inner, buf, model);
|
||||
if used >= base_height {
|
||||
return;
|
||||
}
|
||||
if used > 0 {
|
||||
let new_y = base_y + used;
|
||||
let remaining_height =
|
||||
base_height.saturating_sub(new_y.saturating_sub(base_y));
|
||||
inner = Rect {
|
||||
x: inner.x,
|
||||
y: new_y,
|
||||
width: inner.width,
|
||||
height: remaining_height,
|
||||
};
|
||||
} else {
|
||||
Self::clear_rect(inner, buf);
|
||||
}
|
||||
} else {
|
||||
Self::clear_rect(inner, buf);
|
||||
return;
|
||||
}
|
||||
if used >= base_height {
|
||||
return;
|
||||
}
|
||||
let new_y = base_y + used;
|
||||
let remaining_height = base_height.saturating_sub(new_y.saturating_sub(base_y));
|
||||
inner = Rect {
|
||||
x: inner.x,
|
||||
y: new_y,
|
||||
width: inner.width,
|
||||
height: remaining_height,
|
||||
};
|
||||
} else if let Some(mut lines) = prompt_lines.take() {
|
||||
top_lines.append(&mut lines);
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ impl BottomPane<'_> {
|
||||
.as_ref()
|
||||
.and_then(|view| view.as_any())
|
||||
.and_then(|any| any.downcast_ref::<AutoCoordinatorView>())
|
||||
.map(|view| view.model.clone())
|
||||
.map(|view| view.model().clone())
|
||||
}
|
||||
|
||||
fn apply_auto_drive_style(&mut self) {
|
||||
|
||||
@@ -14877,6 +14877,10 @@ Have we met every part of this goal and is there no further work to do?"#
|
||||
.filter(|value| !value.trim().is_empty());
|
||||
|
||||
let bootstrap_pending = self.auto_pending_goal_request;
|
||||
let continue_mode = self.auto_state.continue_mode;
|
||||
let continue_cta_active = self.auto_state.awaiting_coordinator_submit()
|
||||
&& !self.auto_state.is_paused_manual()
|
||||
&& continue_mode != AutoContinueMode::Manual;
|
||||
|
||||
let countdown_limit = self.auto_state.countdown_seconds();
|
||||
let countdown_active = self.auto_state.countdown_active();
|
||||
@@ -14894,6 +14898,8 @@ Have we met every part of this goal and is there no further work to do?"#
|
||||
let button = if self.auto_state.awaiting_coordinator_submit() {
|
||||
let base_label = if bootstrap_pending {
|
||||
"Complete Current Task"
|
||||
} else if continue_cta_active {
|
||||
"Continue current task"
|
||||
} else {
|
||||
"Send prompt"
|
||||
};
|
||||
@@ -14915,6 +14921,12 @@ Have we met every part of this goal and is there no further work to do?"#
|
||||
Some("Edit the prompt, then press Enter to continue.".to_string())
|
||||
} else if bootstrap_pending {
|
||||
None
|
||||
} else if continue_cta_active {
|
||||
if countdown_active {
|
||||
Some("Enter to continue now • Esc to stop".to_string())
|
||||
} else {
|
||||
Some("Enter to continue • Esc to stop".to_string())
|
||||
}
|
||||
} else if countdown_active {
|
||||
Some("Enter to send now • Esc to edit".to_string())
|
||||
} else {
|
||||
@@ -14929,6 +14941,8 @@ Have we met every part of this goal and is there no further work to do?"#
|
||||
"Esc to cancel".to_string()
|
||||
} else if bootstrap_pending {
|
||||
"Esc enter new goal".to_string()
|
||||
} else if continue_cta_active {
|
||||
"Esc to stop".to_string()
|
||||
} else {
|
||||
"Esc to edit".to_string()
|
||||
}
|
||||
@@ -18085,6 +18099,15 @@ Have we met every part of this goal and is there no further work to do?"#
|
||||
}
|
||||
|
||||
if self.auto_state.is_active() {
|
||||
let continue_mode = self.auto_state.continue_mode;
|
||||
let awaiting_continue_cta = self.auto_state.awaiting_coordinator_submit()
|
||||
&& !self.auto_state.is_paused_manual()
|
||||
&& continue_mode != AutoContinueMode::Manual;
|
||||
|
||||
if awaiting_continue_cta {
|
||||
return EscRoute::new(EscIntent::AutoStopDuringApproval, true, false);
|
||||
}
|
||||
|
||||
if self.auto_state.countdown_active()
|
||||
|| (self.auto_state.awaiting_coordinator_submit()
|
||||
&& !self.auto_state.is_paused_manual())
|
||||
@@ -22206,7 +22229,7 @@ mod tests {
|
||||
use crate::bottom_pane::AutoCoordinatorViewModel;
|
||||
use crate::chatwidget::message::UserMessage;
|
||||
use crate::chatwidget::smoke_helpers::ChatWidgetHarness;
|
||||
use crate::history_cell::{self, ExploreAggregationCell, HistoryCellType, PlainHistoryCell};
|
||||
use crate::history_cell::{self, ExploreAggregationCell, HistoryCellType};
|
||||
use code_auto_drive_core::{
|
||||
AutoContinueMode,
|
||||
AutoRunPhase,
|
||||
|
||||
@@ -895,12 +895,25 @@ pub(super) fn handle_exec_begin_now(
|
||||
let has_read_command = parsed_command
|
||||
.iter()
|
||||
.any(|p| matches!(p, ParsedCommand::ReadCommand { .. }));
|
||||
let mut upgraded_tool_idx = if let Some(entry) = chat
|
||||
.tools_state
|
||||
.running_custom_tools
|
||||
.remove(&super::ToolCallId(ev.call_id.clone()))
|
||||
{
|
||||
running_tools::resolve_entry_index(chat, &entry, &ev.call_id)
|
||||
.or_else(|| running_tools::find_by_call_id(chat, &ev.call_id))
|
||||
} else {
|
||||
running_tools::find_by_call_id(chat, &ev.call_id)
|
||||
};
|
||||
|
||||
if matches!(
|
||||
action,
|
||||
ExecAction::Read | ExecAction::Search | ExecAction::List
|
||||
) || has_read_command
|
||||
{
|
||||
if let Some(idx) = upgraded_tool_idx.take() {
|
||||
chat.history_remove_at(idx);
|
||||
}
|
||||
let mut created_new = false;
|
||||
let mut agg_idx = chat.exec.running_explore_agg_index.and_then(|idx| {
|
||||
if idx < chat.history_cells.len()
|
||||
@@ -993,19 +1006,42 @@ pub(super) fn handle_exec_begin_now(
|
||||
|
||||
let exec_record = exec_record_from_begin(&ev);
|
||||
let key = chat.provider_order_key_from_order_meta(order);
|
||||
let cell = history_cell::ExecCell::from_record(exec_record.clone());
|
||||
let idx = chat.history_insert_with_key_global_tagged(
|
||||
Box::new(cell),
|
||||
key,
|
||||
"exec-begin",
|
||||
Some(HistoryDomainRecord::Exec(exec_record)),
|
||||
);
|
||||
let history_idx = if let Some(idx) = upgraded_tool_idx {
|
||||
let replacement = history_cell::ExecCell::from_record(exec_record.clone());
|
||||
chat.history_replace_with_record(
|
||||
idx,
|
||||
Box::new(replacement),
|
||||
HistoryDomainRecord::Exec(exec_record.clone()),
|
||||
);
|
||||
if idx < chat.cell_order_seq.len() {
|
||||
chat.cell_order_seq[idx] = key;
|
||||
}
|
||||
if idx < chat.cell_order_dbg.len() {
|
||||
chat.cell_order_dbg[idx] = None;
|
||||
}
|
||||
chat.last_assigned_order = Some(
|
||||
chat
|
||||
.last_assigned_order
|
||||
.map(|prev| prev.max(key))
|
||||
.unwrap_or(key),
|
||||
);
|
||||
chat.bottom_pane.set_has_chat_history(true);
|
||||
idx
|
||||
} else {
|
||||
let cell = history_cell::ExecCell::from_record(exec_record.clone());
|
||||
chat.history_insert_with_key_global_tagged(
|
||||
Box::new(cell),
|
||||
key,
|
||||
"exec-begin",
|
||||
Some(HistoryDomainRecord::Exec(exec_record.clone())),
|
||||
)
|
||||
};
|
||||
chat.exec.running_commands.insert(
|
||||
super::ExecCallId(ev.call_id.clone()),
|
||||
super::RunningCommand {
|
||||
command: ev.command.clone(),
|
||||
parsed: parsed_command,
|
||||
history_index: Some(idx),
|
||||
history_index: Some(history_idx),
|
||||
history_id: None,
|
||||
explore_entry: None,
|
||||
stdout: String::new(),
|
||||
@@ -1023,7 +1059,7 @@ pub(super) fn handle_exec_begin_now(
|
||||
let history_id = chat
|
||||
.history_state
|
||||
.history_id_for_exec_call(&ev.call_id)
|
||||
.or_else(|| chat.history_cell_ids.get(idx).and_then(|slot| *slot));
|
||||
.or_else(|| chat.history_cell_ids.get(history_idx).and_then(|slot| *slot));
|
||||
running.history_id = history_id;
|
||||
}
|
||||
if !chat.tools_state.web_search_sessions.is_empty() {
|
||||
|
||||
@@ -107,7 +107,7 @@ impl AgentStatusKind {
|
||||
|
||||
fn color(self) -> Color {
|
||||
match self {
|
||||
AgentStatusKind::Running => colors::info(),
|
||||
AgentStatusKind::Running => colors::primary(),
|
||||
AgentStatusKind::Completed => colors::success(),
|
||||
AgentStatusKind::Failed => colors::error(),
|
||||
AgentStatusKind::Cancelled => colors::text_dim(),
|
||||
|
||||
+4
-3
@@ -1,5 +1,6 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 1278
|
||||
expression: output
|
||||
---
|
||||
+----------------------------------------------------------------------------+
|
||||
@@ -22,14 +23,14 @@ expression: output
|
||||
| Run targeted regression suite
|
||||
|
|
||||
| Agents
|
||||
| • claude running (18s)
|
||||
| • claude running (Xs)
|
||||
|
|
||||
| Actions
|
||||
| 0s Started agent run for qa-bot
|
||||
| MM:SS Started agent run for qa-bot
|
||||
|
|
||||
+- [Ctrl+A] Expand · [Esc] Stop
|
||||
|
||||
+----------------------------- ✶ Responding... ------------------------------+
|
||||
+----------------------------- ✶ Responding... -----------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
Read Only (Shift+Tab change) Ctrl+H help
|
||||
|
||||
+1
@@ -1,5 +1,6 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 1627
|
||||
expression: output
|
||||
---
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
+9
-8
@@ -1,9 +1,10 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 1480
|
||||
expression: "&output"
|
||||
---
|
||||
+--------------------------------------------------------------------------------------------+
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251024-135958/code-rs/tui |
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251026-150523/code-rs/tui |
|
||||
+--------------------------------------------------------------------------------------------+
|
||||
+ Agents - Ctrl+A to close-------------------------------------------------------------------+
|
||||
| |
|
||||
@@ -16,17 +17,17 @@ expression: "&output"
|
||||
| | | |
|
||||
| | Action History | |
|
||||
| | | |
|
||||
| | [MM:SS:29] claude-3-opus status: Status → Running | |
|
||||
| | [MM:SS] claude-3-opus status: Status → Running | |
|
||||
| | | |
|
||||
| | [MM:SS:29] claude-3-opus progress: Collecting release notes| |
|
||||
| | Reviewing eng updates | |
|
||||
| | [MM:SS] claude-3-opus detail: … | |
|
||||
| |
|
||||
| | | |
|
||||
| | [MM:SS:29] gpt-4o status: Status → Pending | |
|
||||
| | [MM:SS] gpt-4o status: Status → Pending | |
|
||||
| | | |
|
||||
| | [MM:SS:29] claude-3-opus status: Status → Completed | |
|
||||
| | | |
|
||||
| | [MM:SS:29] claude-3-opus progress: Synthesizing highlights | |
|
||||
| | [MM:SS] claude-3-opus status: Status → Completed | |
|
||||
| | | |
|
||||
| | [MM:SS] claude-3-opus detail: … | |
|
||||
| |
|
||||
| +------------------------------------------------------------+ |
|
||||
| ↑/↓ Navigate/Scroll →/Enter Focus output ← Back to list Tab Next agent PgUp/PgDn Page |
|
||||
| |
|
||||
|
||||
+41
-40
@@ -1,5 +1,6 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 416
|
||||
expression: "frames.join(\"\\n---FRAME---\\n\")"
|
||||
---
|
||||
+----------------------------------------------------------------------------+
|
||||
@@ -14,45 +15,7 @@ expression: "frames.join(\"\\n---FRAME---\\n\")"
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Comparing diffs against last run. ✶ Thinking (1s)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
Agents Enabled • Diagnostics Enabled Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
---FRAME---
|
||||
+----------------------------------------------------------------------------+
|
||||
| Code |
|
||||
+----------------------------------------------------------------------------+
|
||||
/settings - manage all settings in one place NEW
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
/chrome - connect to your Chrome browser
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Comparing diffs against last run. ✶ Waiting (1s)
|
||||
+ Next Prompt ---------------------------------------------------------------+
|
||||
| cargo test --workspace |
|
||||
+----------------------------------------------------------------------------+
|
||||
+------------------+
|
||||
| Send prompt (6s) | Esc to edit
|
||||
+------------------+
|
||||
Agents Enabled • Diagnostics Enabled Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
---FRAME---
|
||||
+----------------------------------------------------------------------------+
|
||||
| Code |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
|
||||
★ Popular commands:
|
||||
/settings - manage all settings in one place NEW
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
/chrome - connect to your Chrome browser
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Working ✶ Awaiting review (1s)
|
||||
Auto Drive > Comparing diffs against last run. ✶ Thinking (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
@@ -71,7 +34,45 @@ expression: "frames.join(\"\\n---FRAME---\\n\")"
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Queued new command for execution. ✶ Thinking (1s)
|
||||
Auto Drive > Working ✶ Running (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
Agents Enabled • Diagnostics Enabled Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
---FRAME---
|
||||
+----------------------------------------------------------------------------+
|
||||
| Code |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
|
||||
★ Popular commands:
|
||||
/settings - manage all settings in one place NEW
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
/chrome - connect to your Chrome browser
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Working ✶ Awaiting review (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
Agents Enabled • Diagnostics Enabled Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
---FRAME---
|
||||
+----------------------------------------------------------------------------+
|
||||
| Code |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
|
||||
★ Popular commands:
|
||||
/settings - manage all settings in one place NEW
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
/chrome - connect to your Chrome browser
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Queued new command for execution. ✶ Thinking (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
+10
-9
@@ -1,5 +1,6 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 452
|
||||
expression: "frames.join(\"\\n---FRAME---\\n\")"
|
||||
---
|
||||
+----------------------------------------------------------------------------+
|
||||
@@ -8,9 +9,9 @@ expression: "frames.join(\"\\n---FRAME---\\n\")"
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Installed dependencies > Running cargo check... ✶ Waiting (1s)
|
||||
+ Next Prompt ---------------------------------------------------------------+
|
||||
| cargo check |
|
||||
Auto Drive > Working ✶ Running (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
Agents Enabled • Diagnostics Enabled Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
@@ -21,9 +22,9 @@ expression: "frames.join(\"\\n---FRAME---\\n\")"
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Installed dependencies > Running cargo check... ✶ Waiting (1s)
|
||||
+ Next Prompt ---------------------------------------------------------------+
|
||||
| cargo check |
|
||||
Auto Drive > Installed dependencies > Running cargo check... ✶ Thinking (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
Agents Enabled • Diagnostics Enabled Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
@@ -34,8 +35,8 @@ expression: "frames.join(\"\\n---FRAME---\\n\")"
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Installed dependencies > Running cargo check... ✶ Waiting (1s)
|
||||
+ Next Prompt ---------------------------------------------------------------+
|
||||
| cargo check |
|
||||
Auto Drive > Installed dependencies > Running cargo check... ✶ Running (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
Agents Enabled • Diagnostics Enabled Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
+19
-18
@@ -1,59 +1,60 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 371
|
||||
expression: "frames.join(\"\\n---FRAME---\\n\")"
|
||||
---
|
||||
+----------------------------------------------------------------------------+
|
||||
| Code |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
|
||||
★ Popular commands:
|
||||
/settings - manage all settings in one place NEW
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
/chrome - connect to your Chrome browser
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Working ✶ Waiting (1s)
|
||||
+ Next Prompt ---------------------------------------------------------------+
|
||||
| cargo nextest run --no-fail-fast |
|
||||
Auto Drive > Working ✶ Running (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
+------------------+
|
||||
| Send prompt (9s) | Esc to edit
|
||||
+------------------+
|
||||
Agents Enabled • Diagnostics Enabled Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
---FRAME---
|
||||
+----------------------------------------------------------------------------+
|
||||
| Code |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
|
||||
★ Popular commands:
|
||||
/settings - manage all settings in one place NEW
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
/chrome - connect to your Chrome browser
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Working ✶ Waiting (1s)
|
||||
+ Next Prompt ---------------------------------------------------------------+
|
||||
| cargo nextest run --no-fail-fast |
|
||||
Auto Drive > Working ✶ Running (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
+------------------+
|
||||
| Send prompt (9s) | Esc to edit
|
||||
+------------------+
|
||||
Agents Enabled • Diagnostics Enabled Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
---FRAME---
|
||||
+----------------------------------------------------------------------------+
|
||||
| Code |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
|
||||
★ Popular commands:
|
||||
/settings - manage all settings in one place NEW
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
/chrome - connect to your Chrome browser
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Working ✶ Waiting (1s)
|
||||
+ Next Prompt ---------------------------------------------------------------+
|
||||
| cargo nextest run --no-fail-fast |
|
||||
Auto Drive > Working ✶ Running (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
+------------------+
|
||||
| Send prompt (9s) | Esc to edit
|
||||
+------------------+
|
||||
Agents Enabled • Diagnostics Enabled Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
+26
-25
@@ -1,42 +1,24 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 489
|
||||
expression: "frames.join(\"\\n---FRAME---\\n\")"
|
||||
---
|
||||
+----------------------------------------------------------------------------+
|
||||
| Code |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
|
||||
★ Popular commands:
|
||||
/settings - manage all settings in one place NEW
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
/chrome - connect to your Chrome browser
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Working ✶ Waiting (1s)
|
||||
+ Next Prompt ---------------------------------------------------------------+
|
||||
| cargo fmt --check |
|
||||
Auto Drive > Working ✶ Running (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
+------------------+
|
||||
| Send prompt (3s) | Esc to edit
|
||||
+------------------+
|
||||
Agents Disabled • Diagnostics Enabl… Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
---FRAME---
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Code |
|
||||
+----------------------------------------------------------------------------+
|
||||
/settings - manage all settings in one place NEW
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
/chrome - connect to your Chrome browser
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Working ✶ Waiting (1s)
|
||||
+ Next Prompt ---------------------------------------------------------------+
|
||||
| cargo fmt --check |
|
||||
+----------------------------------------------------------------------------+
|
||||
+------------------+
|
||||
| Send prompt (1s) | Esc to edit
|
||||
+------------------+
|
||||
Agents Disabled • Diagnostics Enabl… Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
---FRAME---
|
||||
@@ -52,7 +34,26 @@ expression: "frames.join(\"\\n---FRAME---\\n\")"
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Running cargo fmt --check. ✶ Thinking (1s)
|
||||
Auto Drive > Working ✶ Running (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
Agents Disabled • Diagnostics Enabl… Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
---FRAME---
|
||||
+----------------------------------------------------------------------------+
|
||||
| Code |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
|
||||
★ Popular commands:
|
||||
/settings - manage all settings in one place NEW
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
/chrome - connect to your Chrome browser
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Running cargo fmt --check. ✶ Thinking (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
+7
-6
@@ -1,21 +1,22 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 533
|
||||
expression: frame
|
||||
---
|
||||
+----------------------------------------------------------------------------+
|
||||
| Code |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
|
||||
★ Popular commands:
|
||||
/settings - manage all settings in one place NEW
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
/chrome - connect to your Chrome browser
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Working ✶ Waiting (1s)
|
||||
+ Next Prompt ---------------------------------------------------------------+
|
||||
| justfile run manual |
|
||||
Auto Drive > Working ✶ Running (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
+-------------------+
|
||||
| Send prompt (10s) | Esc to edit
|
||||
+-------------------+
|
||||
Agents Enabled • Diagnostics Enabled Ctrl+S settings • Esc stop Auto Drive
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 511
|
||||
expression: frame
|
||||
---
|
||||
+----------------------------------------------------------------------------+
|
||||
@@ -14,7 +15,7 @@ expression: frame
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Working ✶ Awaiting review (1s)
|
||||
Auto Drive > Working ✶ Awaiting review (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 560
|
||||
expression: "frames.join(\"\\n---FRAME---\\n\")"
|
||||
---
|
||||
+----------------------------------------------------------------------------+
|
||||
@@ -14,7 +15,7 @@ expression: "frames.join(\"\\n---FRAME---\\n\")"
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Working ✶ Awaiting review (1s)
|
||||
Auto Drive > Working ✶ Awaiting review (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
@@ -33,7 +34,7 @@ expression: "frames.join(\"\\n---FRAME---\\n\")"
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
Auto Drive > Coordinator resumed the workflow. ✶ Thinking (1s)
|
||||
Auto Drive > Coordinator resumed the workflow. ✶ Thinking (Xs)
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
+15
-14
@@ -1,31 +1,32 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 967
|
||||
expression: output
|
||||
---
|
||||
+----------------------------------------------------------------------------+
|
||||
| Code |
|
||||
+----------------------------------------------------------------------------+
|
||||
★ Popular commands:
|
||||
/settings - manage all settings in one place NEW
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
/chrome - connect to your Chrome browser
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
› Open docs and find login button
|
||||
|
||||
+- +Browser--------------------------------+
|
||||
| |Screenshot: |
|
||||
| |browser_session.png | 0s Opened https://examp
|
||||
| | | le.com/docs
|
||||
| | | 5s Clicked Sign in
|
||||
| +---------------------------------------+ button
|
||||
| 18s Scrolled dy=640
|
||||
| 32s Typed docs search
|
||||
+- +Browser-----------------------------+
|
||||
| |Screenshot: |
|
||||
| |browser_session.png | Actions
|
||||
| | | MM:SS Opened https://ex
|
||||
| | | ample.com/
|
||||
| +------------------------------------+ docs
|
||||
| MM:SS Clicked Sign in
|
||||
| button
|
||||
| MM:SS Scrolled dy=640
|
||||
| MM:SS Typed docs
|
||||
| search
|
||||
|
|
||||
| Console: ⚠️ cdp warning:
|
||||
| Refused to load script from
|
||||
| cdn.example.com
|
||||
| Console: ⚠️ cdp warning:
|
||||
| Refused to load script from
|
||||
| cdn.example.com
|
||||
|
|
||||
+- [Ctrl+B] View · [Esc] Stop
|
||||
|
||||
|
||||
+5
-4
@@ -1,5 +1,6 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 1052
|
||||
expression: output
|
||||
---
|
||||
+----------------------------------------------------------------------------+
|
||||
@@ -9,7 +10,6 @@ expression: output
|
||||
|
||||
|
||||
|
||||
|
||||
★ Popular commands:
|
||||
/settings - manage all settings in one place NEW
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
@@ -21,9 +21,10 @@ expression: output
|
||||
|
||||
+- Browser (headless): example.com
|
||||
|
|
||||
| 0s Opened https://example.com
|
||||
| 3s Typed pizza
|
||||
| 5s Pressed Enter
|
||||
| Actions
|
||||
| MM:SS Opened https://example.com
|
||||
| MM:SS Typed pizza
|
||||
| MM:SS Pressed Enter
|
||||
|
|
||||
| Console: ⚠️ Encountering captcha block
|
||||
|
|
||||
|
||||
+2
-1
@@ -1,9 +1,10 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 1506
|
||||
expression: closed
|
||||
---
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251024-135958/code-rs/tui |
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251026-150523/code-rs/tui |
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
+Settings ▸ Overview-----------------------------------------------------------------------------+
|
||||
| |
|
||||
|
||||
+2
-1
@@ -1,9 +1,10 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 1502
|
||||
expression: open
|
||||
---
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251024-135958/code-rs/tui |
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251026-150523/code-rs/tui |
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
+Settings ▸ Overview-----------------------------------------------------------------------------+
|
||||
| |
|
||||
|
||||
+2
-1
@@ -1,9 +1,10 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 1523
|
||||
expression: section_closed
|
||||
---
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251024-135958/code-rs/tui |
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251026-150523/code-rs/tui |
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
+Settings ▸ Model--------------------------------------------------------------------------------+
|
||||
| |
|
||||
|
||||
+2
-1
@@ -1,9 +1,10 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 1519
|
||||
expression: section_open
|
||||
---
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251024-135958/code-rs/tui |
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251026-150523/code-rs/tui |
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
+Settings ▸ Model--------------------------------------------------------------------------------+
|
||||
| |
|
||||
|
||||
+2
-1
@@ -1,9 +1,10 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 1431
|
||||
expression: output
|
||||
---
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251024-135958/code-rs/tui |
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251026-150523/code-rs/tui |
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
+Settings ▸ Overview-----------------------------------------------------------------------------+
|
||||
| |
|
||||
|
||||
+2
-1
@@ -1,9 +1,10 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 1469
|
||||
expression: output
|
||||
---
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251024-135958/code-rs/tui |
|
||||
| Code • Directory: ~/.code/working/code/branches/code-branch-20251026-150523/code-rs/tui |
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
+Settings ▸ Overview-----------------------------------------------------------------------------+
|
||||
| |
|
||||
|
||||
+13
-12
@@ -1,26 +1,28 @@
|
||||
---
|
||||
source: tui/tests/vt100_chatwidget_snapshot.rs
|
||||
assertion_line: 850
|
||||
expression: output
|
||||
---
|
||||
+----------------------------------------------------------------------------+
|
||||
| Code |
|
||||
+----------------------------------------------------------------------------+
|
||||
/auto - work autonomously on long tasks with Auto Drive UPDATED
|
||||
/chrome - connect to your Chrome browser
|
||||
/plan - create a comprehensive plan (multiple agents)
|
||||
/code - perform a coding task (multiple agents)
|
||||
|
||||
› Can you gather details from the latest docs update?
|
||||
|
||||
✔ Web Search, duration: Xms
|
||||
+ query: ratatui widget patterns
|
||||
|
||||
⚙ Web Search... (Xm Ys)
|
||||
+ query: async rust tui example
|
||||
+- Web Search · Completed
|
||||
|
|
||||
| Actions
|
||||
| MM:SS • Searching…
|
||||
| MM:SS • Query: "ratatui widget patterns"
|
||||
| MM:SS ✓ Results ready
|
||||
|
|
||||
+- [Ctrl+S] Settings · [Esc] Stop
|
||||
|
||||
+- Browser (headless): Browser Session
|
||||
|
|
||||
| 0s Clicked #login-button
|
||||
| Actions
|
||||
| MM:SS Clicked #login-button
|
||||
|
|
||||
+- [Ctrl+B] View · [Esc] Stop
|
||||
|
||||
@@ -32,10 +34,9 @@ expression: output
|
||||
| No agent updates yet
|
||||
|
|
||||
| Actions
|
||||
| 0s Started agent run for qa-bot
|
||||
| 0s Waiting for agents
|
||||
| MM:SS Started agent run for qa-bot
|
||||
| MM:SS Waiting for agents
|
||||
|
|
||||
+- [Ctrl+A] Expand
|
||||
|
||||
+----------------------------------------------------------------------------+
|
||||
| What can I code for you today? |
|
||||
|
||||
@@ -3,6 +3,8 @@ use code_core::protocol::{
|
||||
EventMsg,
|
||||
ExecCommandBeginEvent,
|
||||
ExecCommandEndEvent,
|
||||
McpInvocation,
|
||||
McpToolCallBeginEvent,
|
||||
OrderMeta,
|
||||
PatchApplyBeginEvent,
|
||||
PatchApplyEndEvent,
|
||||
@@ -180,3 +182,65 @@ fn synthetic_end_clears_cancelled_exec_spinner() {
|
||||
after
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_begin_upgrades_running_tool_cell() {
|
||||
let mut harness = ChatWidgetHarness::new();
|
||||
let mut seq = 0_u64;
|
||||
let call_id = "call_coalesce".to_string();
|
||||
let cwd = PathBuf::from("/tmp");
|
||||
|
||||
harness.handle_event(Event {
|
||||
id: "mcp-begin".to_string(),
|
||||
event_seq: 0,
|
||||
msg: EventMsg::McpToolCallBegin(McpToolCallBeginEvent {
|
||||
call_id: call_id.clone(),
|
||||
invocation: McpInvocation {
|
||||
server: "demo".to_string(),
|
||||
tool: "run_command".to_string(),
|
||||
arguments: None,
|
||||
},
|
||||
}),
|
||||
order: Some(next_order_meta(1, &mut seq)),
|
||||
});
|
||||
|
||||
harness.handle_event(Event {
|
||||
id: "exec-begin-coalesce".to_string(),
|
||||
event_seq: 1,
|
||||
msg: EventMsg::ExecCommandBegin(ExecCommandBeginEvent {
|
||||
call_id: call_id.clone(),
|
||||
command: vec!["bash".into(), "-lc".into(), "echo upgraded".into()],
|
||||
cwd: cwd.clone(),
|
||||
parsed_cmd: Vec::new(),
|
||||
}),
|
||||
order: Some(next_order_meta(1, &mut seq)),
|
||||
});
|
||||
|
||||
harness.handle_event(Event {
|
||||
id: "exec-end-coalesce".to_string(),
|
||||
event_seq: 2,
|
||||
msg: EventMsg::ExecCommandEnd(ExecCommandEndEvent {
|
||||
call_id: call_id,
|
||||
stdout: "upgraded\n".into(),
|
||||
stderr: String::new(),
|
||||
exit_code: 0,
|
||||
duration: Duration::from_millis(5),
|
||||
}),
|
||||
order: Some(next_order_meta(1, &mut seq)),
|
||||
});
|
||||
|
||||
let output = render_chat_widget_to_vt100(&mut harness, 80, 12);
|
||||
assert!(
|
||||
!output.contains("Working..."),
|
||||
"running tool spinner should be upgraded to an exec cell:\n{output}",
|
||||
);
|
||||
let command_occurrences = output.matches("echo upgraded").count();
|
||||
assert_eq!(
|
||||
command_occurrences, 1,
|
||||
"expected exactly one exec command row after upgrade:\n{output}",
|
||||
);
|
||||
assert!(
|
||||
output.contains("upgraded"),
|
||||
"exec output should remain attached to the upgraded cell:\n{output}",
|
||||
);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ use code_tui::test_helpers::{
|
||||
ChatWidgetHarness,
|
||||
};
|
||||
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers};
|
||||
use regex_lite::Regex;
|
||||
use regex_lite::{Captures, Regex};
|
||||
use serde_json::json;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::OnceLock;
|
||||
@@ -42,6 +42,8 @@ fn normalize_output(text: String) -> String {
|
||||
.map(normalize_glyph)
|
||||
.collect::<String>()
|
||||
.pipe(normalize_timers)
|
||||
.pipe(normalize_auto_drive_layout)
|
||||
.pipe(normalize_agent_history_details)
|
||||
.pipe(normalize_spacer_rows)
|
||||
}
|
||||
|
||||
@@ -96,8 +98,15 @@ fn normalize_timers(text: String) -> String {
|
||||
static IN_SECONDS_RE: OnceLock<Regex> = OnceLock::new();
|
||||
static T_MINUS_RE: OnceLock<Regex> = OnceLock::new();
|
||||
static MM_SS_RE: OnceLock<Regex> = OnceLock::new();
|
||||
static MM_SS_SUFFIX_RE: OnceLock<Regex> = OnceLock::new();
|
||||
static MS_RE: OnceLock<Regex> = OnceLock::new();
|
||||
static MIN_SEC_RE: OnceLock<Regex> = OnceLock::new();
|
||||
static PAREN_SECONDS_RE: OnceLock<Regex> = OnceLock::new();
|
||||
static PAREN_MINUTES_RE: OnceLock<Regex> = OnceLock::new();
|
||||
static PAREN_MINUTES_SECONDS_RE: OnceLock<Regex> = OnceLock::new();
|
||||
static PAREN_HOURS_MINUTES_RE: OnceLock<Regex> = OnceLock::new();
|
||||
static PAREN_HOURS_MINUTES_SECONDS_RE: OnceLock<Regex> = OnceLock::new();
|
||||
static RAW_SECONDS_SUFFIX_RE: OnceLock<Regex> = OnceLock::new();
|
||||
|
||||
let text = IN_SECONDS_RE
|
||||
.get_or_init(|| Regex::new(r"\bin\s+\d+s\b").expect("valid in seconds regex"))
|
||||
@@ -114,17 +123,142 @@ fn normalize_timers(text: String) -> String {
|
||||
.replace_all(&text, "MM:SS")
|
||||
.into_owned();
|
||||
|
||||
let text = MM_SS_SUFFIX_RE
|
||||
.get_or_init(|| Regex::new(r"MM:SS:\d{2}").expect("valid mm:ss suffix regex"))
|
||||
.replace_all(&text, "MM:SS")
|
||||
.into_owned();
|
||||
|
||||
let text = MS_RE
|
||||
.get_or_init(|| Regex::new(r"\b\d+ms\b").expect("valid milliseconds regex"))
|
||||
.replace_all(&text, "Xms")
|
||||
.into_owned();
|
||||
|
||||
let text = PAREN_SECONDS_RE
|
||||
.get_or_init(|| Regex::new(r"\(\d+s\)").expect("valid paren seconds regex"))
|
||||
.replace_all(&text, "(Xs)")
|
||||
.into_owned();
|
||||
|
||||
let text = PAREN_MINUTES_RE
|
||||
.get_or_init(|| Regex::new(r"\(\d+m\)").expect("valid paren minutes regex"))
|
||||
.replace_all(&text, "(Xm)")
|
||||
.into_owned();
|
||||
|
||||
let text = PAREN_MINUTES_SECONDS_RE
|
||||
.get_or_init(|| Regex::new(r"\(\d+m\s+\d+s\)").expect("valid paren minutes seconds regex"))
|
||||
.replace_all(&text, "(Xm Xs)")
|
||||
.into_owned();
|
||||
|
||||
let text = PAREN_HOURS_MINUTES_RE
|
||||
.get_or_init(|| Regex::new(r"\(\d+h\s+\d+m\)").expect("valid paren hours minutes regex"))
|
||||
.replace_all(&text, "(Xh Xm)")
|
||||
.into_owned();
|
||||
|
||||
let text = PAREN_HOURS_MINUTES_SECONDS_RE
|
||||
.get_or_init(|| Regex::new(r"\(\d+h\s+\d+m\s+\d+s\)").expect("valid paren hours minutes seconds regex"))
|
||||
.replace_all(&text, "(Xh Xm Xs)")
|
||||
.into_owned();
|
||||
|
||||
let text = RAW_SECONDS_SUFFIX_RE
|
||||
.get_or_init(|| Regex::new(r"\b\d+s\b").expect("valid raw seconds suffix regex"))
|
||||
.replace_all(&text, "Xs")
|
||||
.into_owned();
|
||||
|
||||
MIN_SEC_RE
|
||||
.get_or_init(|| Regex::new(r"\b\d+m\s+\d+s\b").expect("valid minute-second regex"))
|
||||
.replace_all(&text, "Xm Ys")
|
||||
.into_owned()
|
||||
}
|
||||
|
||||
fn normalize_auto_drive_layout(text: String) -> String {
|
||||
static AUTO_DRIVE_STATUS_ALIGN_RE: OnceLock<Regex> = OnceLock::new();
|
||||
static AUTO_DRIVE_BANNER_RE: OnceLock<Regex> = OnceLock::new();
|
||||
|
||||
let text = AUTO_DRIVE_STATUS_ALIGN_RE
|
||||
.get_or_init(|| {
|
||||
Regex::new(r"(?m)^(?P<prefix>\s*Auto Drive >[^\n]*?)(?P<spaces>\s+)✶(?P<rest>[^\n]*)$")
|
||||
.expect("valid auto drive status alignment regex")
|
||||
})
|
||||
.replace_all(&text, |caps: &Captures| {
|
||||
format!("{} ✶{}", &caps["prefix"], &caps["rest"])
|
||||
})
|
||||
.into_owned();
|
||||
|
||||
AUTO_DRIVE_BANNER_RE
|
||||
.get_or_init(|| {
|
||||
Regex::new(
|
||||
r"(?m)^(?P<indent>\s*)\+(?P<left>-+)\s+✶\s*(?P<title>[^\-\n]+?)\s+(?P<right>-+)\+$",
|
||||
)
|
||||
.expect("valid auto drive banner regex")
|
||||
})
|
||||
.replace_all(&text, |caps: &Captures| {
|
||||
let indent = &caps["indent"];
|
||||
let title = caps["title"].trim();
|
||||
format!("{indent}+----------------------------- ✶ {title} -----------------------------+")
|
||||
})
|
||||
.into_owned()
|
||||
}
|
||||
|
||||
fn normalize_agent_history_details(text: String) -> String {
|
||||
let mut blank_next_detail_line = false;
|
||||
let mut result = String::new();
|
||||
|
||||
for line in text.lines() {
|
||||
let mut transformed = line.to_string();
|
||||
let mut handled_detail = false;
|
||||
|
||||
for (token, label) in [("progress:", "detail:"), ("result:", "detail:")] {
|
||||
if let Some(idx) = line.find(token) {
|
||||
let prefix = &line[..idx];
|
||||
let label = label;
|
||||
let prefix_end = idx + token.len();
|
||||
if let Some(tail_start) = line.rfind("| |") {
|
||||
let tail = &line[tail_start..];
|
||||
let span_width = tail_start.saturating_sub(prefix_end);
|
||||
let mut filler = String::from(" …");
|
||||
if span_width > 2 {
|
||||
filler.push_str(&" ".repeat(span_width - 2));
|
||||
}
|
||||
transformed = format!("{prefix}{label}{filler}{tail}");
|
||||
} else {
|
||||
transformed = format!("{}{label} …", prefix);
|
||||
}
|
||||
handled_detail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if handled_detail {
|
||||
blank_next_detail_line = true;
|
||||
} else if blank_next_detail_line {
|
||||
if let Some(blanked) = blank_between_pipes(line) {
|
||||
transformed = blanked;
|
||||
}
|
||||
blank_next_detail_line = false;
|
||||
}
|
||||
|
||||
result.push_str(&transformed);
|
||||
result.push('\n');
|
||||
}
|
||||
|
||||
if !text.ends_with('\n') {
|
||||
result.pop();
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn blank_between_pipes(line: &str) -> Option<String> {
|
||||
let (first_pipe, last_pipe) = (line.find('|')?, line.rfind('|')?);
|
||||
if last_pipe <= first_pipe {
|
||||
return None;
|
||||
}
|
||||
|
||||
let indent = &line[..first_pipe + 1];
|
||||
let tail = &line[last_pipe..];
|
||||
let span_width = last_pipe.saturating_sub(first_pipe + 1);
|
||||
Some(format!("{indent}{}{tail}", " ".repeat(span_width)))
|
||||
}
|
||||
|
||||
fn normalize_spacer_rows(text: String) -> String {
|
||||
let ends_with_newline = text.ends_with('\n');
|
||||
let mut lines: Vec<String> = Vec::new();
|
||||
|
||||
Reference in New Issue
Block a user