aboutsummaryrefslogtreecommitdiffstats
path: root/crates/daemon/src/api/server
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-07-20 17:54:34 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-07-20 17:54:34 +0200
commit6bd2b80be51a8623640fbd77afa1da09289e40cc (patch)
tree8fa76fc78e27a4f3d6f57af07805a83e9877f0ad /crates/daemon/src/api/server
parentchore: Commit (diff)
downloadatuin-6bd2b80be51a8623640fbd77afa1da09289e40cc.zip
chore: All compiles
Diffstat (limited to '')
-rw-r--r--crates/daemon/src/api/server/control.rs18
-rw-r--r--crates/daemon/src/api/server/history.rs88
2 files changed, 77 insertions, 29 deletions
diff --git a/crates/daemon/src/api/server/control.rs b/crates/daemon/src/api/server/control.rs
index 8d1ec7b8..a5e26355 100644
--- a/crates/daemon/src/api/server/control.rs
+++ b/crates/daemon/src/api/server/control.rs
@@ -11,7 +11,7 @@ use crate::{
api::{
DAEMON_PROTOCOL_VERSION, DAEMON_VERSION,
generated::control::{
- ForceSyncReply, ForceSyncRequest, StatusReply, StatusRequest,
+ ForceSyncReply, ForceSyncRequest, PathsReply, PathsRequest, StatusReply, StatusRequest,
control_server::{Control, ControlServer},
},
},
@@ -58,6 +58,22 @@ impl ControlService {
#[tonic::async_trait]
impl Control for ControlService {
#[instrument(skip_all, level = Level::INFO)]
+ async fn paths(&self, _request: Request<PathsRequest>) -> Result<Response<PathsReply>, Status> {
+ let settings = self.handle.settings().await;
+
+ let config = Settings::get_config_path()
+ .map_err(|e| Status::internal(format!("failed to get settings path: {e:?}")))?;
+
+ let reply = PathsReply {
+ config: config.to_string_lossy().to_string(),
+ db: settings.db_path.clone(),
+ socket: settings.daemon.socket_path.clone(),
+ };
+
+ Ok(Response::new(reply))
+ }
+
+ #[instrument(skip_all, level = Level::INFO)]
async fn status(
&self,
_request: Request<StatusRequest>,
diff --git a/crates/daemon/src/api/server/history.rs b/crates/daemon/src/api/server/history.rs
index 989c7895..0edf3b94 100644
--- a/crates/daemon/src/api/server/history.rs
+++ b/crates/daemon/src/api/server/history.rs
@@ -9,14 +9,16 @@ use tracing::{Level, instrument};
use crate::{
aclient::{
+ database::{ClientSqlite, current_context},
history::{History, HistoryId, store::HistoryStore},
settings::Settings,
},
api::{
DAEMON_PROTOCOL_VERSION,
generated::history::{
- EndHistoryReply, EndHistoryRequest, HistoryEntry, HistoryEventKind, StartHistoryReply,
- StartHistoryRequest, TailHistoryReply, TailHistoryRequest,
+ EndHistoryReply, EndHistoryRequest, HistoryEntry, HistoryEventKind, HistoryReply,
+ HistoryRequest, StartHistoryReply, StartHistoryRequest, TailHistoryReply,
+ TailHistoryRequest,
history_server::{History as HistorySvc, HistoryServer},
},
},
@@ -32,14 +34,16 @@ pub(crate) struct HistoryService {
running: DashMap<HistoryId, History>,
/// Handle to the daemon (set during start).
- pub(crate) handle: DaemonHandle,
+ handle: DaemonHandle,
- /// History store for pushing records (set during start).
- pub(crate) history_store: HistoryStore,
+ /// History store for pushing records
+ history_store: HistoryStore,
+
+ history_db: ClientSqlite,
}
impl HistoryService {
- pub(crate) async fn new(handle: DaemonHandle) -> Result<Self> {
+ pub(crate) async fn new(handle: DaemonHandle, history_db: ClientSqlite) -> Result<Self> {
let host_id = Settings::host_id().await?;
let history_store =
HistoryStore::new(handle.store().clone(), host_id, *handle.encryption_key());
@@ -48,6 +52,7 @@ impl HistoryService {
running: DashMap::new(),
handle,
history_store,
+ history_db,
})
}
@@ -57,21 +62,18 @@ impl HistoryService {
}
}
-fn history_to_tail_reply(kind: HistoryEventKind, history: History) -> TailHistoryReply {
- TailHistoryReply {
- kind: kind as i32,
- history: Some(HistoryEntry {
- timestamp: history.timestamp.unix_timestamp_nanos() as u64,
- id: history.id.0,
- command: history.command,
- cwd: history.cwd,
- session: history.session,
- hostname: history.hostname,
- author: history.author,
- intent: history.intent.unwrap_or_default(),
- exit: history.exit,
- duration: history.duration,
- }),
+fn history_to_reply(history: History) -> HistoryEntry {
+ HistoryEntry {
+ timestamp: history.timestamp.unix_timestamp_nanos() as u64,
+ id: history.id.0,
+ command: history.command,
+ cwd: history.cwd,
+ session: history.session,
+ hostname: history.hostname,
+ author: history.author,
+ intent: history.intent.unwrap_or_default(),
+ exit: history.exit,
+ duration: history.duration,
}
}
@@ -80,6 +82,35 @@ impl HistorySvc for HistoryService {
type TailHistoryStream = Pin<Box<dyn Stream<Item = Result<TailHistoryReply, Status>> + Send>>;
#[instrument(skip_all, level = Level::INFO)]
+ async fn history(
+ &self,
+ request: Request<HistoryRequest>,
+ ) -> Result<Response<HistoryReply>, Status> {
+ let req = request.into_inner();
+
+ let context = current_context(req.session)
+ .await
+ .map_err(|e| Status::internal(format!("failed to aquire context: {e:?}")))?;
+
+ let entries = if let Some(range) = req.range {
+ let from = OffsetDateTime::from_unix_timestamp(range.start as i64).unwrap();
+ let to = OffsetDateTime::from_unix_timestamp(range.end as i64).unwrap();
+
+ self.history_db.range(from, to).await
+ } else {
+ self.history_db
+ .list(&[], &context, None, false, false)
+ .await
+ }
+ .map_err(|e| Status::internal(format!("failed to read db: {e:?}")))?
+ .into_iter()
+ .map(history_to_reply)
+ .collect();
+
+ Ok(Response::new(HistoryReply { entries }))
+ }
+
+ #[instrument(skip_all, level = Level::INFO)]
async fn start_history(
&self,
request: Request<StartHistoryRequest>,
@@ -120,7 +151,6 @@ impl HistorySvc for HistoryService {
}
#[instrument(skip_all, level = Level::INFO)]
- #[expect(clippy::significant_drop_tightening, reason = "Would be a logic-bug")]
async fn end_history(
&self,
request: Request<EndHistoryRequest>,
@@ -195,12 +225,14 @@ impl HistorySvc for HistoryService {
};
let reply = match event {
- DaemonEvent::HistoryStarted(history) => {
- Some(history_to_tail_reply(HistoryEventKind::Started, history))
- }
- DaemonEvent::HistoryEnded(history) => {
- Some(history_to_tail_reply(HistoryEventKind::Ended, history))
- }
+ DaemonEvent::HistoryStarted(history) => Some(TailHistoryReply {
+ kind: HistoryEventKind::Started.into(),
+ history: Some(history_to_reply(history)),
+ }),
+ DaemonEvent::HistoryEnded(history) => Some(TailHistoryReply {
+ kind: HistoryEventKind::Ended.into(),
+ history: Some(history_to_reply(history)),
+ }),
_ => None,
};