Skip to main content

vs_daemon/
config.rs

1//! Filesystem layout: where the daemon keeps state on disk.
2//!
3//! ```text
4//! ~/.vibesurfer/
5//!   daemon.sock           # the IPC socket
6//!   active-session        # one-line session id
7//!   state.db              # SQLite, WAL mode
8//!   key                   # AES-256 fallback if OS keyring unavailable
9//!   log/                  # rotating tracing output (M5+)
10//!   captures/             # screenshot output paths (M5+)
11//! ```
12
13use std::path::{Path, PathBuf};
14
15/// Daemon-side filesystem layout.
16#[derive(Debug, Clone)]
17pub struct Paths {
18    /// Root directory; usually `$HOME/.vibesurfer`.
19    pub root: PathBuf,
20}
21
22impl Paths {
23    /// Construct from a custom root (tests use a temp dir).
24    #[must_use]
25    pub fn at(root: impl Into<PathBuf>) -> Self {
26        Self { root: root.into() }
27    }
28
29    /// Conventional location: `$HOME/.vibesurfer`. Falls back to the
30    /// current directory if `$HOME` is unset (rare; CI containers).
31    #[must_use]
32    pub fn home() -> Self {
33        let root = std::env::var_os("HOME").map_or_else(
34            || PathBuf::from(".vibesurfer"),
35            |h| Path::new(&h).join(".vibesurfer"),
36        );
37        Self::at(root)
38    }
39
40    #[must_use]
41    pub fn socket(&self) -> PathBuf {
42        self.root.join("daemon.sock")
43    }
44
45    /// PID file for the running daemon. Written by `vs serve` on startup
46    /// and removed on graceful shutdown. `vs serve --stop` reads it.
47    #[must_use]
48    pub fn pid_file(&self) -> PathBuf {
49        self.root.join("daemon.pid")
50    }
51
52    #[must_use]
53    pub fn db(&self) -> PathBuf {
54        self.root.join("state.db")
55    }
56
57    #[must_use]
58    pub fn active_session(&self) -> PathBuf {
59        self.root.join("active-session")
60    }
61
62    #[must_use]
63    pub fn key_file(&self) -> PathBuf {
64        self.root.join("key")
65    }
66
67    /// Where the daemon writes screenshot PNGs from `vs_capture`.
68    /// Defaults to `<root>/captures`. Overridable per-process via the
69    /// `VS_CAPTURES_DIR` environment variable.
70    #[must_use]
71    pub fn captures(&self) -> PathBuf {
72        if let Some(p) = std::env::var_os("VS_CAPTURES_DIR") {
73            return PathBuf::from(p);
74        }
75        self.root.join("captures")
76    }
77
78    /// Ensure the root directory exists.
79    pub fn ensure_root(&self) -> std::io::Result<()> {
80        std::fs::create_dir_all(&self.root)
81    }
82}