diff options
Diffstat (limited to 'crates/turtle/src/atuin_daemon')
| -rw-r--r-- | crates/turtle/src/atuin_daemon/client.rs | 83 | ||||
| -rw-r--r-- | crates/turtle/src/atuin_daemon/daemon.rs | 28 | ||||
| -rw-r--r-- | crates/turtle/src/atuin_daemon/mod.rs | 3 | ||||
| -rw-r--r-- | crates/turtle/src/atuin_daemon/search/index.rs | 29 |
4 files changed, 18 insertions, 125 deletions
diff --git a/crates/turtle/src/atuin_daemon/client.rs b/crates/turtle/src/atuin_daemon/client.rs index a0a27741..325b21b8 100644 --- a/crates/turtle/src/atuin_daemon/client.rs +++ b/crates/turtle/src/atuin_daemon/client.rs @@ -29,8 +29,7 @@ use crate::atuin_daemon::search::{ search_client::SearchClient as SearchServiceClient, }; use crate::atuin_daemon::semantic::{ - CommandCapture, CommandOutputReply, CommandOutputRequest, OutputRange, RecordCommandsReply, - semantic_client::SemanticClient as SemanticServiceClient, + CommandCapture, RecordCommandsReply, semantic_client::SemanticClient as SemanticServiceClient, }; pub(crate) struct HistoryClient { @@ -112,7 +111,7 @@ impl HistoryClient { duration: u64, exit: i64, ) -> Result<EndHistoryReply> { - let req = EndHistoryRequest { id, duration, exit }; + let req = EndHistoryRequest { id, exit, duration }; Ok(self.client.end_history(req).await?.into_inner()) } @@ -255,22 +254,6 @@ impl SemanticClient { let stream = tokio_stream::iter(captures); Ok(self.client.record_commands(stream).await?.into_inner()) } - - pub(crate) async fn command_output( - &mut self, - history_id: String, - ranges: Vec<(i64, i64)>, - ) -> Result<CommandOutputReply> { - let request = CommandOutputRequest { - history_id, - ranges: ranges - .into_iter() - .map(|(start, end)| OutputRange { start, end }) - .collect(), - }; - - Ok(self.client.command_output(request).await?.into_inner()) - } } // ============================================================================ @@ -354,65 +337,3 @@ fn daemon_event_to_proto( } } } - -// ============================================================================ -// Convenience Functions -// ============================================================================ - -/// Emit an event to the daemon. -/// -/// This is a fire-and-forget helper for sending events to the daemon from -/// external processes like CLI commands. If the daemon isn't running, this -/// will silently succeed (returns Ok). -/// -/// # Example -/// -/// ```ignore -/// // After pruning history -/// emit_event(DaemonEvent::HistoryPruned).await?; -/// -/// // After deleting specific history items -/// emit_event(DaemonEvent::HistoryDeleted { ids: vec![...] }).await?; -/// -/// // Request immediate sync -/// emit_event(DaemonEvent::ForceSync).await?; -/// ``` -pub(crate) async fn emit_event(event: DaemonEvent) -> Result<()> { - emit_event_with_settings(event, None).await -} - -/// Emit an event to the daemon with explicit settings. -/// -/// If settings are not provided, they will be loaded from the default location. -/// If the daemon isn't running, this will silently succeed. -pub(crate) async fn emit_event_with_settings( - event: DaemonEvent, - settings: Option<&Settings>, -) -> Result<()> { - // Load settings if not provided - let owned_settings; - let settings = match settings { - Some(s) => s, - None => { - owned_settings = Settings::new()?; - &owned_settings - } - }; - - // Try to connect - if daemon isn't running, that's fine - let mut client = match ControlClient::from_settings(settings).await { - Ok(c) => c, - Err(e) => { - tracing::debug!(?e, "daemon not running, skipping event emission"); - return Ok(()); - } - }; - - // Send the event - if let Err(e) = client.send_event(event).await { - tracing::debug!(?e, "failed to send event to daemon"); - // Don't fail - this is fire-and-forget - } - - Ok(()) -} diff --git a/crates/turtle/src/atuin_daemon/daemon.rs b/crates/turtle/src/atuin_daemon/daemon.rs index 7583c197..80aaeef8 100644 --- a/crates/turtle/src/atuin_daemon/daemon.rs +++ b/crates/turtle/src/atuin_daemon/daemon.rs @@ -113,17 +113,7 @@ impl DaemonHandle { self.state.settings.read().await } - /// Reload settings from disk and emit a SettingsReloaded event. - /// - /// Components listening for `SettingsReloaded` can then re-read settings - /// via `handle.settings()` to pick up the changes. - pub(crate) async fn reload_settings(&self) -> Result<()> { - let new_settings = Settings::new()?; - self.apply_settings(new_settings).await; - Ok(()) - } - - /// Apply already-loaded settings and emit a SettingsReloaded event. + /// Apply already-loaded settings and emit a [`SettingsReloaded`] event. /// /// Use this when settings have already been loaded (e.g., from a file watcher) /// to avoid parsing the config file twice. @@ -292,7 +282,7 @@ impl Daemon { /// Run the daemon event loop. /// - /// This processes events until a ShutdownRequested event is received. + /// This processes events until a [`ShutdownRequested`] event is received. /// Components must be started first via `start_components()`. pub(crate) async fn run_event_loop(&mut self) -> Result<()> { let mut event_rx = self.handle.subscribe(); @@ -338,18 +328,6 @@ impl Daemon { tracing::info!("all components stopped"); } - /// Run the daemon. - /// - /// This is a convenience method that starts components, runs the event loop, - /// and handles shutdown. It does not return until the daemon is shut down. - pub(crate) async fn run(mut self) -> Result<()> { - self.start_components().await?; - self.run_event_loop().await?; - self.stop_components().await; - tracing::info!("daemon stopped"); - Ok(()) - } - async fn dispatch_event(&mut self, event: &DaemonEvent) { for component in &mut self.components { if let Err(e) = component.handle_event(event).await { @@ -424,7 +402,7 @@ impl DaemonBuilder { /// Build the daemon. /// /// This loads the encryption key and creates the daemon state. - pub(crate) async fn build(self) -> Result<Daemon> { + pub(crate) fn build(self) -> Result<Daemon> { let store = self.store.ok_or_else(|| eyre::eyre!("store is required"))?; let history_db = self .history_db diff --git a/crates/turtle/src/atuin_daemon/mod.rs b/crates/turtle/src/atuin_daemon/mod.rs index 6037b5a8..b161b0cc 100644 --- a/crates/turtle/src/atuin_daemon/mod.rs +++ b/crates/turtle/src/atuin_daemon/mod.rs @@ -52,8 +52,7 @@ pub(crate) async fn boot( .component(search_component) .component(semantic_component) .component(sync_component) - .build() - .await?; + .build()?; // Get a handle for the control service and gRPC server shutdown let handle = daemon.handle(); diff --git a/crates/turtle/src/atuin_daemon/search/index.rs b/crates/turtle/src/atuin_daemon/search/index.rs index a23b3133..197a8c1b 100644 --- a/crates/turtle/src/atuin_daemon/search/index.rs +++ b/crates/turtle/src/atuin_daemon/search/index.rs @@ -90,7 +90,7 @@ impl FrecencyData { }; // Frequency boost: more uses = higher score (with diminishing returns) - let frequency_score = ((self.count as f64).ln() * 20.0).min(100.0); + let frequency_score = (f64::from(self.count).ln() * 20.0).min(100.0); // Apply multipliers and combine scores, then round to u32 ((recency_score * recency_mul) + (frequency_score * frequency_mul)).round() as u32 @@ -117,7 +117,7 @@ pub(crate) struct CommandData { } impl CommandData { - /// Create a new CommandData from a history entry. + /// Create a new [`CommandData`] from a history entry. /// Returns None if the history entry has invalid UUIDs. pub(crate) fn new(history: &History, interner: &ThreadedRodeo) -> Option<Self> { let history_id = parse_uuid_bytes(&history.id.0)?; @@ -237,9 +237,13 @@ pub(crate) enum IndexFilterMode { /// Context for search queries. #[derive(Debug, Clone, Default)] pub(crate) struct QueryContext { + #[expect(dead_code)] pub(crate) cwd: Option<String>, + #[expect(dead_code)] pub(crate) git_root: Option<String>, + #[expect(dead_code)] pub(crate) hostname: Option<String>, + #[expect(dead_code)] pub(crate) session_id: Option<String>, } @@ -325,21 +329,21 @@ impl SearchIndex { self.commands.len() } - /// Get the number of items in Nucleo (should match command_count). - pub(crate) async fn nucleo_item_count(&self) -> u32 { - self.nucleo.read().await.snapshot().item_count() - } - /// Search for commands matching a query. /// /// Returns a list of history IDs (most recent invocation per command). /// Uses precomputed global frecency for scoring if available. #[instrument(skip_all, level = tracing::Level::TRACE, name = "index_search", fields(query = %query))] + #[expect( + clippy::significant_drop_tightening, + reason = "The nucleo early drop is a false-positive" + )] pub(crate) async fn search( &self, query: &str, filter_mode: IndexFilterMode, - _context: &QueryContext, + // TODO(@bpeetz): Use the query context here <2026-06-12> + #[expect(unused)] context: &QueryContext, limit: u32, ) -> Vec<String> { let mut nucleo = self.nucleo.write().await; @@ -480,15 +484,6 @@ mod tests { use super::*; use time::macros::datetime; - fn make_history(command: &str, cwd: &str, timestamp: OffsetDateTime) -> History { - History::import() - .timestamp(timestamp) - .command(command) - .cwd(cwd) - .build() - .into() - } - #[test] fn frecency_data_compute() { let now = 1_000_000i64; |
