aboutsummaryrefslogtreecommitdiffstats
path: root/crates/atuin-daemon
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-06-11 00:54:30 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-06-11 00:54:30 +0200
commit5c39e7cf284a1f6e9a1657f2deb44e359fc47eb8 (patch)
treec64baa8d5866c8e339eaf660dd3f94f30a3f7d8a /crates/atuin-daemon
parentchore: Somewhat simplify sync code (diff)
downloadatuin-5c39e7cf284a1f6e9a1657f2deb44e359fc47eb8.zip
chore: Move everything into one big crate
That helps remove duplicated code and rustc/cargo will now also show dead code correctly.
Diffstat (limited to '')
-rw-r--r--crates/atuin-daemon/Cargo.toml52
-rw-r--r--crates/atuin-daemon/build.rs25
-rw-r--r--crates/atuin-daemon/tests/lifecycle.rs222
-rw-r--r--crates/turtle/proto/control.proto (renamed from crates/atuin-daemon/proto/control.proto)0
-rw-r--r--crates/turtle/proto/history.proto (renamed from crates/atuin-daemon/proto/history.proto)0
-rw-r--r--crates/turtle/proto/search.proto (renamed from crates/atuin-daemon/proto/search.proto)0
-rw-r--r--crates/turtle/proto/semantic.proto (renamed from crates/atuin-daemon/proto/semantic.proto)0
-rw-r--r--crates/turtle/src/atuin_daemon/client.rs (renamed from crates/atuin-daemon/src/client.rs)126
-rw-r--r--crates/turtle/src/atuin_daemon/components/history.rs (renamed from crates/atuin-daemon/src/components/history.rs)4
-rw-r--r--crates/turtle/src/atuin_daemon/components/mod.rs (renamed from crates/atuin-daemon/src/components/mod.rs)0
-rw-r--r--crates/turtle/src/atuin_daemon/components/search.rs (renamed from crates/atuin-daemon/src/components/search.rs)6
-rw-r--r--crates/turtle/src/atuin_daemon/components/semantic.rs (renamed from crates/atuin-daemon/src/components/semantic.rs)29
-rw-r--r--crates/turtle/src/atuin_daemon/components/sync.rs (renamed from crates/atuin-daemon/src/components/sync.rs)4
-rw-r--r--crates/turtle/src/atuin_daemon/control/mod.rs (renamed from crates/atuin-daemon/src/control/mod.rs)0
-rw-r--r--crates/turtle/src/atuin_daemon/control/service.rs (renamed from crates/atuin-daemon/src/control/service.rs)4
-rw-r--r--crates/turtle/src/atuin_daemon/daemon.rs (renamed from crates/atuin-daemon/src/daemon.rs)4
-rw-r--r--crates/turtle/src/atuin_daemon/events.rs (renamed from crates/atuin-daemon/src/events.rs)4
-rw-r--r--crates/turtle/src/atuin_daemon/history/mod.rs (renamed from crates/atuin-daemon/src/history/mod.rs)0
-rw-r--r--crates/turtle/src/atuin_daemon/mod.rs (renamed from crates/atuin-daemon/src/lib.rs)14
-rw-r--r--crates/turtle/src/atuin_daemon/search/index.rs (renamed from crates/atuin-daemon/src/search/index.rs)13
-rw-r--r--crates/turtle/src/atuin_daemon/search/mod.rs (renamed from crates/atuin-daemon/src/search/mod.rs)0
-rw-r--r--crates/turtle/src/atuin_daemon/semantic/mod.rs (renamed from crates/atuin-daemon/src/semantic/mod.rs)0
-rw-r--r--crates/turtle/src/atuin_daemon/server.rs (renamed from crates/atuin-daemon/src/server.rs)75
23 files changed, 62 insertions, 520 deletions
diff --git a/crates/atuin-daemon/Cargo.toml b/crates/atuin-daemon/Cargo.toml
deleted file mode 100644
index e767d3c9..00000000
--- a/crates/atuin-daemon/Cargo.toml
+++ /dev/null
@@ -1,52 +0,0 @@
-[package]
-name = "atuin-daemon"
-edition = "2024"
-version = { workspace = true }
-description = "The daemon crate for Atuin"
-
-authors.workspace = true
-rust-version.workspace = true
-license.workspace = true
-homepage.workspace = true
-repository.workspace = true
-readme.workspace = true
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-atuin-client = { path = "../atuin-client", version = "18.16.1" }
-atuin-common = { path = "../atuin-common", version = "18.16.1" }
-atuin-history = { path = "../atuin-history", version = "18.16.1" }
-
-time = { workspace = true }
-uuid = { workspace = true }
-tokio = { workspace = true }
-tower = { workspace = true }
-eyre = { workspace = true }
-tracing = { workspace = true }
-tracing-subscriber = { workspace = true }
-
-dashmap = "6.1.0"
-lasso = { version = "0.7", features = ["multi-threaded"] }
-tonic-types = "0.14"
-tonic = "0.14"
-tonic-prost = "0.14"
-prost = "0.14"
-prost-types = "0.14"
-tokio-stream = { version = "0.1.14", features = ["net"] }
-hyper-util = "0.1"
-
-rand.workspace = true
-atuin-nucleo = { workspace = true }
-
-
-[target.'cfg(target_os = "linux")'.dependencies]
-listenfd = "1.0.1"
-
-[dev-dependencies]
-tempfile = { workspace = true }
-
-[build-dependencies]
-protox = "0.9"
-tonic-build = "0.14"
-tonic-prost-build = "0.14"
diff --git a/crates/atuin-daemon/build.rs b/crates/atuin-daemon/build.rs
deleted file mode 100644
index 7808a07b..00000000
--- a/crates/atuin-daemon/build.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use std::{env, fs, path::PathBuf};
-
-use protox::prost::Message;
-
-fn main() -> std::io::Result<()> {
- let proto_paths = [
- "proto/history.proto",
- "proto/search.proto",
- "proto/control.proto",
- "proto/semantic.proto",
- ];
- let proto_include_dirs = ["proto"];
-
- let file_descriptors = protox::compile(proto_paths, proto_include_dirs).unwrap();
-
- let file_descriptor_path = PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR not set"))
- .join("file_descriptor_set.bin");
- fs::write(&file_descriptor_path, file_descriptors.encode_to_vec()).unwrap();
-
- tonic_prost_build::configure()
- .build_server(true)
- .file_descriptor_set_path(&file_descriptor_path)
- .skip_protoc_run()
- .compile_protos(&proto_paths, &proto_include_dirs)
-}
diff --git a/crates/atuin-daemon/tests/lifecycle.rs b/crates/atuin-daemon/tests/lifecycle.rs
deleted file mode 100644
index 4a91e5cb..00000000
--- a/crates/atuin-daemon/tests/lifecycle.rs
+++ /dev/null
@@ -1,222 +0,0 @@
-//! Integration tests for the daemon server lifecycle.
-//!
-//! Each test spins up a real gRPC server on a temporary unix socket,
-//! connects a client, and exercises the daemon RPCs.
-
-#[cfg(unix)]
-mod unix {
- use std::time::Duration;
-
- use atuin_client::database::Sqlite;
- use atuin_client::record::sqlite_store::SqliteStore;
- use atuin_client::settings::{Settings, init_meta_config_for_testing};
- use atuin_daemon::client::HistoryClient;
- use atuin_daemon::components::HistoryComponent;
- use atuin_daemon::{Daemon, DaemonHandle};
- use tempfile::TempDir;
- use tokio::net::UnixListener;
- use tokio_stream::wrappers::UnixListenerStream;
- use tonic::transport::Server;
-
- /// Spins up a daemon server on a temp socket and returns a connected client,
- /// the daemon handle (for shutdown), and the temp dir (must be held to keep paths alive).
- async fn start_test_daemon() -> (HistoryClient, DaemonHandle, TempDir) {
- let tmp = tempfile::tempdir().unwrap();
-
- let db_path = tmp.path().join("history.db");
- let record_path = tmp.path().join("records.db");
- let key_path = tmp.path().join("key");
- let socket_path = tmp.path().join("test.sock");
- let meta_path = tmp.path().join("meta.db");
-
- // Initialize the meta store config for testing (required for Settings::host_id())
- init_meta_config_for_testing(meta_path.to_str().unwrap(), 5.0);
-
- // Build settings with test paths
- let settings: Settings = Settings::builder()
- .expect("could not build settings builder")
- .set_override("db_path", db_path.to_str().unwrap())
- .expect("failed to set db_path")
- .set_override("record_store_path", record_path.to_str().unwrap())
- .expect("failed to set record_store_path")
- .set_override("key_path", key_path.to_str().unwrap())
- .expect("failed to set key_path")
- .set_override("daemon.socket_path", socket_path.to_str().unwrap())
- .expect("failed to set socket_path")
- .set_override("meta.db_path", meta_path.to_str().unwrap())
- .expect("failed to set meta.db_path")
- .build()
- .expect("could not build settings")
- .try_deserialize()
- .expect("could not deserialize settings");
-
- // Create databases
- let history_db = Sqlite::new(&db_path, 5.0).await.unwrap();
- let store = SqliteStore::new(&record_path, 5.0).await.unwrap();
-
- // Create the history component and get its gRPC service
- let history_component = HistoryComponent::new();
- let history_service = history_component.grpc_service();
-
- // Build and start the daemon
- let mut daemon = Daemon::builder(settings)
- .store(store)
- .history_db(history_db)
- .component(history_component)
- .build()
- .await
- .unwrap();
-
- let handle = daemon.handle();
-
- // Start components (this initializes the history component with the handle)
- daemon.start_components().await.unwrap();
-
- // Start the gRPC server
- let uds = UnixListener::bind(&socket_path).unwrap();
- let stream = UnixListenerStream::new(uds);
-
- let server_handle = handle.clone();
- tokio::spawn(async move {
- let mut rx = server_handle.subscribe();
- Server::builder()
- .add_service(history_service)
- .serve_with_incoming_shutdown(stream, async move {
- loop {
- match rx.recv().await {
- Ok(atuin_daemon::DaemonEvent::ShutdownRequested) => break,
- Ok(_) => continue,
- Err(_) => break,
- }
- }
- })
- .await
- .unwrap();
- });
-
- // Spawn the daemon event loop in the background
- tokio::spawn(async move {
- daemon.run_event_loop().await.unwrap();
- });
-
- // Give the server a moment to bind.
- tokio::time::sleep(Duration::from_millis(50)).await;
-
- let client = HistoryClient::new(socket_path.to_string_lossy().to_string())
- .await
- .unwrap();
-
- (client, handle, tmp)
- }
-
- #[tokio::test]
- async fn test_status() {
- let (mut client, _handle, _tmp) = start_test_daemon().await;
-
- let status = client.status().await.unwrap();
- assert!(status.healthy);
- assert_eq!(status.version, env!("CARGO_PKG_VERSION"));
- assert_eq!(status.protocol, 1);
- assert!(status.pid > 0);
- }
-
- #[tokio::test]
- async fn test_start_end_history() {
- use atuin_client::history::History;
-
- let (mut client, _handle, _tmp) = start_test_daemon().await;
-
- let history = History::daemon()
- .timestamp(time::OffsetDateTime::now_utc())
- .command("echo hello".to_string())
- .cwd("/tmp".to_string())
- .session("test-session".to_string())
- .hostname("test-host".to_string())
- .build()
- .into();
-
- let start_reply = client.start_history(history).await.unwrap();
- assert!(!start_reply.id.is_empty());
-
- let end_reply = client
- .end_history(start_reply.id, 1_000_000, 0)
- .await
- .unwrap();
- assert!(!end_reply.id.is_empty());
- }
-
- #[tokio::test]
- async fn test_tail_history_streams_started_and_ended_events() {
- use atuin_client::history::History;
- use atuin_daemon::history::HistoryEventKind;
-
- let (mut client, _handle, _tmp) = start_test_daemon().await;
- let mut stream = client.tail_history().await.unwrap();
-
- let history = History::daemon()
- .timestamp(time::OffsetDateTime::now_utc())
- .command("git status".to_string())
- .cwd("/tmp/repo".to_string())
- .session("tail-session".to_string())
- .hostname("test-host:ellie".to_string())
- .author("claude".to_string())
- .intent("inspect repository state".to_string())
- .build()
- .into();
-
- let start_reply = client.start_history(history).await.unwrap();
-
- let started = stream.message().await.unwrap().unwrap();
- assert_eq!(
- HistoryEventKind::try_from(started.kind).unwrap(),
- HistoryEventKind::Started
- );
- let started_history = started.history.unwrap();
- assert_eq!(started_history.id, start_reply.id);
- assert_eq!(started_history.command, "git status");
- assert_eq!(started_history.cwd, "/tmp/repo");
- assert_eq!(started_history.hostname, "test-host:ellie");
- assert_eq!(started_history.author, "claude");
- assert_eq!(started_history.intent, "inspect repository state");
-
- client
- .end_history(start_reply.id.clone(), 1_000_000, 0)
- .await
- .unwrap();
-
- let ended = stream.message().await.unwrap().unwrap();
- assert_eq!(
- HistoryEventKind::try_from(ended.kind).unwrap(),
- HistoryEventKind::Ended
- );
- let ended_history = ended.history.unwrap();
- assert_eq!(ended_history.id, start_reply.id);
- assert_eq!(ended_history.exit, 0);
- assert_eq!(ended_history.duration, 1_000_000);
- }
-
- #[tokio::test]
- async fn test_end_unknown_history_fails() {
- let (mut client, _handle, _tmp) = start_test_daemon().await;
-
- let result = client
- .end_history("nonexistent-id".to_string(), 1000, 0)
- .await;
- assert!(result.is_err());
- }
-
- #[tokio::test]
- async fn test_shutdown() {
- let (mut client, _handle, _tmp) = start_test_daemon().await;
-
- let accepted = client.shutdown().await.unwrap();
- assert!(accepted);
-
- // Give server time to shut down.
- tokio::time::sleep(Duration::from_millis(100)).await;
-
- // Subsequent calls should fail since the server is gone.
- let result = client.status().await;
- assert!(result.is_err());
- }
-}
diff --git a/crates/atuin-daemon/proto/control.proto b/crates/turtle/proto/control.proto
index 06347902..06347902 100644
--- a/crates/atuin-daemon/proto/control.proto
+++ b/crates/turtle/proto/control.proto
diff --git a/crates/atuin-daemon/proto/history.proto b/crates/turtle/proto/history.proto
index 59c12471..59c12471 100644
--- a/crates/atuin-daemon/proto/history.proto
+++ b/crates/turtle/proto/history.proto
diff --git a/crates/atuin-daemon/proto/search.proto b/crates/turtle/proto/search.proto
index 6b84acbd..6b84acbd 100644
--- a/crates/atuin-daemon/proto/search.proto
+++ b/crates/turtle/proto/search.proto
diff --git a/crates/atuin-daemon/proto/semantic.proto b/crates/turtle/proto/semantic.proto
index 07e550c8..07e550c8 100644
--- a/crates/atuin-daemon/proto/semantic.proto
+++ b/crates/turtle/proto/semantic.proto
diff --git a/crates/atuin-daemon/src/client.rs b/crates/turtle/src/atuin_daemon/client.rs
index c18e0e46..45ef19e9 100644
--- a/crates/atuin-daemon/src/client.rs
+++ b/crates/turtle/src/atuin_daemon/client.rs
@@ -1,8 +1,6 @@
-use atuin_client::database::Context;
-use atuin_client::settings::{FilterMode, Settings};
+use crate::atuin_client::database::Context;
+use crate::atuin_client::settings::{FilterMode, Settings};
use eyre::{Context as EyreContext, Result};
-#[cfg(windows)]
-use tokio::net::TcpStream;
use tonic::Code;
use tonic::transport::{Channel, Endpoint, Uri};
use tower::service_fn;
@@ -12,25 +10,25 @@ use hyper_util::rt::TokioIo;
#[cfg(unix)]
use tokio::net::UnixStream;
-use atuin_client::history::History;
+use crate::atuin_client::history::History;
use tracing::{Level, instrument, span};
-use crate::control::HistoryRebuiltEvent;
-use crate::control::{
+use crate::atuin_daemon::control::HistoryRebuiltEvent;
+use crate::atuin_daemon::control::{
ForceSyncEvent, HistoryDeletedEvent, HistoryPrunedEvent, SendEventRequest,
SettingsReloadedEvent, ShutdownEvent, control_client::ControlClient as ControlServiceClient,
};
-use crate::events::DaemonEvent;
-use crate::history::{
+use crate::atuin_daemon::events::DaemonEvent;
+use crate::atuin_daemon::history::{
EndHistoryReply, EndHistoryRequest, ShutdownRequest, StartHistoryReply, StartHistoryRequest,
StatusReply, StatusRequest, TailHistoryReply, TailHistoryRequest,
history_client::HistoryClient as HistoryServiceClient,
};
-use crate::search::{
+use crate::atuin_daemon::search::{
FilterMode as RpcFilterMode, SearchContext as RpcSearchContext, SearchRequest, SearchResponse,
search_client::SearchClient as SearchServiceClient,
};
-use crate::semantic::{
+use crate::atuin_daemon::semantic::{
CommandCapture, CommandOutputReply, CommandOutputRequest, OutputRange, RecordCommandsReply,
semantic_client::SemanticClient as SemanticServiceClient,
};
@@ -94,28 +92,6 @@ impl HistoryClient {
Ok(HistoryClient { client })
}
- #[cfg(not(unix))]
- pub async fn new(port: u64) -> Result<Self> {
- let channel = Endpoint::try_from("http://atuin_local_daemon:0")?
- .connect_with_connector(service_fn(move |_: Uri| {
- let url = format!("127.0.0.1:{port}");
-
- async move {
- Ok::<_, std::io::Error>(TokioIo::new(TcpStream::connect(url.clone()).await?))
- }
- }))
- .await
- .wrap_err_with(|| {
- format!(
- "failed to connect to local atuin daemon at 127.0.0.1:{port}. Is it running?"
- )
- })?;
-
- let client = HistoryServiceClient::new(channel);
-
- Ok(HistoryClient { client })
- }
-
pub async fn start_history(&mut self, h: History) -> Result<StartHistoryReply> {
let req = StartHistoryRequest {
command: h.command,
@@ -188,28 +164,6 @@ impl SearchClient {
Ok(SearchClient { client })
}
- #[cfg(not(unix))]
- pub async fn new(port: u64) -> Result<Self> {
- let channel = Endpoint::try_from("http://atuin_local_daemon:0")?
- .connect_with_connector(service_fn(move |_: Uri| {
- let url = format!("127.0.0.1:{port}");
-
- async move {
- Ok::<_, std::io::Error>(TokioIo::new(TcpStream::connect(url.clone()).await?))
- }
- }))
- .await
- .wrap_err_with(|| {
- format!(
- "failed to connect to local atuin daemon at 127.0.0.1:{port}. Is it running?"
- )
- })?;
-
- let client = SearchServiceClient::new(channel);
-
- Ok(SearchClient { client })
- }
-
#[instrument(skip_all, level = Level::TRACE, name = "daemon_client_search", fields(query = %query, query_id = query_id))]
pub async fn search(
&mut self,
@@ -289,38 +243,11 @@ impl SemanticClient {
Ok(SemanticClient { client })
}
- #[cfg(not(unix))]
- pub async fn new(port: u64) -> Result<Self> {
- let channel = Endpoint::try_from("http://atuin_local_daemon:0")?
- .connect_with_connector(service_fn(move |_: Uri| {
- let url = format!("127.0.0.1:{port}");
-
- async move {
- Ok::<_, std::io::Error>(TokioIo::new(TcpStream::connect(url.clone()).await?))
- }
- }))
- .await
- .wrap_err_with(|| {
- format!(
- "failed to connect to local atuin daemon at 127.0.0.1:{port}. Is it running?"
- )
- })?;
-
- let client = SemanticServiceClient::new(channel);
-
- Ok(SemanticClient { client })
- }
-
#[cfg(unix)]
pub async fn from_settings(settings: &Settings) -> Result<Self> {
Self::new(settings.daemon.socket_path.clone()).await
}
- #[cfg(not(unix))]
- pub async fn from_settings(settings: &Settings) -> Result<Self> {
- Self::new(settings.daemon.tcp_port).await
- }
-
pub async fn record_commands(
&mut self,
captures: Vec<CommandCapture>,
@@ -383,41 +310,12 @@ impl ControlClient {
Ok(ControlClient { client })
}
- /// Connect to the daemon's control service.
- #[cfg(not(unix))]
- pub async fn new(port: u64) -> Result<Self> {
- let channel = Endpoint::try_from("http://atuin_local_daemon:0")?
- .connect_with_connector(service_fn(move |_: Uri| {
- let url = format!("127.0.0.1:{port}");
-
- async move {
- Ok::<_, std::io::Error>(TokioIo::new(TcpStream::connect(url.clone()).await?))
- }
- }))
- .await
- .wrap_err_with(|| {
- format!(
- "failed to connect to local atuin daemon at 127.0.0.1:{port}. Is it running?"
- )
- })?;
-
- let client = ControlServiceClient::new(channel);
-
- Ok(ControlClient { client })
- }
-
/// Connect using settings.
#[cfg(unix)]
pub async fn from_settings(settings: &Settings) -> Result<Self> {
Self::new(settings.daemon.socket_path.clone()).await
}
- /// Connect using settings.
- #[cfg(not(unix))]
- pub async fn from_settings(settings: &Settings) -> Result<Self> {
- Self::new(settings.daemon.tcp_port).await
- }
-
/// Send an event to the daemon.
pub async fn send_event(&mut self, event: DaemonEvent) -> Result<()> {
let proto_event = daemon_event_to_proto(event);
@@ -430,8 +328,10 @@ impl ControlClient {
}
/// Convert a daemon event to its proto representation.
-fn daemon_event_to_proto(event: DaemonEvent) -> crate::control::send_event_request::Event {
- use crate::control::send_event_request::Event;
+fn daemon_event_to_proto(
+ event: DaemonEvent,
+) -> crate::atuin_daemon::control::send_event_request::Event {
+ use crate::atuin_daemon::control::send_event_request::Event;
match event {
DaemonEvent::HistoryPruned => Event::HistoryPruned(HistoryPrunedEvent {}),
diff --git a/crates/atuin-daemon/src/components/history.rs b/crates/turtle/src/atuin_daemon/components/history.rs
index c82c8f94..95d34b69 100644
--- a/crates/atuin-daemon/src/components/history.rs
+++ b/crates/turtle/src/atuin_daemon/components/history.rs
@@ -4,7 +4,7 @@
use std::{pin::Pin, sync::Arc};
-use atuin_client::{
+use crate::atuin_client::{
database::Database,
history::{History, HistoryId, store::HistoryStore},
settings::Settings,
@@ -16,7 +16,7 @@ use tokio_stream::Stream;
use tonic::{Request, Response, Status};
use tracing::{Level, instrument};
-use crate::{
+use crate::atuin_daemon::{
daemon::{Component, DaemonHandle},
events::DaemonEvent,
history::{
diff --git a/crates/atuin-daemon/src/components/mod.rs b/crates/turtle/src/atuin_daemon/components/mod.rs
index 447e31df..447e31df 100644
--- a/crates/atuin-daemon/src/components/mod.rs
+++ b/crates/turtle/src/atuin_daemon/components/mod.rs
diff --git a/crates/atuin-daemon/src/components/search.rs b/crates/turtle/src/atuin_daemon/components/search.rs
index 9fc87fae..85191cff 100644
--- a/crates/atuin-daemon/src/components/search.rs
+++ b/crates/turtle/src/atuin_daemon/components/search.rs
@@ -5,7 +5,7 @@
use std::{pin::Pin, sync::Arc};
-use atuin_client::database::Database;
+use crate::atuin_client::database::Database;
use eyre::Result;
use tokio::sync::RwLock;
use tokio_stream::Stream;
@@ -13,7 +13,7 @@ use tonic::{Request, Response, Status, Streaming};
use tracing::{Level, debug, info, instrument, span, trace};
use uuid::Uuid;
-use crate::{
+use crate::atuin_daemon::{
daemon::{Component, DaemonHandle},
events::DaemonEvent,
search::{
@@ -368,7 +368,7 @@ impl SearchSvc for SearchGrpcService {
/// Convert proto FilterMode and context to IndexFilterMode.
fn convert_filter_mode(
mode: FilterMode,
- context: &Option<crate::search::SearchContext>,
+ context: &Option<crate::atuin_daemon::search::SearchContext>,
) -> IndexFilterMode {
match (mode, context) {
(FilterMode::Global, _) => IndexFilterMode::Global,
diff --git a/crates/atuin-daemon/src/components/semantic.rs b/crates/turtle/src/atuin_daemon/components/semantic.rs
index dff38fd3..a42fd5cb 100644
--- a/crates/atuin-daemon/src/components/semantic.rs
+++ b/crates/turtle/src/atuin_daemon/components/semantic.rs
@@ -8,13 +8,13 @@ use std::collections::{HashMap, VecDeque};
use std::fmt::{Display, Formatter};
use std::sync::Arc;
-use atuin_client::history::{History, HistoryId};
+use crate::atuin_client::history::{History, HistoryId};
use eyre::Result;
use tokio::sync::Mutex;
use tonic::{Request, Response, Status, Streaming};
use tracing::{Level, instrument};
-use crate::{
+use crate::atuin_daemon::{
daemon::{Component, DaemonHandle},
events::DaemonEvent,
semantic::{
@@ -244,7 +244,7 @@ impl SemanticState {
fn command_output_for_ref(
&self,
capture_ref: &CaptureRef,
- ranges: &[crate::semantic::OutputRange],
+ ranges: &[crate::atuin_daemon::semantic::OutputRange],
) -> Option<CommandOutputReply> {
let stored = self
.sessions
@@ -534,14 +534,17 @@ fn command_output_not_found() -> CommandOutputReply {
}
}
-fn select_output_ranges(output: &str, ranges: &[crate::semantic::OutputRange]) -> Vec<OutputLine> {
+fn select_output_ranges(
+ output: &str,
+ ranges: &[crate::atuin_daemon::semantic::OutputRange],
+) -> Vec<OutputLine> {
let lines: Vec<&str> = output.lines().collect();
if lines.is_empty() {
return Vec::new();
}
let ranges = if ranges.is_empty() {
- vec![crate::semantic::OutputRange { start: 0, end: 999 }]
+ vec![crate::atuin_daemon::semantic::OutputRange { start: 0, end: 999 }]
} else {
ranges.to_vec()
};
@@ -816,8 +819,8 @@ mod tests {
fn output_ranges_are_line_based_inclusive_and_support_negative_offsets() {
let output = "zero\none\ntwo\nthree\nfour";
let ranges = vec![
- crate::semantic::OutputRange { start: 1, end: 2 },
- crate::semantic::OutputRange { start: -2, end: -1 },
+ crate::atuin_daemon::semantic::OutputRange { start: 1, end: 2 },
+ crate::atuin_daemon::semantic::OutputRange { start: -2, end: -1 },
];
assert_eq!(
@@ -838,8 +841,8 @@ mod tests {
.collect::<Vec<_>>()
.join("\n");
let ranges = vec![
- crate::semantic::OutputRange { start: 0, end: 100 },
- crate::semantic::OutputRange {
+ crate::atuin_daemon::semantic::OutputRange { start: 0, end: 100 },
+ crate::atuin_daemon::semantic::OutputRange {
start: -100,
end: -1,
},
@@ -856,8 +859,8 @@ mod tests {
fn output_ranges_can_leave_gaps_for_client_formatting() {
let output = "zero\none\ntwo\nthree\nfour";
let ranges = vec![
- crate::semantic::OutputRange { start: 0, end: 1 },
- crate::semantic::OutputRange { start: 4, end: 4 },
+ crate::atuin_daemon::semantic::OutputRange { start: 0, end: 1 },
+ crate::atuin_daemon::semantic::OutputRange { start: 4, end: 4 },
];
assert_eq!(
@@ -888,8 +891,8 @@ mod tests {
fn output_ranges_skip_ranges_fully_outside_output() {
let output = "zero\none\ntwo";
let ranges = vec![
- crate::semantic::OutputRange { start: 10, end: 20 },
- crate::semantic::OutputRange {
+ crate::atuin_daemon::semantic::OutputRange { start: 10, end: 20 },
+ crate::atuin_daemon::semantic::OutputRange {
start: -20,
end: -10,
},
diff --git a/crates/atuin-daemon/src/components/sync.rs b/crates/turtle/src/atuin_daemon/components/sync.rs
index 6e486250..c76fb71b 100644
--- a/crates/atuin-daemon/src/components/sync.rs
+++ b/crates/turtle/src/atuin_daemon/components/sync.rs
@@ -9,9 +9,9 @@ use rand::Rng;
use tokio::sync::mpsc;
use tokio::time::{self, MissedTickBehavior};
-use atuin_client::{history::store::HistoryStore, record::sync, settings::Settings};
+use crate::atuin_client::{history::store::HistoryStore, record::sync, settings::Settings};
-use crate::{
+use crate::atuin_daemon::{
daemon::{Component, DaemonHandle},
events::DaemonEvent,
};
diff --git a/crates/atuin-daemon/src/control/mod.rs b/crates/turtle/src/atuin_daemon/control/mod.rs
index afb29c57..afb29c57 100644
--- a/crates/atuin-daemon/src/control/mod.rs
+++ b/crates/turtle/src/atuin_daemon/control/mod.rs
diff --git a/crates/atuin-daemon/src/control/service.rs b/crates/turtle/src/atuin_daemon/control/service.rs
index 2e7403ce..cb2ff74e 100644
--- a/crates/atuin-daemon/src/control/service.rs
+++ b/crates/turtle/src/atuin_daemon/control/service.rs
@@ -3,7 +3,7 @@
//! This gRPC service allows external processes (like CLI commands) to inject
//! events into the daemon's event bus.
-use atuin_client::history::HistoryId;
+use crate::atuin_client::history::HistoryId;
use tonic::{Request, Response, Status};
use tracing::{Level, info, instrument};
@@ -12,7 +12,7 @@ use super::{
control_server::{Control, ControlServer},
send_event_request::Event,
};
-use crate::{daemon::DaemonHandle, events::DaemonEvent};
+use crate::atuin_daemon::{daemon::DaemonHandle, events::DaemonEvent};
/// The Control gRPC service.
///
diff --git a/crates/atuin-daemon/src/daemon.rs b/crates/turtle/src/atuin_daemon/daemon.rs
index 625ca205..77c0d8a5 100644
--- a/crates/atuin-daemon/src/daemon.rs
+++ b/crates/turtle/src/atuin_daemon/daemon.rs
@@ -10,14 +10,14 @@
use std::sync::Arc;
-use atuin_client::{
+use crate::atuin_client::{
database::Sqlite as HistoryDatabase, encryption, record::sqlite_store::SqliteStore,
settings::Settings,
};
use eyre::{Context, Result};
use tokio::sync::{RwLock, broadcast};
-use crate::events::DaemonEvent;
+use crate::atuin_daemon::events::DaemonEvent;
// ============================================================================
// DaemonState
diff --git a/crates/atuin-daemon/src/events.rs b/crates/turtle/src/atuin_daemon/events.rs
index 4e6c6ff3..9a398925 100644
--- a/crates/atuin-daemon/src/events.rs
+++ b/crates/turtle/src/atuin_daemon/events.rs
@@ -7,8 +7,8 @@
//! External processes (like CLI commands) can also inject events via the
//! Control gRPC service.
-use atuin_client::history::{History, HistoryId};
-use atuin_common::record::RecordId;
+use crate::atuin_client::history::{History, HistoryId};
+use crate::atuin_common::record::RecordId;
/// Events that flow through the daemon's event bus.
///
diff --git a/crates/atuin-daemon/src/history/mod.rs b/crates/turtle/src/atuin_daemon/history/mod.rs
index b71853df..b71853df 100644
--- a/crates/atuin-daemon/src/history/mod.rs
+++ b/crates/turtle/src/atuin_daemon/history/mod.rs
diff --git a/crates/atuin-daemon/src/lib.rs b/crates/turtle/src/atuin_daemon/mod.rs
index 27d3932b..b05eb95c 100644
--- a/crates/atuin-daemon/src/lib.rs
+++ b/crates/turtle/src/atuin_daemon/mod.rs
@@ -1,6 +1,6 @@
-use atuin_client::database::Sqlite as HistoryDatabase;
-use atuin_client::record::sqlite_store::SqliteStore;
-use atuin_client::settings::{Settings, watcher::global_settings_watcher};
+use crate::atuin_client::database::Sqlite as HistoryDatabase;
+use crate::atuin_client::record::sqlite_store::SqliteStore;
+use crate::atuin_client::settings::{Settings, watcher::global_settings_watcher};
use eyre::Result;
pub mod client;
@@ -126,11 +126,3 @@ async fn shutdown_signal() {
_ = int.recv() => {},
}
}
-
-/// Wait for a shutdown signal (Ctrl+C).
-#[cfg(not(unix))]
-async fn shutdown_signal() {
- tokio::signal::ctrl_c()
- .await
- .expect("failed to listen for ctrl+c");
-}
diff --git a/crates/atuin-daemon/src/search/index.rs b/crates/turtle/src/atuin_daemon/search/index.rs
index bb155979..df627e1b 100644
--- a/crates/atuin-daemon/src/search/index.rs
+++ b/crates/turtle/src/atuin_daemon/search/index.rs
@@ -12,8 +12,11 @@ use std::{
sync::Arc,
};
-use atuin_client::history::{History, is_known_agent};
-use atuin_client::settings::Search;
+use crate::atuin_client::settings::Search;
+use crate::{
+ atuin_client::history::{History, is_known_agent},
+ atuin_daemon::components::search::with_trailing_slash,
+};
use atuin_nucleo::{Injector, Nucleo, pattern};
use dashmap::DashMap;
use lasso::{Spur, ThreadedRodeo};
@@ -22,8 +25,6 @@ use tokio::sync::RwLock;
use tracing::{Level, instrument};
use uuid::Uuid;
-use crate::components::search::with_trailing_slash;
-
/// Parse a UUID string into a 16-byte array.
/// Returns None if the string is not a valid UUID.
fn parse_uuid_bytes(s: &str) -> Option<[u8; 16]> {
@@ -491,7 +492,7 @@ mod tests {
#[test]
fn frecency_data_compute() {
- let now = 1000000i64;
+ let now = 1_000_000i64;
// Recent command (with default multipliers of 1.0)
let recent = FrecencyData {
@@ -518,7 +519,7 @@ mod tests {
#[test]
fn frecency_data_compute_with_multipliers() {
- let now = 1000000i64;
+ let now = 1_000_000_i64;
let data = FrecencyData {
count: 5,
diff --git a/crates/atuin-daemon/src/search/mod.rs b/crates/turtle/src/atuin_daemon/search/mod.rs
index 4d261956..4d261956 100644
--- a/crates/atuin-daemon/src/search/mod.rs
+++ b/crates/turtle/src/atuin_daemon/search/mod.rs
diff --git a/crates/atuin-daemon/src/semantic/mod.rs b/crates/turtle/src/atuin_daemon/semantic/mod.rs
index c3511676..c3511676 100644
--- a/crates/atuin-daemon/src/semantic/mod.rs
+++ b/crates/turtle/src/atuin_daemon/semantic/mod.rs
diff --git a/crates/atuin-daemon/src/server.rs b/crates/turtle/src/atuin_daemon/server.rs
index b823cff2..23b04342 100644
--- a/crates/atuin-daemon/src/server.rs
+++ b/crates/turtle/src/atuin_daemon/server.rs
@@ -1,15 +1,15 @@
use eyre::Result;
-use crate::components::history::HistoryGrpcService;
-use crate::components::search::SearchGrpcService;
-use crate::components::semantic::SemanticGrpcService;
-use crate::control::{ControlService, control_server::ControlServer};
-use crate::daemon::DaemonHandle;
-use crate::history::history_server::HistoryServer;
-use crate::search::search_server::SearchServer;
-use crate::semantic::semantic_server::SemanticServer;
+use crate::atuin_daemon::components::history::HistoryGrpcService;
+use crate::atuin_daemon::components::search::SearchGrpcService;
+use crate::atuin_daemon::components::semantic::SemanticGrpcService;
+use crate::atuin_daemon::control::{ControlService, control_server::ControlServer};
+use crate::atuin_daemon::daemon::DaemonHandle;
+use crate::atuin_daemon::history::history_server::HistoryServer;
+use crate::atuin_daemon::search::search_server::SearchServer;
+use crate::atuin_daemon::semantic::semantic_server::SemanticServer;
-use atuin_client::settings::Settings;
+use crate::atuin_client::settings::Settings;
/// Run the gRPC server with the given services.
///
@@ -65,8 +65,6 @@ pub async fn run_grpc_server(
}
(UnixListener::from_std(listener)?, false)
}
- #[cfg(not(target_os = "linux"))]
- unreachable!()
} else {
tracing::info!("listening on unix socket {socket_path:?}");
(UnixListener::bind(socket_path.clone())?, true)
@@ -78,7 +76,7 @@ pub async fn run_grpc_server(
let shutdown_signal = async move {
let mut rx = handle.subscribe();
loop {
- use crate::DaemonEvent;
+ use crate::atuin_daemon::DaemonEvent;
match rx.recv().await {
Ok(DaemonEvent::ShutdownRequested) => break,
@@ -115,56 +113,3 @@ pub async fn run_grpc_server(
Ok(())
}
-
-/// Run the gRPC server with the given services (Windows/TCP version).
-#[cfg(not(unix))]
-pub async fn run_grpc_server(
- settings: Settings,
- history_service: HistoryServer<HistoryGrpcService>,
- search_service: SearchServer<SearchGrpcService>,
- semantic_service: SemanticServer<SemanticGrpcService>,
- control_service: ControlServer<ControlService>,
- handle: DaemonHandle,
-) -> Result<()> {
- use tokio::net::TcpListener;
- use tokio_stream::wrappers::TcpListenerStream;
- use tonic::transport::Server;
-
- let port = settings.daemon.tcp_port;
- let url = format!("127.0.0.1:{port}");
- let tcp = TcpListener::bind(&url).await?;
- let tcp_stream = TcpListenerStream::new(tcp);
-
- tracing::info!("listening on tcp port {:?}", port);
-
- // Create shutdown signal from daemon handle
- let shutdown_signal = async move {
- use crate::DaemonEvent;
-
- let mut rx = handle.subscribe();
- loop {
- match rx.recv().await {
- Ok(DaemonEvent::ShutdownRequested) => break,
- Ok(_) => continue,
- Err(_) => break, // Channel closed
- }
- }
- eprintln!("Shutting down gRPC server...");
- };
-
- // Spawn the server in the background
- tokio::spawn(async move {
- if let Err(e) = Server::builder()
- .add_service(history_service)
- .add_service(search_service)
- .add_service(semantic_service)
- .add_service(control_service)
- .serve_with_incoming_shutdown(tcp_stream, shutdown_signal)
- .await
- {
- tracing::error!("gRPC server error: {e}");
- }
- });
-
- Ok(())
-}