aboutsummaryrefslogtreecommitdiffstats
path: root/crates/turtle/src/atuin_daemon
diff options
context:
space:
mode:
Diffstat (limited to 'crates/turtle/src/atuin_daemon')
-rw-r--r--crates/turtle/src/atuin_daemon/client.rs46
-rw-r--r--crates/turtle/src/atuin_daemon/components/history.rs8
-rw-r--r--crates/turtle/src/atuin_daemon/components/mod.rs16
-rw-r--r--crates/turtle/src/atuin_daemon/components/search.rs12
-rw-r--r--crates/turtle/src/atuin_daemon/components/semantic.rs8
-rw-r--r--crates/turtle/src/atuin_daemon/components/sync.rs4
-rw-r--r--crates/turtle/src/atuin_daemon/control/mod.rs2
-rw-r--r--crates/turtle/src/atuin_daemon/control/service.rs6
-rw-r--r--crates/turtle/src/atuin_daemon/daemon.rs52
-rw-r--r--crates/turtle/src/atuin_daemon/events.rs2
-rw-r--r--crates/turtle/src/atuin_daemon/mod.rs28
-rw-r--r--crates/turtle/src/atuin_daemon/search/index.rs56
-rw-r--r--crates/turtle/src/atuin_daemon/search/mod.rs2
-rw-r--r--crates/turtle/src/atuin_daemon/server.rs2
14 files changed, 122 insertions, 122 deletions
diff --git a/crates/turtle/src/atuin_daemon/client.rs b/crates/turtle/src/atuin_daemon/client.rs
index 45ef19e9..a0a27741 100644
--- a/crates/turtle/src/atuin_daemon/client.rs
+++ b/crates/turtle/src/atuin_daemon/client.rs
@@ -33,12 +33,12 @@ use crate::atuin_daemon::semantic::{
semantic_client::SemanticClient as SemanticServiceClient,
};
-pub struct HistoryClient {
+pub(crate) struct HistoryClient {
client: HistoryServiceClient<Channel>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-pub enum DaemonClientErrorKind {
+pub(crate) enum DaemonClientErrorKind {
Connect,
Unavailable,
Unimplemented,
@@ -46,7 +46,7 @@ pub enum DaemonClientErrorKind {
}
#[must_use]
-pub fn classify_error(error: &eyre::Report) -> DaemonClientErrorKind {
+pub(crate) fn classify_error(error: &eyre::Report) -> DaemonClientErrorKind {
for cause in error.chain() {
if cause.downcast_ref::<tonic::transport::Error>().is_some() {
return DaemonClientErrorKind::Connect;
@@ -67,7 +67,7 @@ pub fn classify_error(error: &eyre::Report) -> DaemonClientErrorKind {
// Wrap the grpc client
impl HistoryClient {
#[cfg(unix)]
- pub async fn new(path: String) -> Result<Self> {
+ pub(crate) async fn new(path: String) -> Result<Self> {
use eyre::Context;
let log_path = path.clone();
@@ -92,7 +92,7 @@ impl HistoryClient {
Ok(HistoryClient { client })
}
- pub async fn start_history(&mut self, h: History) -> Result<StartHistoryReply> {
+ pub(crate) async fn start_history(&mut self, h: History) -> Result<StartHistoryReply> {
let req = StartHistoryRequest {
command: h.command,
cwd: h.cwd,
@@ -106,7 +106,7 @@ impl HistoryClient {
Ok(self.client.start_history(req).await?.into_inner())
}
- pub async fn end_history(
+ pub(crate) async fn end_history(
&mut self,
id: String,
duration: u64,
@@ -117,11 +117,11 @@ impl HistoryClient {
Ok(self.client.end_history(req).await?.into_inner())
}
- pub async fn status(&mut self) -> Result<StatusReply> {
+ pub(crate) async fn status(&mut self) -> Result<StatusReply> {
Ok(self.client.status(StatusRequest {}).await?.into_inner())
}
- pub async fn tail_history(&mut self) -> Result<tonic::Streaming<TailHistoryReply>> {
+ pub(crate) async fn tail_history(&mut self) -> Result<tonic::Streaming<TailHistoryReply>> {
Ok(self
.client
.tail_history(TailHistoryRequest {})
@@ -129,19 +129,19 @@ impl HistoryClient {
.into_inner())
}
- pub async fn shutdown(&mut self) -> Result<bool> {
+ pub(crate) async fn shutdown(&mut self) -> Result<bool> {
let resp = self.client.shutdown(ShutdownRequest {}).await?.into_inner();
Ok(resp.accepted)
}
}
-pub struct SearchClient {
+pub(crate) struct SearchClient {
client: SearchServiceClient<Channel>,
}
impl SearchClient {
#[cfg(unix)]
- pub async fn new(path: String) -> Result<Self> {
+ pub(crate) async fn new(path: String) -> Result<Self> {
let log_path = path.clone();
let channel = Endpoint::try_from("http://atuin_local_daemon:0")?
.connect_with_connector(service_fn(move |_: Uri| {
@@ -165,7 +165,7 @@ impl SearchClient {
}
#[instrument(skip_all, level = Level::TRACE, name = "daemon_client_search", fields(query = %query, query_id = query_id))]
- pub async fn search(
+ pub(crate) async fn search(
&mut self,
query: String,
query_id: u64,
@@ -214,13 +214,13 @@ impl From<Context> for RpcSearchContext {
}
}
-pub struct SemanticClient {
+pub(crate) struct SemanticClient {
client: SemanticServiceClient<Channel>,
}
impl SemanticClient {
#[cfg(unix)]
- pub async fn new(path: String) -> Result<Self> {
+ pub(crate) async fn new(path: String) -> Result<Self> {
let log_path = path.clone();
let channel = Endpoint::try_from("http://atuin_local_daemon:0")?
.connect_with_connector(service_fn(move |_: Uri| {
@@ -244,11 +244,11 @@ impl SemanticClient {
}
#[cfg(unix)]
- pub async fn from_settings(settings: &Settings) -> Result<Self> {
+ pub(crate) async fn from_settings(settings: &Settings) -> Result<Self> {
Self::new(settings.daemon.socket_path.clone()).await
}
- pub async fn record_commands(
+ pub(crate) async fn record_commands(
&mut self,
captures: Vec<CommandCapture>,
) -> Result<RecordCommandsReply> {
@@ -256,7 +256,7 @@ impl SemanticClient {
Ok(self.client.record_commands(stream).await?.into_inner())
}
- pub async fn command_output(
+ pub(crate) async fn command_output(
&mut self,
history_id: String,
ranges: Vec<(i64, i64)>,
@@ -280,14 +280,14 @@ impl SemanticClient {
/// Client for the Control gRPC service.
///
/// Used to inject events into a running daemon from external processes.
-pub struct ControlClient {
+pub(crate) struct ControlClient {
client: ControlServiceClient<Channel>,
}
impl ControlClient {
/// Connect to the daemon's control service.
#[cfg(unix)]
- pub async fn new(path: String) -> Result<Self> {
+ pub(crate) async fn new(path: String) -> Result<Self> {
let log_path = path.clone();
let channel = Endpoint::try_from("http://atuin_local_daemon:0")?
.connect_with_connector(service_fn(move |_: Uri| {
@@ -312,12 +312,12 @@ impl ControlClient {
/// Connect using settings.
#[cfg(unix)]
- pub async fn from_settings(settings: &Settings) -> Result<Self> {
+ pub(crate) async fn from_settings(settings: &Settings) -> Result<Self> {
Self::new(settings.daemon.socket_path.clone()).await
}
/// Send an event to the daemon.
- pub async fn send_event(&mut self, event: DaemonEvent) -> Result<()> {
+ pub(crate) async fn send_event(&mut self, event: DaemonEvent) -> Result<()> {
let proto_event = daemon_event_to_proto(event);
let request = SendEventRequest {
event: Some(proto_event),
@@ -377,7 +377,7 @@ fn daemon_event_to_proto(
/// // Request immediate sync
/// emit_event(DaemonEvent::ForceSync).await?;
/// ```
-pub async fn emit_event(event: DaemonEvent) -> Result<()> {
+pub(crate) async fn emit_event(event: DaemonEvent) -> Result<()> {
emit_event_with_settings(event, None).await
}
@@ -385,7 +385,7 @@ pub async fn emit_event(event: DaemonEvent) -> Result<()> {
///
/// If settings are not provided, they will be loaded from the default location.
/// If the daemon isn't running, this will silently succeed.
-pub async fn emit_event_with_settings(
+pub(crate) async fn emit_event_with_settings(
event: DaemonEvent,
settings: Option<&Settings>,
) -> Result<()> {
diff --git a/crates/turtle/src/atuin_daemon/components/history.rs b/crates/turtle/src/atuin_daemon/components/history.rs
index 95d34b69..ec41977f 100644
--- a/crates/turtle/src/atuin_daemon/components/history.rs
+++ b/crates/turtle/src/atuin_daemon/components/history.rs
@@ -36,7 +36,7 @@ const DAEMON_PROTOCOL_VERSION: u32 = 1;
/// - Saves completed commands to the database and record store
/// - Emits history events for other components (e.g., search indexing)
/// - Provides the History gRPC service
-pub struct HistoryComponent {
+pub(crate) struct HistoryComponent {
inner: Arc<HistoryComponentInner>,
}
@@ -53,7 +53,7 @@ struct HistoryComponentInner {
impl HistoryComponent {
/// Create a new history component.
- pub fn new() -> Self {
+ pub(crate) fn new() -> Self {
Self {
inner: Arc::new(HistoryComponentInner {
running: DashMap::new(),
@@ -66,7 +66,7 @@ impl HistoryComponent {
/// Get the gRPC service for this component.
///
/// This returns a tonic service that can be added to a gRPC server.
- pub fn grpc_service(&self) -> HistoryServer<HistoryGrpcService> {
+ pub(crate) fn grpc_service(&self) -> HistoryServer<HistoryGrpcService> {
HistoryServer::new(HistoryGrpcService {
inner: self.inner.clone(),
})
@@ -112,7 +112,7 @@ impl Component for HistoryComponent {
/// The gRPC service implementation.
///
/// This is a thin wrapper that delegates to the component's shared state.
-pub struct HistoryGrpcService {
+pub(crate) struct HistoryGrpcService {
inner: Arc<HistoryComponentInner>,
}
diff --git a/crates/turtle/src/atuin_daemon/components/mod.rs b/crates/turtle/src/atuin_daemon/components/mod.rs
index 447e31df..5a93fbc1 100644
--- a/crates/turtle/src/atuin_daemon/components/mod.rs
+++ b/crates/turtle/src/atuin_daemon/components/mod.rs
@@ -14,12 +14,12 @@
//! - [`semantic::SemanticComponent`]: In-memory semantic command captures
//! - [`sync::SyncComponent`]: Cloud sync
-pub mod history;
-pub mod search;
-pub mod semantic;
-pub mod sync;
+pub(crate) mod history;
+pub(crate) mod search;
+pub(crate) mod semantic;
+pub(crate) mod sync;
-pub use history::HistoryComponent;
-pub use search::SearchComponent;
-pub use semantic::SemanticComponent;
-pub use sync::SyncComponent;
+pub(crate) use history::HistoryComponent;
+pub(crate) use search::SearchComponent;
+pub(crate) use semantic::SemanticComponent;
+pub(crate) use sync::SyncComponent;
diff --git a/crates/turtle/src/atuin_daemon/components/search.rs b/crates/turtle/src/atuin_daemon/components/search.rs
index 85191cff..17decdad 100644
--- a/crates/turtle/src/atuin_daemon/components/search.rs
+++ b/crates/turtle/src/atuin_daemon/components/search.rs
@@ -34,7 +34,7 @@ const FRECENCY_REFRESH_INTERVAL_SECS: u64 = 60;
/// - Loads history from the database on startup
/// - Updates the index when history events occur
/// - Provides the Search gRPC service
-pub struct SearchComponent {
+pub(crate) struct SearchComponent {
index: Arc<RwLock<SearchIndex>>,
handle: tokio::sync::RwLock<Option<DaemonHandle>>,
loader_handle: Option<tokio::task::JoinHandle<()>>,
@@ -43,7 +43,7 @@ pub struct SearchComponent {
impl SearchComponent {
/// Create a new search component.
- pub fn new() -> Self {
+ pub(crate) fn new() -> Self {
Self {
index: Arc::new(RwLock::new(SearchIndex::new())),
handle: tokio::sync::RwLock::new(None),
@@ -53,7 +53,7 @@ impl SearchComponent {
}
/// Get the gRPC service for this component.
- pub fn grpc_service(&self) -> SearchServer<SearchGrpcService> {
+ pub(crate) fn grpc_service(&self) -> SearchServer<SearchGrpcService> {
SearchServer::new(SearchGrpcService {
index: self.index.clone(),
})
@@ -273,7 +273,7 @@ impl Component for SearchComponent {
}
/// The gRPC service implementation.
-pub struct SearchGrpcService {
+pub(crate) struct SearchGrpcService {
index: Arc<RwLock<SearchIndex>>,
}
@@ -395,7 +395,7 @@ fn convert_filter_mode(
}
#[cfg(windows)]
-pub fn with_trailing_slash(s: &str) -> String {
+pub(crate) fn with_trailing_slash(s: &str) -> String {
if s.ends_with('\\') {
s.to_string()
} else {
@@ -404,7 +404,7 @@ pub fn with_trailing_slash(s: &str) -> String {
}
#[cfg(not(windows))]
-pub fn with_trailing_slash(s: &str) -> String {
+pub(crate) fn with_trailing_slash(s: &str) -> String {
if s.ends_with('/') {
s.to_string()
} else {
diff --git a/crates/turtle/src/atuin_daemon/components/semantic.rs b/crates/turtle/src/atuin_daemon/components/semantic.rs
index a42fd5cb..052c2d73 100644
--- a/crates/turtle/src/atuin_daemon/components/semantic.rs
+++ b/crates/turtle/src/atuin_daemon/components/semantic.rs
@@ -29,7 +29,7 @@ const MAX_BYTES_PER_SESSION: usize = 32 * 1024 * 1024;
const MAX_PENDING_HISTORIES: usize = 128;
/// Stores completed command captures and associates them with history events.
-pub struct SemanticComponent {
+pub(crate) struct SemanticComponent {
inner: Arc<SemanticComponentInner>,
}
@@ -83,7 +83,7 @@ struct SemanticCommandRecord {
}
impl SemanticComponent {
- pub fn new() -> Self {
+ pub(crate) fn new() -> Self {
Self {
inner: Arc::new(SemanticComponentInner {
state: Mutex::new(SemanticState::default()),
@@ -91,7 +91,7 @@ impl SemanticComponent {
}
}
- pub fn grpc_service(&self) -> SemanticServer<SemanticGrpcService> {
+ pub(crate) fn grpc_service(&self) -> SemanticServer<SemanticGrpcService> {
SemanticServer::new(SemanticGrpcService {
inner: self.inner.clone(),
})
@@ -452,7 +452,7 @@ impl Display for SessionId {
}
}
-pub struct SemanticGrpcService {
+pub(crate) struct SemanticGrpcService {
inner: Arc<SemanticComponentInner>,
}
diff --git a/crates/turtle/src/atuin_daemon/components/sync.rs b/crates/turtle/src/atuin_daemon/components/sync.rs
index c76fb71b..93d1024a 100644
--- a/crates/turtle/src/atuin_daemon/components/sync.rs
+++ b/crates/turtle/src/atuin_daemon/components/sync.rs
@@ -41,14 +41,14 @@ enum SyncState {
/// - Implements exponential backoff on sync failures
/// - Responds to ForceSync events for immediate sync
/// - Emits SyncCompleted/SyncFailed events
-pub struct SyncComponent {
+pub(crate) struct SyncComponent {
task_handle: Option<tokio::task::JoinHandle<()>>,
command_tx: Option<mpsc::Sender<SyncCommand>>,
}
impl SyncComponent {
/// Create a new sync component.
- pub fn new() -> Self {
+ pub(crate) fn new() -> Self {
Self {
task_handle: None,
command_tx: None,
diff --git a/crates/turtle/src/atuin_daemon/control/mod.rs b/crates/turtle/src/atuin_daemon/control/mod.rs
index afb29c57..23068519 100644
--- a/crates/turtle/src/atuin_daemon/control/mod.rs
+++ b/crates/turtle/src/atuin_daemon/control/mod.rs
@@ -9,4 +9,4 @@ mod service;
tonic::include_proto!("control");
// Re-export the service
-pub use service::ControlService;
+pub(crate) use service::ControlService;
diff --git a/crates/turtle/src/atuin_daemon/control/service.rs b/crates/turtle/src/atuin_daemon/control/service.rs
index cb2ff74e..8061a3c2 100644
--- a/crates/turtle/src/atuin_daemon/control/service.rs
+++ b/crates/turtle/src/atuin_daemon/control/service.rs
@@ -18,18 +18,18 @@ use crate::atuin_daemon::{daemon::DaemonHandle, events::DaemonEvent};
///
/// This service is used by external processes to inject events into the daemon.
/// It's not a component - it's part of the daemon's core infrastructure.
-pub struct ControlService {
+pub(crate) struct ControlService {
handle: DaemonHandle,
}
impl ControlService {
/// Create a new control service with the given daemon handle.
- pub fn new(handle: DaemonHandle) -> Self {
+ pub(crate) fn new(handle: DaemonHandle) -> Self {
Self { handle }
}
/// Get a tonic server for this service.
- pub fn into_server(self) -> ControlServer<Self> {
+ pub(crate) fn into_server(self) -> ControlServer<Self> {
ControlServer::new(self)
}
}
diff --git a/crates/turtle/src/atuin_daemon/daemon.rs b/crates/turtle/src/atuin_daemon/daemon.rs
index 77c0d8a5..3268548e 100644
--- a/crates/turtle/src/atuin_daemon/daemon.rs
+++ b/crates/turtle/src/atuin_daemon/daemon.rs
@@ -27,7 +27,7 @@ use crate::atuin_daemon::events::DaemonEvent;
///
/// This contains all the resources that components and services need access to.
/// The state is wrapped in an `Arc` and accessed via [`DaemonHandle`].
-pub struct DaemonState {
+pub(crate) struct DaemonState {
// Event bus
event_tx: broadcast::Sender<DaemonEvent>,
@@ -72,7 +72,7 @@ pub struct DaemonState {
/// let history = handle.history_db().load(id).await?;
/// ```
#[derive(Clone)]
-pub struct DaemonHandle {
+pub(crate) struct DaemonHandle {
state: Arc<DaemonState>,
}
@@ -83,7 +83,7 @@ impl DaemonHandle {
///
/// This is fire-and-forget - if no receivers are listening (which shouldn't
/// happen in normal operation), the event is dropped silently.
- pub fn emit(&self, event: DaemonEvent) {
+ pub(crate) fn emit(&self, event: DaemonEvent) {
if let Err(e) = self.state.event_tx.send(event) {
tracing::warn!("failed to emit event (no receivers?): {e}");
}
@@ -94,12 +94,12 @@ impl DaemonHandle {
/// Returns a receiver that will receive all events emitted after this call.
/// Useful for components that need to listen for events outside of the
/// normal `handle_event` callback flow.
- pub fn subscribe(&self) -> broadcast::Receiver<DaemonEvent> {
+ pub(crate) fn subscribe(&self) -> broadcast::Receiver<DaemonEvent> {
self.state.event_tx.subscribe()
}
/// Request graceful shutdown of the daemon.
- pub fn shutdown(&self) {
+ pub(crate) fn shutdown(&self) {
self.emit(DaemonEvent::ShutdownRequested);
}
@@ -109,7 +109,7 @@ impl DaemonHandle {
///
/// This acquires a read lock on the settings. For most use cases, clone
/// the settings if you need to hold onto them.
- pub async fn settings(&self) -> tokio::sync::RwLockReadGuard<'_, Settings> {
+ pub(crate) async fn settings(&self) -> tokio::sync::RwLockReadGuard<'_, Settings> {
self.state.settings.read().await
}
@@ -117,7 +117,7 @@ impl DaemonHandle {
///
/// Components listening for `SettingsReloaded` can then re-read settings
/// via `handle.settings()` to pick up the changes.
- pub async fn reload_settings(&self) -> Result<()> {
+ pub(crate) async fn reload_settings(&self) -> Result<()> {
let new_settings = Settings::new()?;
self.apply_settings(new_settings).await;
Ok(())
@@ -127,26 +127,26 @@ impl DaemonHandle {
///
/// Use this when settings have already been loaded (e.g., from a file watcher)
/// to avoid parsing the config file twice.
- pub async fn apply_settings(&self, settings: Settings) {
+ pub(crate) async fn apply_settings(&self, settings: Settings) {
*self.state.settings.write().await = settings;
self.emit(DaemonEvent::SettingsReloaded);
tracing::info!("settings applied");
}
/// Get the encryption key.
- pub fn encryption_key(&self) -> &[u8; 32] {
+ pub(crate) fn encryption_key(&self) -> &[u8; 32] {
&self.state.encryption_key
}
// ---- Database ----
/// Get a reference to the history database.
- pub fn history_db(&self) -> &HistoryDatabase {
+ pub(crate) fn history_db(&self) -> &HistoryDatabase {
&self.state.history_db
}
/// Get a reference to the record store.
- pub fn store(&self) -> &SqliteStore {
+ pub(crate) fn store(&self) -> &SqliteStore {
&self.state.store
}
}
@@ -181,7 +181,7 @@ impl std::fmt::Debug for DaemonHandle {
/// # Example
///
/// ```ignore
-/// pub struct MyComponent {
+/// pub(crate) struct MyComponent {
/// handle: Option<DaemonHandle>,
/// }
///
@@ -213,7 +213,7 @@ impl std::fmt::Debug for DaemonHandle {
/// }
/// ```
#[tonic::async_trait]
-pub trait Component: Send + Sync {
+pub(crate) trait Component: Send + Sync {
/// Human-readable name for logging and debugging.
fn name(&self) -> &'static str;
@@ -257,21 +257,21 @@ pub trait Component: Send + Sync {
///
/// Events emitted during handling are queued and processed in subsequent
/// iterations, ensuring the loop eventually drains.
-pub struct Daemon {
+pub(crate) struct Daemon {
components: Vec<Box<dyn Component>>,
handle: DaemonHandle,
}
impl Daemon {
/// Create a new daemon builder.
- pub fn builder(settings: Settings) -> DaemonBuilder {
+ pub(crate) fn builder(settings: Settings) -> DaemonBuilder {
DaemonBuilder::new(settings)
}
/// Get a clone of the daemon handle.
///
/// The handle can be used to emit events, access settings, etc.
- pub fn handle(&self) -> DaemonHandle {
+ pub(crate) fn handle(&self) -> DaemonHandle {
self.handle.clone()
}
@@ -279,7 +279,7 @@ impl Daemon {
///
/// This must be called before `run_event_loop()`. It initializes all
/// registered components with the daemon handle.
- pub async fn start_components(&mut self) -> Result<()> {
+ pub(crate) async fn start_components(&mut self) -> Result<()> {
for component in &mut self.components {
tracing::info!(component = component.name(), "starting component");
component
@@ -294,7 +294,7 @@ impl Daemon {
///
/// This processes events until a ShutdownRequested event is received.
/// Components must be started first via `start_components()`.
- pub async fn run_event_loop(&mut self) -> Result<()> {
+ pub(crate) async fn run_event_loop(&mut self) -> Result<()> {
let mut event_rx = self.handle.subscribe();
loop {
match event_rx.recv().await {
@@ -324,7 +324,7 @@ impl Daemon {
/// Stop all components.
///
/// This performs graceful shutdown of all components.
- pub async fn stop_components(&mut self) {
+ pub(crate) async fn stop_components(&mut self) {
for component in &mut self.components {
tracing::info!(component = component.name(), "stopping component");
if let Err(e) = component.stop().await {
@@ -342,7 +342,7 @@ impl 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 async fn run(mut self) -> Result<()> {
+ pub(crate) async fn run(mut self) -> Result<()> {
self.start_components().await?;
self.run_event_loop().await?;
self.stop_components().await;
@@ -383,7 +383,7 @@ impl Daemon {
///
/// daemon.run().await?;
/// ```
-pub struct DaemonBuilder {
+pub(crate) struct DaemonBuilder {
settings: Settings,
store: Option<SqliteStore>,
history_db: Option<HistoryDatabase>,
@@ -392,7 +392,7 @@ pub struct DaemonBuilder {
impl DaemonBuilder {
/// Create a new daemon builder with the given settings.
- pub fn new(settings: Settings) -> Self {
+ pub(crate) fn new(settings: Settings) -> Self {
Self {
settings,
store: None,
@@ -402,13 +402,13 @@ impl DaemonBuilder {
}
/// Set the record store.
- pub fn store(mut self, store: SqliteStore) -> Self {
+ pub(crate) fn store(mut self, store: SqliteStore) -> Self {
self.store = Some(store);
self
}
/// Set the history database.
- pub fn history_db(mut self, db: HistoryDatabase) -> Self {
+ pub(crate) fn history_db(mut self, db: HistoryDatabase) -> Self {
self.history_db = Some(db);
self
}
@@ -416,7 +416,7 @@ impl DaemonBuilder {
/// Register a component.
///
/// Components are started in registration order and stopped in reverse order.
- pub fn component(mut self, component: impl Component + 'static) -> Self {
+ pub(crate) fn component(mut self, component: impl Component + 'static) -> Self {
self.components.push(Box::new(component));
self
}
@@ -424,7 +424,7 @@ impl DaemonBuilder {
/// Build the daemon.
///
/// This loads the encryption key and creates the daemon state.
- pub async fn build(self) -> Result<Daemon> {
+ pub(crate) async 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/events.rs b/crates/turtle/src/atuin_daemon/events.rs
index 9a398925..09369512 100644
--- a/crates/turtle/src/atuin_daemon/events.rs
+++ b/crates/turtle/src/atuin_daemon/events.rs
@@ -15,7 +15,7 @@ use crate::atuin_common::record::RecordId;
/// Events are broadcast to all components. Each component decides which
/// events it cares about in its `handle_event` implementation.
#[derive(Debug, Clone)]
-pub enum DaemonEvent {
+pub(crate) enum DaemonEvent {
// ---- History lifecycle ----
/// A command has started running.
HistoryStarted(History),
diff --git a/crates/turtle/src/atuin_daemon/mod.rs b/crates/turtle/src/atuin_daemon/mod.rs
index aff33307..eac28f78 100644
--- a/crates/turtle/src/atuin_daemon/mod.rs
+++ b/crates/turtle/src/atuin_daemon/mod.rs
@@ -3,31 +3,31 @@ use crate::atuin_client::record::sqlite_store::SqliteStore;
use crate::atuin_client::settings::{Settings, watcher::global_settings_watcher};
use eyre::Result;
-pub mod client;
-pub mod components;
-pub mod control;
-pub mod daemon;
-pub mod events;
-pub mod history;
-pub mod search;
-pub mod semantic;
-pub mod server;
+pub(crate) mod client;
+pub(crate) mod components;
+pub(crate) mod control;
+pub(crate) mod daemon;
+pub(crate) mod events;
+pub(crate) mod history;
+pub(crate) mod search;
+pub(crate) mod semantic;
+pub(crate) mod server;
// Re-export core daemon types for convenience
-pub use daemon::Daemon;
-pub use events::DaemonEvent;
+pub(crate) use daemon::Daemon;
+pub(crate) use events::DaemonEvent;
// Re-export components
-pub use components::{HistoryComponent, SearchComponent, SemanticComponent, SyncComponent};
+pub(crate) use components::{HistoryComponent, SearchComponent, SemanticComponent, SyncComponent};
// Re-export client helpers
-pub use client::SemanticClient;
+pub(crate) use client::SemanticClient;
/// Boot the daemon using the new component-based architecture.
///
/// This creates a daemon with the standard components (history, search, sync),
/// starts the gRPC server with their services, and runs the event loop.
-pub async fn boot(
+pub(crate) async fn boot(
settings: Settings,
store: SqliteStore,
history_db: HistoryDatabase,
diff --git a/crates/turtle/src/atuin_daemon/search/index.rs b/crates/turtle/src/atuin_daemon/search/index.rs
index df627e1b..446d7992 100644
--- a/crates/turtle/src/atuin_daemon/search/index.rs
+++ b/crates/turtle/src/atuin_daemon/search/index.rs
@@ -38,16 +38,16 @@ fn format_uuid_bytes(bytes: &[u8; 16]) -> String {
/// Pre-computed frecency data for O(1) lookup.
#[derive(Debug, Clone, Default)]
-pub struct FrecencyData {
+pub(crate) struct FrecencyData {
/// Total number of times this command was used.
- pub count: u32,
+ pub(crate) count: u32,
/// Most recent usage timestamp (unix seconds).
- pub last_used: i64,
+ pub(crate) last_used: i64,
}
impl FrecencyData {
/// Record a new usage of this command.
- pub fn record_use(&mut self, timestamp: i64) {
+ pub(crate) fn record_use(&mut self, timestamp: i64) {
self.count += 1;
if timestamp > self.last_used {
self.last_used = timestamp;
@@ -66,7 +66,7 @@ impl FrecencyData {
/// A multiplier of 0.0 disables that component, 1.0 is unchanged, 2.0 doubles weight.
/// Values like 0.5 reduce weight by half, 1.5 increases by 50%, etc.
#[instrument(level = tracing::Level::TRACE, name = "index_frecency_compute")]
- pub fn compute(&self, now: i64, recency_mul: f64, frequency_mul: f64) -> u32 {
+ pub(crate) fn compute(&self, now: i64, recency_mul: f64, frequency_mul: f64) -> u32 {
if self.count == 0 {
return 0;
}
@@ -99,13 +99,13 @@ impl FrecencyData {
}
/// Data for a unique command.
-pub struct CommandData {
+pub(crate) struct CommandData {
/// History ID of the most recent invocation (16-byte UUID).
most_recent_id: [u8; 16],
/// Timestamp of the most recent invocation.
most_recent_timestamp: i64,
/// Pre-computed global frecency.
- pub global_frecency: FrecencyData,
+ pub(crate) global_frecency: FrecencyData,
// Pre-computed indexes for O(1) filter lookups
// Using HashSet instead of DashSet since CommandData lives inside DashMap (already synchronized)
@@ -120,7 +120,7 @@ pub struct CommandData {
impl CommandData {
/// Create a new CommandData from a history entry.
/// Returns None if the history entry has invalid UUIDs.
- pub fn new(history: &History, interner: &ThreadedRodeo) -> Option<Self> {
+ pub(crate) fn new(history: &History, interner: &ThreadedRodeo) -> Option<Self> {
let history_id = parse_uuid_bytes(&history.id.0)?;
let session = parse_uuid_bytes(&history.session)?;
let timestamp = history.timestamp.unix_timestamp();
@@ -152,7 +152,7 @@ impl CommandData {
/// Add an invocation from a history entry.
/// Returns false if the history entry has invalid UUIDs.
- pub fn add_invocation(&mut self, history: &History, interner: &ThreadedRodeo) -> bool {
+ pub(crate) fn add_invocation(&mut self, history: &History, interner: &ThreadedRodeo) -> bool {
let Some(history_id) = parse_uuid_bytes(&history.id.0) else {
return false;
};
@@ -181,13 +181,13 @@ impl CommandData {
}
/// Get the most recent history ID for this command.
- pub fn most_recent_id(&self) -> String {
+ pub(crate) fn most_recent_id(&self) -> String {
format_uuid_bytes(&self.most_recent_id)
}
/// Check if any invocation matches a directory filter (exact match).
/// O(1) lookup using pre-computed index.
- pub fn has_invocation_in_dir(&self, dir: &str, interner: &ThreadedRodeo) -> bool {
+ pub(crate) fn has_invocation_in_dir(&self, dir: &str, interner: &ThreadedRodeo) -> bool {
interner
.get(dir)
.is_some_and(|spur| self.directories.contains(&spur))
@@ -195,7 +195,7 @@ impl CommandData {
/// Check if any invocation matches a directory prefix (workspace/git root).
/// O(n) where n = number of unique directories for this command.
- pub fn has_invocation_in_workspace(&self, prefix: &str, interner: &ThreadedRodeo) -> bool {
+ pub(crate) fn has_invocation_in_workspace(&self, prefix: &str, interner: &ThreadedRodeo) -> bool {
self.directories
.iter()
.any(|&spur| interner.resolve(&spur).starts_with(prefix))
@@ -203,7 +203,7 @@ impl CommandData {
/// Check if any invocation matches a hostname.
/// O(1) lookup using pre-computed index.
- pub fn has_invocation_on_host(&self, hostname: &str, interner: &ThreadedRodeo) -> bool {
+ pub(crate) fn has_invocation_on_host(&self, hostname: &str, interner: &ThreadedRodeo) -> bool {
interner
.get(hostname)
.is_some_and(|spur| self.hosts.contains(&spur))
@@ -211,14 +211,14 @@ impl CommandData {
/// Check if any invocation matches a session.
/// O(1) lookup using pre-computed index.
- pub fn has_invocation_in_session(&self, session: &str) -> bool {
+ pub(crate) fn has_invocation_in_session(&self, session: &str) -> bool {
parse_uuid_bytes(session).is_some_and(|bytes| self.sessions.contains(&bytes))
}
}
/// Filter mode for search queries.
#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum IndexFilterMode {
+pub(crate) enum IndexFilterMode {
/// No filtering - search all commands.
Global,
/// Filter to commands run in a specific directory.
@@ -233,11 +233,11 @@ pub enum IndexFilterMode {
/// Context for search queries.
#[derive(Debug, Clone, Default)]
-pub struct QueryContext {
- pub cwd: Option<String>,
- pub git_root: Option<String>,
- pub hostname: Option<String>,
- pub session_id: Option<String>,
+pub(crate) struct QueryContext {
+ pub(crate) cwd: Option<String>,
+ pub(crate) git_root: Option<String>,
+ pub(crate) hostname: Option<String>,
+ pub(crate) session_id: Option<String>,
}
/// Shareable frecency map: command -> frecency score.
@@ -252,7 +252,7 @@ type FrecencyMap = Arc<HashMap<Arc<str>, u32>>;
/// Global frecency is precomputed by a background task and used for scoring.
/// If frecency data is not available, search still works but without frecency ranking;
/// although this should never happen due to precomputing the frecency map.
-pub struct SearchIndex {
+pub(crate) struct SearchIndex {
/// Map from command text to command data.
/// Using DashMap for concurrent read/write access, wrapped in Arc for sharing with scorer.
/// Keys are Arc<str> to enable zero-copy sharing with frecency_map.
@@ -269,7 +269,7 @@ pub struct SearchIndex {
impl SearchIndex {
/// Create a new empty search index.
- pub fn new() -> Self {
+ pub(crate) fn new() -> Self {
let nucleo_config = atuin_nucleo::Config::DEFAULT;
// Single column for command text
let nucleo = Nucleo::<String>::new(nucleo_config, Arc::new(|| {}), None, 1);
@@ -288,7 +288,7 @@ impl SearchIndex {
///
/// If the command already exists, updates its invocation data.
/// If it's a new command, adds it to both the map and Nucleo.
- pub fn add_history(&self, history: &History) {
+ pub(crate) fn add_history(&self, history: &History) {
if is_known_agent(&history.author) {
return;
}
@@ -315,19 +315,19 @@ impl SearchIndex {
}
/// Add multiple history entries to the index.
- pub fn add_histories(&self, histories: &[History]) {
+ pub(crate) fn add_histories(&self, histories: &[History]) {
for history in histories {
self.add_history(history);
}
}
/// Get the number of unique commands in the index.
- pub fn command_count(&self) -> usize {
+ pub(crate) fn command_count(&self) -> usize {
self.commands.len()
}
/// Get the number of items in Nucleo (should match command_count).
- pub async fn nucleo_item_count(&self) -> u32 {
+ pub(crate) async fn nucleo_item_count(&self) -> u32 {
self.nucleo.read().await.snapshot().item_count()
}
@@ -336,7 +336,7 @@ impl SearchIndex {
/// 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))]
- pub async fn search(
+ pub(crate) async fn search(
&self,
query: &str,
filter_mode: IndexFilterMode,
@@ -398,7 +398,7 @@ impl SearchIndex {
/// - `frequency_score_multiplier`: Weight for frequency component
/// - `frecency_score_multiplier`: Overall multiplier for final score
#[instrument(skip_all, level = tracing::Level::DEBUG, name = "rebuild_frecency")]
- pub async fn rebuild_frecency(&self, search_settings: &Search) {
+ pub(crate) async fn rebuild_frecency(&self, search_settings: &Search) {
let now = OffsetDateTime::now_utc().unix_timestamp();
let mut frecency_map: HashMap<Arc<str>, u32> = HashMap::new();
diff --git a/crates/turtle/src/atuin_daemon/search/mod.rs b/crates/turtle/src/atuin_daemon/search/mod.rs
index 4d261956..51b6c6cc 100644
--- a/crates/turtle/src/atuin_daemon/search/mod.rs
+++ b/crates/turtle/src/atuin_daemon/search/mod.rs
@@ -8,4 +8,4 @@ mod index;
tonic::include_proto!("search");
// Re-export the service and index
-pub use index::{IndexFilterMode, QueryContext, SearchIndex};
+pub(crate) use index::{IndexFilterMode, QueryContext, SearchIndex};
diff --git a/crates/turtle/src/atuin_daemon/server.rs b/crates/turtle/src/atuin_daemon/server.rs
index 23b04342..65272d2a 100644
--- a/crates/turtle/src/atuin_daemon/server.rs
+++ b/crates/turtle/src/atuin_daemon/server.rs
@@ -16,7 +16,7 @@ use crate::atuin_client::settings::Settings;
/// This starts the gRPC server in the background and returns immediately.
/// The server will shut down when a ShutdownRequested event is received.
#[cfg(unix)]
-pub async fn run_grpc_server(
+pub(crate) async fn run_grpc_server(
settings: Settings,
history_service: HistoryServer<HistoryGrpcService>,
search_service: SearchServer<SearchGrpcService>,