P2 slice 3: opening and closing the books (plan 3.9, D-21, D-23)
One wanderbooks executable. The books are open while the viewer, an agent session or a terminal holds them: a host process takes leases on a socket, starts the server (the hidden mode `wanderbooks server`) with a pipe on its input, and closes it 10 s after the last lease ends. No background service. One host even in a race (run/host.lock). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3gXMVt7XJPi6ens1or9Dj
This commit is contained in:
1 parent
168e5c9846
commit
a298d154b6
31 files changed
+11937
-112
No files matched your search
@@ -18,8 +18,12 @@
|
||||
//! `/`, the home folder, or holds the books, the vault or a key is refused
|
||||
//! at startup.
|
||||
|
||||
pub mod admin;
|
||||
mod handbook;
|
||||
#[cfg(unix)]
|
||||
pub mod local;
|
||||
mod local_files;
|
||||
pub mod opening;
|
||||
mod policy;
|
||||
mod server;
|
||||
mod settings;
|
||||
@@ -34,6 +38,7 @@ use policy::ReceiptPolicy;
|
||||
use rmcp::ServiceExt;
|
||||
use serde::Deserialize;
|
||||
use server::BooksServer;
|
||||
pub use server::{NOT_RUN_CLOSING, NOT_RUN_CLOSING_CODE};
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Server configuration, JSON. All fields optional.
|
||||
@@ -138,6 +143,14 @@ pub fn run(
|
||||
}
|
||||
}
|
||||
}
|
||||
// Books in the data root are the books server's alone (plan 3.1):
|
||||
// a second writer beside it is refused before anything is opened.
|
||||
if ledger_store::root::inside_a_root(&data_dir) {
|
||||
eprintln!(
|
||||
"ledger-mcp: those books are in the books' private folder, which only the books server opens: connect to them with `wanderbooks mcp --book <id>`"
|
||||
);
|
||||
return Err(Box::new(Exit(2)));
|
||||
}
|
||||
let import_roots = if import_roots.is_empty() {
|
||||
ImportRoots::defaults()
|
||||
} else {
|
||||
@@ -221,7 +234,12 @@ pub fn run(
|
||||
// vault or a key (local_files.rs INVARIANT 0): a named one stops the
|
||||
// server here, a default one is dropped.
|
||||
let settings_now = live.lock().unwrap_or_else(|e| e.into_inner()).current();
|
||||
let import_roots = match server::guard_import_roots(&store, &settings_now, import_roots) {
|
||||
let import_roots = match server::guard_import_roots(
|
||||
&store,
|
||||
&settings_now,
|
||||
&server::Layout::BooksDir,
|
||||
import_roots,
|
||||
) {
|
||||
Ok(roots) => roots,
|
||||
Err(why) => {
|
||||
eprintln!("ledger-mcp: {why}");
|
||||
|
||||
Reference in new issue
Block a user