pub struct Client {
pub commit_author_name: String,
pub commit_author_email: String,
/* private fields */
}Expand description
On-disk layout root + state selection.
<dir> default: ~/.objectiveai
├── bin/ ── shared across states ──
│ ├── objectiveai[.exe] (+ -api, -viewer, -mcp, -db)
│ ├── pg-bin/ postgres install (objectiveai-db)
│ ├── plugins/<owner>/<name>/<version>/
│ └── tools/<owner>/<name>/<version>/
└── state/<state>/ default state: "default"
├── config.json
├── db/ .pgpass db.lock (cluster, per state)
├── logs/
└── instances/agents/Binaries, the postgres install, plugins and tools are
machine-wide (Self::bin_dir); everything else is per-state
(Self::state_dir), so independent states coexist under one
install by switching OBJECTIVEAI_STATE.
Fields§
Implementations§
Source§impl Client
impl Client
Sourcepub fn new(
dir: Option<impl Into<PathBuf>>,
state: Option<impl Into<String>>,
commit_author_name: Option<impl Into<String>>,
commit_author_email: Option<impl Into<String>>,
) -> Self
pub fn new( dir: Option<impl Into<PathBuf>>, state: Option<impl Into<String>>, commit_author_name: Option<impl Into<String>>, commit_author_email: Option<impl Into<String>>, ) -> Self
Resolution per field: explicit arg → env (OBJECTIVEAI_DIR /
OBJECTIVEAI_STATE, feature env) → default
(~/.objectiveai / "default").
Panics when the state name doesn’t match [A-Za-z0-9_-]+ —
state names become directory names under <dir>/state/, so
separators, dot-segments, and empty names are rejected
outright.
Sourcepub fn dir(&self) -> &PathBuf
pub fn dir(&self) -> &PathBuf
The layout root (OBJECTIVEAI_DIR). Forward this (with
Self::state) to child processes so they resolve the same
tree.
Sourcepub fn bin_dir(&self) -> PathBuf
pub fn bin_dir(&self) -> PathBuf
<dir>/bin — binaries, the postgres install, plugins, tools.
Shared across every state.
Sourcepub fn state_dir(&self) -> PathBuf
pub fn state_dir(&self) -> PathBuf
<dir>/state/<state> — config, database cluster, logs, agent
registry. Per state.
Sourcepub fn config_path(&self) -> PathBuf
pub fn config_path(&self) -> PathBuf
Per-state config: <dir>/state/<state>/config.json.
Sourcepub fn global_config_path(&self) -> PathBuf
pub fn global_config_path(&self) -> PathBuf
Machine-wide (global) config: <dir>/bin/config.json — lives
with the other machine-wide artifacts.
pub fn logs_dir(&self) -> PathBuf
Source§impl Client
impl Client
pub async fn read_config(&self) -> Result<Config, Error>
pub async fn write_config(&self, config: &Config) -> Result<(), Error>
Sourcepub async fn read_config_at(&self, scope: SetScope) -> Result<Config, Error>
pub async fn read_config_at(&self, scope: SetScope) -> Result<Config, Error>
Read the config file a MUTATION targets — no merging, ever:
--global edits <dir>/bin/config.json, --state edits
<dir>/state/<state>/config.json. Missing file = defaults.
Sourcepub async fn write_config_at(
&self,
scope: SetScope,
config: &Config,
) -> Result<(), Error>
pub async fn write_config_at( &self, scope: SetScope, config: &Config, ) -> Result<(), Error>
Write back the file Self::read_config_at selected.
Sourcepub async fn read_config_view(&self, scope: GetScope) -> Result<Config, Error>
pub async fn read_config_view(&self, scope: GetScope) -> Result<Config, Error>
Read the config VIEW a get targets: --global and
--state return their file verbatim; --final joins them —
the global (root) config is the base and the per-state config
is layered on top, winning every conflict (recursively: maps
like api.mcp_authorization union per key with the per-state
entry overwriting the global one).
Source§impl Client
impl Client
Sourcepub fn plugins_dir(&self) -> PathBuf
pub fn plugins_dir(&self) -> PathBuf
The plugins directory: <bin_dir>/plugins — installed
plugins are machine-wide, shared by every state.
Sourcepub fn plugin_dir(&self, owner: &str, name: &str, version: &str) -> PathBuf
pub fn plugin_dir(&self, owner: &str, name: &str, version: &str) -> PathBuf
The directory that holds a plugin’s installed artifacts:
<plugins_dir>/<owner>/<name>/<version>/. Contains the
manifest objectiveai.json, the cli/ exec working
directory, and an optional viewer/ bundle.
Sourcepub fn plugin_cli_dir(&self, owner: &str, name: &str, version: &str) -> PathBuf
pub fn plugin_cli_dir(&self, owner: &str, name: &str, version: &str) -> PathBuf
A plugin’s cli working directory: <plugin_dir>/cli/. The
manifest’s exec runs with this as CWD; cli_zip extracts
into it at install time.
Sourcepub async fn resolve_plugin(
&self,
owner: &str,
name: &str,
version: &str,
) -> Option<(Vec<String>, PathBuf)>
pub async fn resolve_plugin( &self, owner: &str, name: &str, version: &str, ) -> Option<(Vec<String>, PathBuf)>
Resolve a plugin coordinate to its (exec_vector, cli_dir)
for the current platform — the same contract
Client::resolve_tool
has, with the plugin’s cli/ folder as the working directory.
exec_vector may be empty when the manifest declares no
command for this platform (viewer-only plugins; the caller
treats that as an error). None when the manifest is
missing/malformed/invalid.
Sourcepub async fn get_plugin(
&self,
owner: &str,
name: &str,
version: &str,
) -> Option<Manifest>
pub async fn get_plugin( &self, owner: &str, name: &str, version: &str, ) -> Option<Manifest>
Look up a single plugin manifest by coordinate. Reads
<base_dir>/plugins/<owner>/<name>/<version>/objectiveai.json.
Returns None if the file is missing, unreadable, malformed, or
invalid.
Sourcepub async fn list_plugins(&self, offset: usize, limit: usize) -> Vec<Manifest>
pub async fn list_plugins(&self, offset: usize, limit: usize) -> Vec<Manifest>
Enumerate plugin manifests by walking the
plugins/<owner>/<name>/<version>/objectiveai.json tree. Every
failure mode — missing dir, unreadable file, malformed JSON,
missing required field — is silently skipped; the return type is
plain Vec rather than Result to reflect that.
Results are sorted by manifest mtime descending (most recently
modified first), then skip(offset).take(limit) is applied —
matching the convention of the logs list endpoints. Pass
(0, usize::MAX) for an unbounded list.
The directory walk is sequential but per-file read+parse runs
concurrently via futures::future::join_all.
Source§impl Client
impl Client
Sourcepub async fn install_plugin(
&self,
owner: &str,
repository: &str,
commit_sha: Option<&str>,
headers: Option<&IndexMap<String, String>>,
upgrade: bool,
) -> Result<bool, Error>
pub async fn install_plugin( &self, owner: &str, repository: &str, commit_sha: Option<&str>, headers: Option<&IndexMap<String, String>>, upgrade: bool, ) -> Result<bool, Error>
Install a plugin from a GitHub repository: fetch
objectiveai.json, download the current platform’s cli_zip
plus the viewer_zip (when declared), extract them, and persist
the manifest verbatim. Thin wrapper over the shared
Client::install_from_github_at engine. headers attaches to
every request (e.g. Authorization); the cli passes None. The
bool is always true on success (retained for wire compat).
Sourcepub async fn fetch_plugin_manifest(
&self,
owner: &str,
repository: &str,
commit_sha: Option<&str>,
headers: Option<&IndexMap<String, String>>,
) -> Result<Manifest, Error>
pub async fn fetch_plugin_manifest( &self, owner: &str, repository: &str, commit_sha: Option<&str>, headers: Option<&IndexMap<String, String>>, ) -> Result<Manifest, Error>
Fetch + parse <owner>/<repo>/<ref>/objectiveai.json. Exposed so
callers can inspect the manifest before committing to an install
(e.g. for whitelist checks).
Sourcepub async fn install_plugin_from_manifest(
&self,
owner: &str,
repository: &str,
manifest: &Manifest,
source: &str,
headers: Option<&IndexMap<String, String>>,
upgrade: bool,
) -> Result<bool, Error>
pub async fn install_plugin_from_manifest( &self, owner: &str, repository: &str, manifest: &Manifest, source: &str, headers: Option<&IndexMap<String, String>>, upgrade: bool, ) -> Result<bool, Error>
Given an already-parsed manifest, download its release assets and
persist it. source is retained for API compatibility and is
unused — the engine derives every path from the coordinate.
Source§impl Client
impl Client
Sourcepub fn resolve_head(
&self,
kind: Kind,
owner: &str,
repository: &str,
) -> Result<String, Error>
pub fn resolve_head( &self, kind: Kind, owner: &str, repository: &str, ) -> Result<String, Error>
Resolves the HEAD commit SHA for a repository.
Sourcepub async fn read_json<T: DeserializeOwned>(
&self,
kind: Kind,
owner: &str,
repository: &str,
commit: Option<&str>,
) -> Result<Option<(T, String)>, Error>
pub async fn read_json<T: DeserializeOwned>( &self, kind: Kind, owner: &str, repository: &str, commit: Option<&str>, ) -> Result<Option<(T, String)>, Error>
Reads and deserializes a kind’s JSON file from a repository.
commit = Some reads from that specific git commit; commit = None
reads the working tree and resolves HEAD for the reported commit.
Returns Ok(None) if the repository or file does not exist.
Sourcepub async fn list(
&self,
kind: Kind,
) -> Pin<Box<dyn Stream<Item = RemotePath> + Send>>
pub async fn list( &self, kind: Kind, ) -> Pin<Box<dyn Stream<Item = RemotePath> + Send>>
Streams every valid repository of kind under state_dir/<kind>.
The outer stream lists the <owner> directories; each owner is then
flat-mapped into an inner stream listing its <repository>
directories, and each repo resolves to a Client remote path by
reading HEAD and parsing the kind’s JSON. Repos whose HEAD or JSON
fails are skipped. Nothing is buffered into a Vec: directories are
walked lazily as the stream is polled.
Source§impl Client
impl Client
Sourcepub fn tool_dir(&self, owner: &str, name: &str, version: &str) -> PathBuf
pub fn tool_dir(&self, owner: &str, name: &str, version: &str) -> PathBuf
A tool’s version directory:
<base_dir>/tools/<owner>/<name>/<version>. Holds the
objectiveai.json manifest; the executable payload lives in the
Self::tool_cli_dir subfolder.
Sourcepub fn tool_cli_dir(&self, owner: &str, name: &str, version: &str) -> PathBuf
pub fn tool_cli_dir(&self, owner: &str, name: &str, version: &str) -> PathBuf
A tool’s cli working directory: <tool_dir>/cli/. The exec runs
here and relative program paths resolve against it; the manifest
objectiveai.json stays in the parent version folder. Mirrors
Client::plugin_cli_dir.
Sourcepub async fn resolve_tool(
&self,
owner: &str,
name: &str,
version: &str,
) -> Option<(Vec<String>, PathBuf)>
pub async fn resolve_tool( &self, owner: &str, name: &str, version: &str, ) -> Option<(Vec<String>, PathBuf)>
Resolve a tool coordinate to its (exec_vector, cwd) for the
current platform. cwd is the version folder’s cli/ subdir
(the exec working directory); exec_vector is the manifest’s
per-OS command (possibly empty when the tool declares no command
for this platform — the caller treats that as an error). None
when the manifest is missing/malformed.
Sourcepub async fn get_tool(
&self,
owner: &str,
name: &str,
version: &str,
) -> Option<Manifest>
pub async fn get_tool( &self, owner: &str, name: &str, version: &str, ) -> Option<Manifest>
Look up a single tool manifest by coordinate. Reads
<base_dir>/tools/<owner>/<name>/<version>/objectiveai.json.
None on missing / unreadable / malformed files.
Sourcepub async fn list_tools(&self, offset: usize, limit: usize) -> Vec<Manifest>
pub async fn list_tools(&self, offset: usize, limit: usize) -> Vec<Manifest>
Enumerate tool manifests by walking the
tools/<owner>/<name>/<version>/objectiveai.json tree. Every
failure mode — missing dir, unreadable file, malformed JSON — is
silently skipped.
Results are sorted by manifest mtime descending, then
skip(offset).take(limit) is applied — matching list_plugins.
Pass (0, usize::MAX) for an unbounded list.
Source§impl Client
impl Client
Sourcepub async fn install_tool(
&self,
owner: &str,
repository: &str,
commit_sha: Option<&str>,
headers: Option<&IndexMap<String, String>>,
upgrade: bool,
) -> Result<bool, Error>
pub async fn install_tool( &self, owner: &str, repository: &str, commit_sha: Option<&str>, headers: Option<&IndexMap<String, String>>, upgrade: bool, ) -> Result<bool, Error>
Install a tool from a GitHub repository: fetch objectiveai.json,
download the current platform’s cli_zip, extract it into the
tool’s cli/ dir, and persist the manifest verbatim. Thin
wrapper over Client::install_from_github_at. The bool is
always true on success (retained for symmetry with plugins).
Sourcepub async fn fetch_tool_manifest(
&self,
owner: &str,
repository: &str,
commit_sha: Option<&str>,
headers: Option<&IndexMap<String, String>>,
) -> Result<Manifest, Error>
pub async fn fetch_tool_manifest( &self, owner: &str, repository: &str, commit_sha: Option<&str>, headers: Option<&IndexMap<String, String>>, ) -> Result<Manifest, Error>
Fetch + parse <owner>/<repo>/<ref>/objectiveai.json as a
tool manifest. Exposed so callers can inspect it before
committing to an install (e.g. for whitelist checks).
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Client
impl RefUnwindSafe for Client
impl Send for Client
impl Sync for Client
impl Unpin for Client
impl UnsafeUnpin for Client
impl UnwindSafe for Client
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more