feat(protocol): add Paste request type for bracketed-paste events

feat(engine): summarize agent completion progress in UI notifications

feat(main): enable and disable bracketed paste support in terminal

fix(app_config): store API key from file as fallback for Claude provider

refactor(workflow): remove unnecessary card separator in workflow panel
This commit is contained in:
asepharyana
2026-07-15 01:54:36 +07:00
parent e13f040833
commit b92dab97e6
5 changed files with 64 additions and 17 deletions
+29 -1
View File
@@ -118,6 +118,7 @@ fn run_single_process() -> Result<()> {
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen)?;
execute!(stdout, crossterm::event::EnableBracketedPaste)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
terminal.clear()?;
@@ -125,6 +126,7 @@ fn run_single_process() -> Result<()> {
let run_result = run_loop(&mut state, &mut terminal);
let mut restore_stdout = io::stdout();
let _ = execute!(restore_stdout, crossterm::event::DisableBracketedPaste);
let _ = execute!(restore_stdout, LeaveAlternateScreen);
let _ = disable_raw_mode();
@@ -408,6 +410,12 @@ fn run_daemon() -> Result<()> {
}
apply_action(&mut state, Action::Tick);
}
ClientRequest::Paste(text) => {
state.input.buffer.insert_str(state.input.cursor, &text);
state.input.cursor += text.len();
state.dirty = true;
apply_action(&mut state, Action::Tick);
}
ClientRequest::Resize(w, h) => {
apply_action(&mut state, Action::Resize(w, h));
apply_action(&mut state, Action::Tick);
@@ -468,6 +476,7 @@ fn run_attach(session_id: &str) -> Result<()> {
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen)?;
execute!(stdout, crossterm::event::EnableBracketedPaste)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
terminal.clear()?;
@@ -516,6 +525,9 @@ fn run_attach(session_id: &str) -> Result<()> {
}
}
}
Event::Paste(text) => {
client.send(&ClientRequest::Paste(text))?;
}
Event::Resize(w, h) => {
client.send(&ClientRequest::Resize(w, h))?;
}
@@ -555,6 +567,7 @@ fn run_attach(session_id: &str) -> Result<()> {
})?;
}
let _ = execute!(io::stdout(), crossterm::event::DisableBracketedPaste);
let _ = execute!(io::stdout(), LeaveAlternateScreen);
let _ = disable_raw_mode();
@@ -578,8 +591,9 @@ fn run_loop(
let result = run_loop_inner(state, terminal);
if let Err(ref _e) = result {
let _ = terminal.clear();
let _ = disable_raw_mode();
let _ = execute!(io::stdout(), crossterm::event::DisableBracketedPaste);
let _ = execute!(io::stdout(), LeaveAlternateScreen);
}
result
@@ -625,6 +639,20 @@ fn run_loop_inner(
}
}
}
Event::Paste(text) => {
// Insert pasted text as a single bulk operation instead of
// character-by-character, avoiding O(n^2) String::insert()
// and preventing stray newline/control-byte misinterpretation.
if state.input.autocomplete_visible {
state.input.close_autocomplete();
}
state.input.buffer.insert_str(state.input.cursor, &text);
state.input.cursor += text.len();
if state.input.buffer.starts_with('/') {
state.input.open_autocomplete();
}
state.dirty = true;
}
Event::Resize(w, h) => {
apply_action(state, Action::Resize(w, h));
}