aboutsummaryrefslogtreecommitdiffstats
path: root/crates/client/src/command
diff options
context:
space:
mode:
Diffstat (limited to 'crates/client/src/command')
-rw-r--r--crates/client/src/command/client.rs31
-rw-r--r--crates/client/src/command/client/daemon.rs2
-rw-r--r--crates/client/src/command/client/history/end.rs6
-rw-r--r--crates/client/src/command/client/history/mod.rs563
-rw-r--r--crates/client/src/command/client/history/start.rs21
-rw-r--r--crates/client/src/command/client/history/tail.rs10
-rw-r--r--crates/client/src/command/client/info.rs2
-rw-r--r--crates/client/src/command/client/stats.rs6
-rw-r--r--crates/client/src/command/client/sync.rs2
-rw-r--r--crates/client/src/command/client/wrapped.rs15
-rw-r--r--crates/client/src/command/mod.rs9
11 files changed, 41 insertions, 626 deletions
diff --git a/crates/client/src/command/client.rs b/crates/client/src/command/client.rs
index 32686c23..60329500 100644
--- a/crates/client/src/command/client.rs
+++ b/crates/client/src/command/client.rs
@@ -1,6 +1,3 @@
-use std::fs::{self};
-use std::path::Path;
-
use clap::Subcommand;
use eyre::{Result, WrapErr};
@@ -8,34 +5,6 @@ use tracing_subscriber::filter::EnvFilter;
use crate::atuin_client::settings::Settings;
-fn cleanup_old_logs(log_dir: &Path, prefix: &str, retention_days: u64) {
- let cutoff = std::time::SystemTime::now()
- - std::time::Duration::from_secs(retention_days * 24 * 60 * 60);
-
- let Ok(entries) = fs::read_dir(log_dir) else {
- return;
- };
-
- for entry in entries.flatten() {
- let path = entry.path();
- let Some(name) = path.file_name().and_then(|n| n.to_str()) else {
- continue;
- };
-
- // Match files like "search.log.2024-02-23" or "daemon.log.2024-02-23"
- if !name.starts_with(prefix) || name == prefix {
- continue;
- }
-
- if let Ok(metadata) = entry.metadata()
- && let Ok(modified) = metadata.modified()
- && modified < cutoff
- {
- drop(fs::remove_file(&path));
- }
- }
-}
-
mod config;
mod daemon;
mod default_config;
diff --git a/crates/client/src/command/client/daemon.rs b/crates/client/src/command/client/daemon.rs
index 83877cfd..08ce7a96 100644
--- a/crates/client/src/command/client/daemon.rs
+++ b/crates/client/src/command/client/daemon.rs
@@ -1,7 +1,7 @@
use clap::Subcommand;
use eyre::Result;
-use turtle_daemon::api::client::{Probe, probe};
+use turtle::client::{Probe, probe};
use crate::atuin_client::settings::Settings;
diff --git a/crates/client/src/command/client/history/end.rs b/crates/client/src/command/client/history/end.rs
index bfec0aab..0e1e6b91 100644
--- a/crates/client/src/command/client/history/end.rs
+++ b/crates/client/src/command/client/history/end.rs
@@ -1,7 +1,7 @@
use crate::atuin_client::settings::Settings;
use eyre::{Result, eyre};
-use turtle_daemon::api::client::{HistoryClient, daemon_matches_expected, daemon_mismatch_message};
+use turtle::client::{HistoryClient, daemon_matches_expected, daemon_mismatch_message};
pub(super) async fn handle(
settings: &Settings,
@@ -24,13 +24,13 @@ async fn end_history(settings: &Settings, id: String, duration: u64, exit: i64)
.await
{
Ok(resp) => {
- if daemon_matches_expected(&resp.version, resp.protocol) {
+ if daemon_matches_expected(resp.protocol) {
return Ok(());
}
Err(eyre!(
"{}. Restart the daemon manually",
- daemon_mismatch_message(&resp.version, resp.protocol)
+ daemon_mismatch_message(resp.protocol)
))
}
Err(err) => Err(err),
diff --git a/crates/client/src/command/client/history/mod.rs b/crates/client/src/command/client/history/mod.rs
index d71c653d..b6bfe6a1 100644
--- a/crates/client/src/command/client/history/mod.rs
+++ b/crates/client/src/command/client/history/mod.rs
@@ -1,18 +1,15 @@
use std::{
- fmt::{self, Display},
- io::{self, IsTerminal, Write},
+ fmt::{self},
ops::ControlFlow,
time::Duration,
};
use clap::Subcommand;
use eyre::Result;
-use runtime_format::{FormatKey, FormatKeyError, ParseSegment, ParsedFmt};
-use time::{OffsetDateTime, macros::format_description};
-use turtle_common::utils::Escapable;
-use turtle_daemon::aclient::history::History;
+use time::macros::format_description;
+use turtle::history::History;
-use crate::atuin_client::settings::{Settings, Timezone};
+use crate::atuin_client::settings::Settings;
mod end;
mod start;
@@ -52,250 +49,9 @@ pub(crate) enum Cmd {
/// Stream history events from the daemon as they are received
Tail,
-
- /// List all items in history
- List {
- #[arg(long, short)]
- cwd: bool,
-
- #[arg(long, short)]
- session: bool,
-
- #[arg(long)]
- human: bool,
-
- /// Show only the text of the command
- #[arg(long)]
- cmd_only: bool,
-
- /// Terminate the output with a null, for better multiline support
- #[arg(long)]
- print0: bool,
-
- #[arg(long, short, default_value = "true")]
- // accept no value
- #[arg(num_args(0..=1), default_missing_value("true"))]
- // accept a value
- #[arg(action = clap::ArgAction::Set)]
- reverse: bool,
-
- /// Display the command time in another timezone other than the configured default.
- ///
- /// This option takes one of the following kinds of values:
- /// - the special value "local" (or "l") which refers to the system time zone
- /// - an offset from UTC (e.g. "+9", "-2:30")
- #[arg(long, visible_alias = "tz")]
- timezone: Option<Timezone>,
-
- /// Available variables: {command}, {directory}, {duration}, {user}, {host}, {author}, {intent}, {exit}, {time}, {session}, and {uuid}
- /// Example: --format "{time} - [{duration}] - {directory}$\t{command}"
- #[arg(long, short)]
- format: Option<String>,
- },
-
- /// Get the last command ran
- Last {
- #[arg(long)]
- human: bool,
-
- /// Show only the text of the command
- #[arg(long)]
- cmd_only: bool,
-
- /// Display the command time in another timezone other than the configured default.
- ///
- /// This option takes one of the following kinds of values:
- /// - the special value "local" (or "l") which refers to the system time zone
- /// - an offset from UTC (e.g. "+9", "-2:30")
- #[arg(long, visible_alias = "tz")]
- timezone: Option<Timezone>,
-
- /// Available variables: {command}, {directory}, {duration}, {user}, {host}, {author}, {intent}, {time}, {session}, {uuid} and {relativetime}.
- /// Example: --format "{time} - [{duration}] - {directory}$\t{command}"
- #[arg(long, short)]
- format: Option<String>,
- },
-
- InitStore,
-
- /// Delete history entries matching the configured exclusion filters
- Prune {
- /// List matching history lines without performing the actual deletion.
- #[arg(short = 'n', long)]
- dry_run: bool,
- },
-
- /// Delete duplicate history entries (that have the same command, cwd and hostname)
- Dedup {
- /// List matching history lines without performing the actual deletion.
- #[arg(short = 'n', long)]
- dry_run: bool,
-
- /// Only delete results added before this date
- #[arg(long, short)]
- before: String,
-
- /// How many recent duplicates to keep
- #[arg(long)]
- dupkeep: u32,
- },
}
impl Cmd {
- // #[expect(clippy::too_many_arguments)]
- // #[expect(clippy::fn_params_excessive_bools)]
- // async fn handle_list(
- // settings: &Settings,
- // session: bool,
- // cwd: bool,
- // mode: ListMode,
- // format: Option<String>,
- // include_deleted: bool,
- // print0: bool,
- // reverse: bool,
- // tz: Timezone,
- // ) -> Result<()> {
- // let filters = match (session, cwd) {
- // (true, true) => [Session, Directory],
- // (true, false) => [Session, Global],
- // (false, true) => [Global, Directory],
- // (false, false) => [
- // settings.default_filter_mode(context.git_root.is_some()),
- // Global,
- // ],
- // };
- //
- // let history = db
- // .list(&filters, &context, None, false, include_deleted)
- // .await?;
- //
- // print_list(
- // &history,
- // mode,
- // match format {
- // None => Some(settings.history_format.as_str()),
- // _ => format.as_deref(),
- // },
- // print0,
- // reverse,
- // tz,
- // );
- //
- // Ok(())
- // }
-
- // async fn handle_prune(
- // db: &ClientSqlite,
- // settings: &Settings,
- // store: SqliteStore,
- // context: crate::atuin_client::database::Context,
- // dry_run: bool,
- // ) -> Result<()> {
- // // Grab all executed commands and filter them using History::should_save.
- // // We could iterate or paginate here if memory usage becomes an issue.
- // let matches: Vec<History> = db
- // .list(&[Global], &context, None, false, false)
- // .await?
- // .into_iter()
- // .filter(|h| !h.should_save(settings))
- // .collect();
- //
- // match matches.len() {
- // 0 => {
- // println!("No entries to prune.");
- // return Ok(());
- // }
- // 1 => println!("Found 1 entry to prune."),
- // n => println!("Found {n} entries to prune."),
- // }
- //
- // if dry_run {
- // print_list(
- // &matches,
- // ListMode::Human,
- // Some(settings.history_format.as_str()),
- // false,
- // false,
- // settings.timezone,
- // );
- // } else {
- // let encryption_key: [u8; 32] = encryption::load_key(settings)
- // .context("could not load encryption key")?
- // .into();
- // let host_id = Settings::host_id().await?;
- // let history_store = HistoryStore::new(store.clone(), host_id, encryption_key);
- //
- // for entry in matches {
- // eprintln!("deleting {}", entry.id);
- // let (id, _) = history_store.delete(entry.id.clone()).await?;
- // history_store.incremental_build(db, &[id]).await?;
- // }
- //
- // daemon::emit_event(settings, crate::atuin_daemon::DaemonEvent::HistoryPruned).await;
- // }
- // Ok(())
- // }
- //
- // async fn handle_dedup(
- // db: &ClientSqlite,
- // settings: &Settings,
- // store: SqliteStore,
- // before: i64,
- // dupkeep: u32,
- // dry_run: bool,
- // ) -> Result<()> {
- // if dupkeep == 0 {
- // eprintln!(
- // "\"--dupkeep 0\" would keep 0 copies of duplicate commands and thus delete all of them! Use \"atuin search --delete ...\" if you really want that."
- // );
- // std::process::exit(1);
- // }
- //
- // let matches: Vec<History> = db.get_dups(before, dupkeep).await?;
- //
- // match matches.len() {
- // 0 => {
- // println!("No duplicates to delete.");
- // return Ok(());
- // }
- // 1 => println!("Found 1 duplicate to delete."),
- // n => println!("Found {n} duplicates to delete."),
- // }
- //
- // if dry_run {
- // print_list(
- // &matches,
- // ListMode::Human,
- // Some(settings.history_format.as_str()),
- // false,
- // false,
- // settings.timezone,
- // );
- // } else {
- // let encryption_key: [u8; 32] = encryption::load_key(settings)
- // .context("could not load encryption key")?
- // .into();
- // let host_id = Settings::host_id().await?;
- // let history_store = HistoryStore::new(store.clone(), host_id, encryption_key);
- //
- // let ids = matches.iter().map(|h| h.id.clone()).collect::<Vec<_>>();
- //
- // for entry in matches {
- // eprintln!("deleting {}", entry.id);
- // let (id, _) = history_store.delete(entry.id).await?;
- // history_store.incremental_build(db, &[id]).await?;
- // }
- //
- // daemon::emit_event(
- // settings,
- // crate::atuin_daemon::DaemonEvent::HistoryDeleted { ids },
- // )
- // .await;
- // }
- // Ok(())
- // }
-
- #[expect(clippy::too_many_lines)]
pub(crate) async fn run(self, settings: &Settings) -> Result<()> {
match self {
Self::Start {
@@ -322,267 +78,10 @@ impl Cmd {
Self::Tail => {
return tail::handle(settings).await;
}
- cmd => {
- todo!()
- // let context = current_context().await?;
- //
- // let db_path = PathBuf::from(settings.db_path.as_str());
- // let record_store_path = PathBuf::from(settings.record_store_path.as_str());
- //
- // let db = ClientSqlite::new(db_path, settings.local_timeout).await?;
- // let store = SqliteStore::new(record_store_path, settings.local_timeout).await?;
- //
- // let encryption_key: [u8; 32] = encryption::load_key(settings)
- // .context("could not load encryption key")?
- // .into();
- //
- // let host_id = Settings::host_id().await?;
- // let history_store = HistoryStore::new(store.clone(), host_id, encryption_key);
- //
- // match cmd {
- // Self::List {
- // session,
- // cwd,
- // human,
- // cmd_only,
- // print0,
- // reverse,
- // timezone,
- // format,
- // } => {
- // let mode = ListMode::from_flags(human, cmd_only);
- // let tz = timezone.unwrap_or(settings.timezone);
- // Self::handle_list(
- // &db, settings, context, session, cwd, mode, format, false, print0,
- // reverse, tz,
- // )
- // .await
- // }
- //
- // Self::Last {
- // human,
- // cmd_only,
- // timezone,
- // format,
- // } => {
- // let last = db.last().await?;
- // let last = last.as_slice();
- // let tz = timezone.unwrap_or(settings.timezone);
- // print_list(
- // last,
- // ListMode::from_flags(human, cmd_only),
- // match format {
- // None => Some(settings.history_format.as_str()),
- // _ => format.as_deref(),
- // },
- // false,
- // true,
- // tz,
- // );
- //
- // Ok(())
- // }
- //
- // Self::InitStore => history_store.init_store(&db).await,
- //
- // Self::Prune { dry_run } => {
- // Self::handle_prune(&db, settings, store, context, dry_run).await
- // }
- //
- // Self::Dedup {
- // dry_run,
- // before,
- // dupkeep,
- // } => {
- // let before = i64::try_from(
- // interim::parse_date_string(
- // before.as_str(),
- // OffsetDateTime::now_utc(),
- // interim::Dialect::Uk,
- // )?
- // .unix_timestamp_nanos(),
- // )?;
- // Self::handle_dedup(&db, settings, store, before, dupkeep, dry_run).await
- // }
- //
- // Self::Start { .. } | Self::End { .. } | Self::Tail => unreachable!(),
- // }
- }
- }
- }
-}
-
-#[derive(Clone, Copy, Debug)]
-pub(crate) enum ListMode {
- Human,
- CmdOnly,
- Regular,
-}
-
-impl ListMode {
- pub(crate) const fn from_flags(human: bool, cmd_only: bool) -> Self {
- if human {
- Self::Human
- } else if cmd_only {
- Self::CmdOnly
- } else {
- Self::Regular
- }
- }
-}
-
-pub(crate) fn print_list(
- h: &[History],
- list_mode: ListMode,
- format: Option<&str>,
- print0: bool,
- reverse: bool,
- tz: Timezone,
-) {
- let w = io::stdout();
- let mut w = w.lock();
-
- let fmt_str = match list_mode {
- ListMode::Human => format
- .unwrap_or("{time} ยท {duration}\t{command}")
- .replace("\\t", "\t"),
- ListMode::Regular => format
- .unwrap_or("{time}\t{command}\t{duration}")
- .replace("\\t", "\t"),
- // not used
- ListMode::CmdOnly => String::new(),
- };
-
- let parsed_fmt = match list_mode {
- ListMode::Human | ListMode::Regular => parse_fmt(&fmt_str),
- ListMode::CmdOnly => std::iter::once(ParseSegment::Key("command")).collect(),
- };
-
- #[expect(trivial_casts)]
- let iterator = if reverse {
- Box::new(h.iter().rev()) as Box<dyn Iterator<Item = &History>>
- } else {
- Box::new(h.iter()) as Box<dyn Iterator<Item = &History>>
- };
-
- let entry_terminator = if print0 { "\0" } else { "\n" };
- let flush_each_line = print0;
-
- for history in iterator {
- let fh = FmtHistory {
- history,
- cmd_format: CmdFormat::for_output(&w),
- tz: &tz,
- };
- let args = parsed_fmt.with_args(&fh);
-
- // Check for formatting errors before attempting to write
- if let Err(err) = args.status() {
- eprintln!("ERROR: history output failed with: {err}");
- std::process::exit(1);
- }
-
- let write_result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
- write!(w, "{args}{entry_terminator}")
- }));
-
- match write_result {
- Ok(Ok(())) => {
- // Write succeeded
- }
- Ok(Err(err)) => {
- if err.kind() != io::ErrorKind::BrokenPipe {
- eprintln!("ERROR: Failed to write history output: {err}");
- std::process::exit(1);
- }
- }
- Err(_) => {
- eprintln!("ERROR: Format string caused a formatting error.");
- eprintln!(
- "This may be due to an unsupported format string containing special characters."
- );
- eprintln!(
- "Please check your format string syntax and ensure literal braces are properly escaped."
- );
- std::process::exit(1);
- }
- }
- if flush_each_line {
- check_for_write_errors(w.flush());
- }
- }
-
- if !flush_each_line {
- check_for_write_errors(w.flush());
- }
-}
-
-fn check_for_write_errors(write: Result<(), io::Error>) {
- if let Err(err) = write {
- // Ignore broken pipe (issue #626)
- if err.kind() != io::ErrorKind::BrokenPipe {
- eprintln!("ERROR: History output failed with the following error: {err}");
- std::process::exit(1);
}
}
}
-/// Type wrapper around `History` with formatting settings.
-#[derive(Clone, Copy, Debug)]
-struct FmtHistory<'a> {
- history: &'a History,
- cmd_format: CmdFormat,
- tz: &'a Timezone,
-}
-/// defines how to format the history
-impl FormatKey for FmtHistory<'_> {
- #[expect(clippy::cast_sign_loss)]
- fn fmt(&self, key: &str, f: &mut fmt::Formatter<'_>) -> Result<(), FormatKeyError> {
- match key {
- "command" => match self.cmd_format {
- CmdFormat::Literal => f.write_str(self.history.command.trim()),
- CmdFormat::Escaped => f.write_str(&self.history.command.trim().escape_control()),
- }?,
- "directory" => f.write_str(self.history.cwd.trim())?,
- "exit" => f.write_str(&self.history.exit.to_string())?,
- "duration" => {
- let dur = Duration::from_nanos(std::cmp::max(self.history.duration, 0) as u64);
- format_duration_into(dur, f)?;
- }
- "time" => {
- self.history
- .timestamp
- .to_offset(self.tz.0)
- .format(TIME_FMT)
- .map_err(|_| fmt::Error)?
- .fmt(f)?;
- }
- "relativetime" => {
- let since = OffsetDateTime::now_utc() - self.history.timestamp;
- let d = Duration::try_from(since).unwrap_or_default();
- format_duration_into(d, f)?;
- }
- "host" => f.write_str(
- self.history
- .hostname
- .split_once(':')
- .map_or(&self.history.hostname, |(host, _)| host),
- )?,
- "author" => f.write_str(&self.history.author)?,
- "intent" => f.write_str(self.history.intent.as_deref().unwrap_or_default())?,
- "user" => f.write_str(
- self.history
- .hostname
- .split_once(':')
- .map_or("", |(_, user)| user),
- )?,
- "session" => f.write_str(&self.history.session)?,
- "uuid" => f.write_str(&self.history.id.0)?,
- _ => return Err(FormatKeyError::UnknownKey),
- }
- Ok(())
- }
-}
fn format_duration_into(dur: Duration, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fn item(unit: &'static str, value: u64) -> ControlFlow<(&'static str, u64)> {
if value > 0 {
@@ -634,45 +133,9 @@ fn format_duration_into(dur: Duration, f: &mut fmt::Formatter<'_>) -> fmt::Resul
}
}
-#[derive(Clone, Copy, Debug)]
-enum CmdFormat {
- Literal,
- Escaped,
-}
-impl CmdFormat {
- fn for_output<O: IsTerminal>(out: &O) -> Self {
- if out.is_terminal() {
- Self::Escaped
- } else {
- Self::Literal
- }
- }
-}
-
static TIME_FMT: &[time::format_description::FormatItem<'static>] =
format_description!("[year]-[month]-[day] [hour repr:24]:[minute]:[second]");
-fn parse_fmt(format: &str) -> ParsedFmt<'_> {
- match ParsedFmt::new(format) {
- Ok(fmt) => fmt,
- Err(err) => {
- eprintln!("ERROR: History formatting failed with the following error: {err}");
-
- if format.contains('"') && (format.contains(":{") || format.contains(",{")) {
- eprintln!("It looks like you're trying to create JSON output.");
- eprintln!("For JSON, you need to escape literal braces by doubling them:");
- eprintln!("Example: '{{\"command\":\"{{command}}\",\"time\":\"{{time}}\"}}'");
- } else {
- eprintln!(
- "If your formatting string contains literal curly braces, you need to escape them by doubling:"
- );
- eprintln!("Use {{{{ for literal {{ and }}}} for literal }}");
- }
- std::process::exit(1)
- }
- }
-}
-
fn apply_start_metadata(history: &mut History, author: Option<&str>, intent: Option<&str>) {
if let Some(author) = author.map(str::trim).filter(|author| !author.is_empty()) {
author.clone_into(&mut history.author);
@@ -711,7 +174,7 @@ fn normalize_command_for_storage<'a>(command: &'a str, settings: &Settings) -> &
#[cfg(test)]
mod tests {
- use super::{Settings, normalize_command_for_storage, parse_fmt};
+ use super::{Settings, normalize_command_for_storage};
#[test]
fn normalize_command_strips_trailing_spaces_and_tabs() {
@@ -734,20 +197,4 @@ mod tests {
"printf foo\\\\"
);
}
-
- #[test]
- fn test_format_string_no_panic() {
- // Don't panic but provide helpful output (issue #2776)
- let malformed_json = r#"{"command":"{command}","key":"value"}"#;
-
- let result = std::panic::catch_unwind(|| parse_fmt(malformed_json));
-
- assert!(result.is_ok());
- }
-
- #[test]
- fn test_valid_formats_still_work() {
- assert!(std::panic::catch_unwind(|| parse_fmt("{command}")).is_ok());
- assert!(std::panic::catch_unwind(|| parse_fmt("{time} - {command}")).is_ok());
- }
}
diff --git a/crates/client/src/command/client/history/start.rs b/crates/client/src/command/client/history/start.rs
index defd46a3..cb8f1b0c 100644
--- a/crates/client/src/command/client/history/start.rs
+++ b/crates/client/src/command/client/history/start.rs
@@ -1,17 +1,19 @@
use crate::{
atuin_client::settings::Settings,
- command::client::history::{apply_start_metadata, normalize_command_for_storage},
+ command::{
+ client::history::{apply_start_metadata, normalize_command_for_storage},
+ current_session,
+ },
};
use eyre::{Result, eyre};
use time::OffsetDateTime;
use tracing::debug;
-use turtle::History;
-use turtle_common::utils;
-use turtle_daemon::{
- aclient::history::SettingsFilter,
- api::client::{HistoryClient, daemon_matches_expected, daemon_mismatch_message},
+use turtle::{
+ client::{HistoryClient, daemon_matches_expected, daemon_mismatch_message},
+ history::{History, SettingsFilter},
};
+use turtle_common::utils::{self, get_hostname, get_username};
pub(super) async fn handle(
settings: &Settings,
@@ -28,6 +30,9 @@ pub(super) async fn handle(
.timestamp(OffsetDateTime::now_utc())
.command(command)
.cwd(cwd)
+ .session(current_session()?)
+ .hostname(get_hostname())
+ .author(get_username())
.build()
.into();
apply_start_metadata(&mut h, author, intent);
@@ -63,13 +68,13 @@ async fn start_history(settings: &Settings, history: History) -> Result<String>
.await
{
Ok(resp) => {
- if daemon_matches_expected(&resp.version, resp.protocol) {
+ if daemon_matches_expected(resp.protocol) {
return Ok(resp.id);
}
Err(eyre!(
"{}. Restart the daemon manually",
- daemon_mismatch_message(&resp.version, resp.protocol)
+ daemon_mismatch_message(resp.protocol)
))
}
Err(err) => Err(err),
diff --git a/crates/client/src/command/client/history/tail.rs b/crates/client/src/command/client/history/tail.rs
index 595fe3a0..212d7fcd 100644
--- a/crates/client/src/command/client/history/tail.rs
+++ b/crates/client/src/command/client/history/tail.rs
@@ -7,13 +7,13 @@ use colored::Colorize;
use eyre::{Context, Result, bail};
use serde::Serialize;
use time::OffsetDateTime;
-use turtle_common::utils::Escapable;
-use turtle_daemon::{
- aclient::history::History,
- api::client::{
+use turtle::{
+ client::{
HistoryClient, HistoryEventKind, Probe, TailHistoryReply, history_entry_to_history, probe,
},
+ history::History,
};
+use turtle_common::utils::Escapable;
use std::{
fmt::{self, Display},
@@ -301,7 +301,7 @@ async fn tail_client(settings: &Settings) -> Result<HistoryClient> {
pub(super) async fn handle(settings: &Settings) -> Result<()> {
let tty = io::stdout().is_terminal();
- let mut client = HistoryClient::new(settings.daemon.socket_path.clone()).await?;
+ let mut client = tail_client(settings).await?;
let mut stream = client.tail_history().await?;
let stdout = io::stdout();
diff --git a/crates/client/src/command/client/info.rs b/crates/client/src/command/client/info.rs
index 77c7064c..c4839c38 100644
--- a/crates/client/src/command/client/info.rs
+++ b/crates/client/src/command/client/info.rs
@@ -2,7 +2,7 @@ use crate::atuin_client::settings::Settings;
use crate::{SHA, VERSION};
use eyre::Result;
-use turtle_daemon::api::client::ControlClient;
+use turtle::client::ControlClient;
pub(crate) async fn run(settings: &Settings) -> Result<()> {
let config = turtle_common::utils::config_dir();
diff --git a/crates/client/src/command/client/stats.rs b/crates/client/src/command/client/stats.rs
index ec235f36..88734bb6 100644
--- a/crates/client/src/command/client/stats.rs
+++ b/crates/client/src/command/client/stats.rs
@@ -1,8 +1,8 @@
use clap::Parser;
use eyre::Result;
-use interim::parse_date_string;
+use interim::{Dialect, parse_date_string};
use time::{Duration, OffsetDateTime, Time};
-use turtle_daemon::api::client::{HistoryClient, Range};
+use turtle::client::{HistoryClient, Range};
use crate::atuin_client::settings::Settings;
@@ -69,7 +69,7 @@ impl Cmd {
let start = end - Duration::days(365);
client.history(session, Some(Range { start, end })).await?
} else {
- let start = parse_date_string(&words, now, settings.dialect.into())?;
+ let start = parse_date_string(&words, now, Dialect::Uk)?;
let end = start + Duration::days(1);
client.history(session, Some(Range { start, end })).await?
};
diff --git a/crates/client/src/command/client/sync.rs b/crates/client/src/command/client/sync.rs
index ac0d0afe..77ae97ba 100644
--- a/crates/client/src/command/client/sync.rs
+++ b/crates/client/src/command/client/sync.rs
@@ -1,7 +1,7 @@
use clap::Subcommand;
use eyre::{Result, bail};
-use turtle_daemon::api::client::{Probe, probe};
+use turtle::client::{Probe, probe};
use crate::atuin_client::settings::Settings;
diff --git a/crates/client/src/command/client/wrapped.rs b/crates/client/src/command/client/wrapped.rs
index 64e5b718..8c15a5d3 100644
--- a/crates/client/src/command/client/wrapped.rs
+++ b/crates/client/src/command/client/wrapped.rs
@@ -2,13 +2,16 @@ use crossterm::style::{ResetColor, SetAttribute};
use eyre::Result;
use std::collections::{HashMap, HashSet};
use time::{Date, Duration, Month, OffsetDateTime, Time};
-use turtle_daemon::aclient::history::History;
-use turtle_daemon::api::client::{HistoryClient, Range};
+use turtle::{
+ client::{HistoryClient, Range},
+ history::History,
+};
-use crate::atuin_client::settings::Settings;
-
-use crate::atuin_history::stats::{Stats, compute};
-use crate::command::current_session;
+use crate::{
+ atuin_client::settings::Settings,
+ atuin_history::stats::{Stats, compute},
+ command::current_session,
+};
#[derive(Debug)]
struct WrappedStats {
diff --git a/crates/client/src/command/mod.rs b/crates/client/src/command/mod.rs
index 2e51a1e2..a2e75034 100644
--- a/crates/client/src/command/mod.rs
+++ b/crates/client/src/command/mod.rs
@@ -10,7 +10,6 @@ mod gen_completions;
#[derive(Subcommand)]
#[command(infer_subcommands = true)]
-#[expect(clippy::large_enum_variant)]
pub(crate) enum AtuinCmd {
#[command(flatten)]
Client(client::Cmd),
@@ -50,14 +49,6 @@ impl AtuinCmd {
}
}
-#[cfg(unix)]
-#[inline]
-fn is_truthy_env(name: &str) -> bool {
- std::env::var(name)
- .ok()
- .as_ref()
- .is_some_and(|value| !value.trim().is_empty() && value.trim() != "false")
-}
pub(crate) fn current_session() -> Result<String> {
std::env::var("ATUIN_SESSION").map_err(|_| {
eyre::eyre!("Failed to find $ATUIN_SESSION in the environment. Check that you have correctly set up your shell.")