aboutsummaryrefslogtreecommitdiff
path: root/src/app/api_helpers.rs
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-07-19 23:52:20 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-07-19 23:56:07 +0300
commit3f80947678a9723434aa7fddfe23750b5393e24c (patch)
tree6f463797132acfc51dfb6e135820a052954b4f13 /src/app/api_helpers.rs
parentf76f895efe5b9f19aa9db909354c6c0f2195630b (diff)
feat: make agent automation a first-class cli primitive
Diffstat (limited to 'src/app/api_helpers.rs')
-rw-r--r--src/app/api_helpers.rs52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/app/api_helpers.rs b/src/app/api_helpers.rs
index c7dc39d2..6c393dac 100644
--- a/src/app/api_helpers.rs
+++ b/src/app/api_helpers.rs
@@ -101,6 +101,58 @@ pub(super) fn pane_agent_status(
}
}
+pub(super) fn read_terminal_snapshot(
+ terminal: &crate::terminal::TerminalRuntime,
+ source: crate::api::schema::ReadSource,
+ format: crate::api::schema::ReadFormat,
+ lines: Option<u32>,
+) -> String {
+ use crate::api::schema::{ReadFormat, ReadSource};
+
+ let requested_lines = lines.unwrap_or(80).min(1000) as usize;
+ let text = match (format, source) {
+ (ReadFormat::Text, ReadSource::Visible) => terminal.visible_text(),
+ (ReadFormat::Text, ReadSource::Recent) => terminal.recent_text(requested_lines),
+ (ReadFormat::Text, ReadSource::RecentUnwrapped) => {
+ terminal.recent_unwrapped_text(requested_lines)
+ }
+ (ReadFormat::Text, ReadSource::Detection) => terminal.detection_text(),
+ (ReadFormat::Ansi, ReadSource::Visible) => terminal.visible_ansi(),
+ (ReadFormat::Ansi, ReadSource::Recent) => terminal.recent_ansi(requested_lines),
+ (ReadFormat::Ansi, ReadSource::RecentUnwrapped) => {
+ terminal.recent_unwrapped_ansi(requested_lines)
+ }
+ (ReadFormat::Ansi, ReadSource::Detection) => terminal.detection_text(),
+ };
+
+ if lines.is_some() && matches!(source, ReadSource::Visible | ReadSource::Detection) {
+ last_lines(&text, requested_lines)
+ } else {
+ text
+ }
+}
+
+fn last_lines(text: &str, count: usize) -> String {
+ if text.is_empty() || count == 0 {
+ return String::new();
+ }
+ let lines: Vec<_> = text.split_inclusive('\n').collect();
+ lines[lines.len().saturating_sub(count)..].concat()
+}
+
+#[cfg(test)]
+mod read_snapshot_tests {
+ use super::last_lines;
+
+ #[test]
+ fn last_lines_preserves_real_line_endings_and_unicode() {
+ assert_eq!(last_lines("one\ntwø\n三\n", 2), "twø\n三\n");
+ assert_eq!(last_lines("one\ntwo\nthree", 1), "three");
+ assert_eq!(last_lines("one\ntwo", 0), "");
+ assert_eq!(last_lines("", 2), "");
+ }
+}
+
pub(super) fn normalize_reported_agent_label(agent: &str) -> Option<String> {
let trimmed = agent.trim();
if trimmed.is_empty() {