Phase 1: project scaffold, clap CLI, self-re-exec daemon, NDJSON IPC

- Cargo.toml with clap, tokio, serde, anyhow dependencies
- Entry point with env-var routing to daemon or CLI mode
- Core protocol types (Request/Response NDJSON wire format)
- Session detection (X11 check with DISPLAY/XDG_SESSION_TYPE)
- RefMap with @wN selector resolution (direct, prefix, substring)
- Snapshot/WindowInfo shared types with Display impl
- clap derive CLI with all subcommands (snapshot, click, type, etc.)
- Client connection: socket path resolution, daemon auto-start via
  self-re-exec, NDJSON send/receive with retry backoff
- Tokio async daemon: Unix socket listener, accept loop, graceful
  shutdown via notify
- DaemonState holding session info and ref map
- Placeholder handler returning hardcoded snapshot response
This commit is contained in:
Harivansh Rathi 2026-03-24 21:19:18 -04:00
parent 17d4a1edeb
commit dfaa339594
13 changed files with 1735 additions and 0 deletions

31
src/daemon/handler.rs Normal file
View file

@ -0,0 +1,31 @@
use std::sync::Arc;
use tokio::sync::Mutex;
use crate::core::protocol::{Request, Response};
use super::state::DaemonState;
pub async fn handle_request(
request: &Request,
_state: &Arc<Mutex<DaemonState>>,
) -> Response {
match request.action.as_str() {
"snapshot" => {
Response::ok(serde_json::json!({
"screenshot": "/tmp/desktop-ctl-placeholder.png",
"windows": [
{
"ref_id": "w1",
"xcb_id": 0,
"title": "Placeholder Window",
"app_name": "placeholder",
"x": 0, "y": 0, "width": 1920, "height": 1080,
"focused": true, "minimized": false
}
]
}))
}
action => {
Response::err(format!("Unknown action: {action}"))
}
}
}