#[cfg(all(
windows,
not(all(
target_vendor = "pc",
target_env = "msvc",
any(target_arch = "x86_64", target_arch = "aarch64")
))
))]
compile_error!(
"Pitboard for Windows is built for x86_64-pc-windows-msvc and aarch64-pc-windows-msvc \
alone, the targets it is built and tested on."
);
#[cfg(not(any(target_os = "macos", target_os = "linux", windows)))]
compile_error!(
"Pitboard runs on macOS, Linux and Windows. Another system needs a host of its own in \
`host/`, saying where its stores, processes and scheduler are."
);
pub(crate) mod api;
pub mod app;
pub mod assumptions;
pub mod audit;
pub mod context;
#[cfg(any(test, feature = "test-support"))]
#[doc(hidden)]
#[allow(
clippy::disallowed_methods,
reason = "it leaves Claude Desktop's files as Claude does"
)]
pub mod desktop_testing;
pub mod doctor;
pub mod duty;
pub mod error;
pub(crate) mod in_use;
pub mod label;
pub mod provider;
pub mod redact;
pub mod release;
pub mod schedule;
pub mod service;
pub(crate) mod settings;
pub mod state;
pub mod status;
pub mod statusline;
pub mod switch;
pub mod time;
pub mod usage;
pub mod words;
pub(crate) mod atomic;
pub(crate) mod base64;
pub(crate) mod fault;
#[cfg(test)]
mod helper;
pub mod holder;
pub(crate) mod home;
pub mod host;
pub(crate) mod lock;
pub(crate) mod park;
pub(crate) mod pending;
pub(crate) mod proxy;
pub(crate) mod sessions;
#[cfg(any(test, feature = "test-support"))]
#[doc(hidden)]
pub mod stand_in;
pub(crate) mod store;
#[cfg(feature = "test-support")]
#[doc(hidden)]
pub mod testing {
pub use crate::api::scripted::{Answer, Asked, ScriptedApi, Trouble};
pub use crate::desktop_testing as desktop;
pub use crate::duty::warm::run::{Started, WarmScript};
pub use crate::host::Ran;
pub use crate::host::fs::testing as fs;
pub use crate::host::memory::MemoryHost;
pub use crate::provider::claude::api::Renewed;
pub use crate::provider::claude::paths::live_service;
pub use crate::provider::claude::slot::{LIVE_SERVICE, dir_hash, service_for_dir};
pub use crate::stand_in;
pub use crate::store::memory::{Fault, MemoryStore};
pub use crate::store::vault_read;
pub use crate::switch::enroll::{ScriptedSignIn, SignInScript};
pub use crate::time::{Clock, FixedClock};
pub fn variables() -> impl Iterator<Item = &'static str> {
crate::context::variables()
}
pub fn lies_in(path: &std::path::Path, place: &std::path::Path) -> bool {
crate::host::lies_in(path, place)
}
pub fn real_login_places(
started_in: &crate::context::Context,
) -> Result<Vec<std::path::PathBuf>, String> {
crate::host::real_login_places(Some(started_in))
}
pub fn vault_write(
ctx: &crate::context::Context,
service: &str,
contents: &str,
) -> crate::error::Result<()> {
let permit = crate::service::gate(ctx)?;
Ok(crate::store::vault_write(ctx, permit, service, contents)?)
}
pub fn may_be_running(pid: u32) -> bool {
crate::host::proc::may_be_running(pid)
}
#[cfg(windows)]
pub fn processes() -> std::io::Result<Vec<(u32, u32, String)>> {
crate::host::proc::snapshot()
}
#[cfg(windows)]
pub mod version_resource {
use std::path::Path;
pub fn file_version(program: &Path) -> Option<[u16; 4]> {
crate::host::proc::file_version(program)
}
pub fn product_version(program: &Path) -> Option<[u16; 4]> {
crate::host::proc::product_version(program)
}
pub fn string(program: &Path, name: &str) -> Option<String> {
crate::host::proc::version_string(program, name)
}
}
#[cfg(windows)]
pub mod credman {
use crate::context::Context;
use crate::store::RawStore;
pub struct Item {
pub kind: u32,
pub persist: u32,
pub user: String,
pub comment: Option<String>,
pub attributes: u32,
pub bytes: usize,
}
fn refused(target: &str) -> std::io::Result<()> {
match crate::provider::names::refusal(target, &[]) {
Some(why) => Err(std::io::Error::other(why)),
None => Ok(()),
}
}
pub fn item(target: &str) -> std::io::Result<Option<Item>> {
refused(target)?;
Ok(
crate::host::windows_credman::item(target)?.map(|held| Item {
kind: held.kind,
persist: held.persist,
user: held.user,
comment: held.comment,
attributes: held.attributes,
bytes: held.blob.len(),
}),
)
}
pub fn write_as_bun(target: &str, user: &str, value: &str) -> std::io::Result<()> {
refused(target)?;
crate::host::windows_credman::write(target, user, value.as_bytes())
}
fn store(ctx: &Context) -> crate::provider::claude::credman::Store {
crate::provider::claude::credman::Store::of(ctx)
}
pub fn write(ctx: &Context, service: &str, contents: &str) -> crate::error::Result<()> {
let permit = crate::service::gate(ctx)?;
Ok(store(ctx).write(permit, service, contents)?)
}
pub fn read(ctx: &Context, service: &str) -> crate::error::Result<Option<String>> {
Ok(store(ctx).read(service)?)
}
pub fn discard(ctx: &Context, service: &str) -> crate::error::Result<()> {
let permit = crate::service::gate(ctx)?;
Ok(store(ctx).delete(permit, service)?)
}
pub fn sweep(ctx: &Context, service: &str) -> Result<(), String> {
crate::provider::claude::credman::swept(ctx, service)
}
}
pub fn vault_delete(ctx: &crate::context::Context, service: &str) -> crate::error::Result<()> {
let permit = crate::service::gate(ctx)?;
Ok(crate::store::vault_delete(ctx, permit, service)?)
}
pub fn signed_in(
ctx: &crate::context::Context,
which: crate::provider::ProviderId,
document: &str,
) -> crate::error::Result<crate::switch::SignIn> {
use crate::provider::LoginKind;
let document = serde_json::from_str(document).expect("a login a test wrote as JSON");
match crate::provider::of(which) {
LoginKind::Document(tool) => {
crate::switch::planted(ctx, crate::service::gate(ctx)?, tool, document)
}
LoginKind::Folder(_) => Err(crate::error::Error::Usage(
"a Claude Desktop sign-in is played by testing::desktop".into(),
)),
}
}
}