1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! basis — the in-process SDK of [basis](https://github.com/oops-rs/basis), an
//! embeddable agent harness built on [Mentra](https://github.com/oops-rs/mentra).
//!
//! This crate is the harness itself: workspace discovery (AGENTS.md, skills,
//! templates, `.mcp.json`), the run lifecycle, one event stream, and the seams
//! a host plugs into (approval, hooks). It carries no protocol, no transport
//! and no terminal code, so an embedder's dependency graph states what they
//! actually use (ADR-0011).
//!
//! Embedding surfaces, in order of preference:
//!
//! 1. **In-process**: depend on this crate (Rust hosts).
//! 2. **ACP**: `basis-acp` serves the Agent Client Protocol (JSON-RPC 2.0 over
//! stdio) over this crate's event stream, for editors and web UIs. It is
//! reached from the binary with the explicit `basis serve --acp` command.
//! 3. **Subprocess**: `basis spawn --json` streams JSONL events for scripts and CI;
//! `basis run` remains a compatibility alias.
//!
//! The core has no opinions: task-specific behavior enters through data — the
//! prompt, the workspace (AGENTS.md, skills, templates, `.mcp.json`), and
//! config — never through code in this crate.
//!
//! # Three shapes
//!
//! [`Workspace`] is the SDK's shape (ADR-0010). Opening one settles everything
//! that belongs to a repository rather than to a prompt — context documents,
//! the resolved model, skills, templates, hooks, MCP connections — and then
//! mints runs from it without doing any of that again:
//!
//! ```no_run
//! # async fn example() -> Result<(), basis::RunError> {
//! let workspace = basis::Workspace::open("/repo").await?;
//! let mut run = workspace.prepare("what does this repo do?")?;
//! let report = run.execute(basis::CollectingSink::default()).await?;
//! # let _ = report;
//! # Ok(())
//! # }
//! ```
//!
//! [`run`](run()) and its neighbours are the one-prompt shape: a
//! [`RunConfig`] in, a report out, with a workspace opened and dropped around
//! it. They are wrappers over the same path — [`RunConfig::split`] is the seam
//! — so nothing behaves differently for having gone through one.
//!
//! [`Runtime`] is the process's shape (ADR-0018), and only the N-repository
//! host sees it: what changes when the host changes — provider and credential,
//! the history store, the host's interceptors — is built once and every
//! workspace borrows it through an `Arc`. `Workspace::open` builds a private
//! one behind the scenes, so the other two shapes never name it.
//!
//! # Features
//!
//! - **`mcp`** (default) — `.mcp.json` discovery and the MCP binding of the
//! tool contract. Built without it, the crate has no MCP concept at all: no
//! `McpConfig` on a run, no servers registered, and a run header that names
//! none (ADR-0012). Custom tools remain, because MCP was only ever one of the
//! ways to reach them.
pub use ;
pub use ;
pub use BudgetPool;
pub use ;
pub use ;
// `fingerprint::snapshot` keeps its module: at the crate root `snapshot` would
// not say a snapshot of what, and the two types beside it are only meaningful
// as its result.
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ShellAccess;
// Mentra's, deliberately. These three are the types basis's own surface asks a
// caller to *name* — a model to resolve, a provider to prefer, a token to stop
// a turn with — and re-exporting them is what keeps that from meaning "add
// mentra to your manifest, pinned to whatever version basis happens to
// resolve". A skew there is a type error with no explanation in it. Everything
// else mentra owns stays behind `mentra::`, where an embedder that wants the
// runtime itself already is.
pub use ;
// The attribute both of basis's async traits make an implementor spell:
// `Approver` and `Interceptor` are `#[async_trait]`, so without this line
// writing either impl means adding `async-trait` to the host's own manifest —
// a dependency basis's docs used to ask for without saying so. Same rule as the
// mentra types above, applied to a macro.
pub use async_trait;
pub use ;
// `store::list` keeps its module: at the crate root `list` would not say what
// is being listed, and `PersistedSession` is only meaningful beside it.
pub use PersistedSession;
pub use ;
// `tools::spawn` keeps its module: `SpawnTool` at the crate root would sit
// beside a dozen types that are not tools, and the name an operator writes in a
// rule or a hook is only meaningful next to the tool it names.
pub use SpawnTool;
pub use ;