harness-sdk
Harness SDK — framework for building autonomous agent harnesses with AHE (arXiv 2604.25850) primitives + Codex-grade TUI runtime.
Harness SDK — framework for building autonomous agent harnesses with AHE (arXiv 2604.25850) primitives + Codex-grade TUI runtime.
Package contract
| Field | Value |
|---|---|
| Language | rust |
| Source version | 0.1.0-alpha.1 |
| Manifest | harness-sdk/Cargo.toml |
| Source files | 62 |
| Evidence | Source reference; registry publication and runtime conformance are separate checks |
Import boundary
use harness_sdk;Use a source checkout or your verified private registry. Manifest coordinates identify the package; they do not establish that a public registry release exists.
Crate boundary
The following entries are taken from src/lib.rs. Feature conditions in the exact source still apply.
pub mod adapter;
pub mod backtrack;
pub mod clipboard;
pub mod composer;
pub mod error;
pub mod external_editor;
pub mod harness;
pub mod keymap;
pub mod onboarding;
pub mod session;
pub mod settings;
pub mod types;
pub mod workspace;
pub mod interjection;
pub mod validation;
pub mod commands;
pub mod modes;
pub mod runtime;
pub mod screens;
pub mod adapters;
#[cfg(feature = "plugins")]
pub mod plugins;
pub use error::{AdapterError, ParseError, PluginError, SdkError};
pub use session::{
JsonlSessionStore, SessionMetadata, SessionRecord, SessionRecordKind, SessionStore,
SessionStoreError,
};
pub use keymap::{
parse_key_spec, parse_key_spec_chord, Action, ContextualKeymap, KeyBinding, KeySpecError,
Keymap, KeymapContext, KeymapError,
};
pub use backtrack::{list_backtrack_targets, rewind_to, BacktrackTarget};
pub use composer::{HistorySearch, MessageQueue, MessageQueueError, MESSAGE_QUEUE_CAPACITY};
pub use settings::{
FlocksCli, ModeInfo, ModelInfo, ProviderInfo, ProviderKind, ProviderSettingField,
ProviderSettingKind, ProviderSettingOption, SettingsAction, SettingsApplyResult,
SettingsSnapshot,
};
pub use clipboard::{Clipboard, ClipboardError, MemoryClipboard, SystemClipboard};
pub use external_editor::{
open_in_editor, open_with_command, resolve_editor_command, ExternalEditorError,
};
pub use onboarding::{OnboardingError, OnboardingFlow, OnboardingSelection, OnboardingStep};
pub use workspace::complete_workspace_paths;
pub use harness::{
attribute, attribute_entry, AttributionDecision, AttributionVerdict, ChangeManifest,
EvidenceCorpus, EvidenceCorpusError, HarnessComponentEdit, HarnessComponentEditKind,
HarnessComponentKind, HarnessLoopError, HarnessLoopPhase, HarnessWorkspace,
HarnessWorkspaceError, IterationRecord, ManifestEntry, OverviewReport, PredictedImpact,
StandardHarnessLoop, TaskAnalysis, TaskDelta, TaskOutcome, TaskOutcomeMap,
HARNESS_COMPONENT_KINDS,
};
pub use types::{
ActivityLevel, AdapterCapabilities, AutonomyEvent, HumanInterjection, InterjectionAck,
InterjectionKind, InterjectionPriority, Mode, ResponseChunk, SdkAgentInfo, SdkAgentStatus,
SdkApprovalAction, SdkApprovalRequest, SdkRiskLevel, SdkRole, SessionInfo,
};
pub use types::{
DEFAULT_MAX_MESSAGES, DEFAULT_STREAM_TIMEOUT, MAX_AGENT_ID_LEN, MAX_AGENT_NAME_LEN,
MAX_CHUNK_SIZE, MAX_INTERJECTION_LEN, MAX_TOOL_INPUT_SIZE,
};
pub use adapter::AgentAdapter;
pub use runtime::app::{AgentApp, AgentAppBuilder};
pub use runtime::terminal_control::{
clear_title, hyperlink, ring_bell, set_title, write_hyperlink, MAX_HYPERLINK_URL_LEN,
MAX_TITLE_LEN,
};
pub use runtime::notifications::{
KindMask, NotificationKind, Notifier, NotifierConfig, MAX_NOTIFICATION_LEN,
};
pub use screens::custom::{CustomScreen, ScreenEvent, ScreenResult};
pub use adapters::stdio::StdioAdapter;
#[cfg(feature = "http")]
pub use adapters::http::HttpAdapter;Feature flags
| Feature | Enables |
|---|---|
default | chat, autonomy |
chat | (empty) |
autonomy | chat |
http | dep:reqwest |
plugins | dep:wasmtime, dep:sha2, dep:toml_edit, dep:glob |
full | chat, autonomy, http, plugins |
Source reference
Download package reference JSON. Each original source file and generated declaration artifact has its own SHA-256 digest. Function bodies and constant values are omitted from downloads. These are source declaration inventories, not compiler-resolved rustdoc, TypeDoc, DocC, or Dokka output. Private modules can contain public declarations that are not reachable through the package boundary; consult the entry point before importing.
adapter.rs
Read declaration text · 1 declaration entries
#[async_trait::async_trait]
pub trait AgentAdapter: Send + Sync + 'static {
/// Returns the adapter's name (used in logs and UI).
///
/// Must be non-empty and stable across calls.
fn name(&self) -> &str;
/// Returns the adapter's capability flags.
///
/// The SDK checks these flags before calling optional methods.
/// Returning `false` for a capability means the SDK will never call
/// the corresponding methods and will disable related UI features.
fn capabilities(&self) -> AdapterCapabilities;
/// Discover available agents.
///
/// Called during initialization and when the user requests a refresh.
/// The SDK validates every returned `SdkAgentInfo` before use.
async fn list_agents(&self) -> Result<Vec<SdkAgentInfo>, AdapterError>;
/// Send a chat message to an agent and receive a streaming response.
///
/// The returned stream must eventually yield [`ResponseChunk::Done`]
/// or [`ResponseChunk::Error`]. The SDK enforces a timeout if neither
/// arrives within the configured duration.
///
/// # Arguments
///
/// * `agent_id` — Target agent identifier (from `list_agents`)
/// * `message` — User's message text (already sanitized)
async fn send_message(
&self,
agent_id: &str,
message: &str,
) -> Result<BoxStream<'static, ResponseChunk>, AdapterError>;
/// Cancel an in-progress response stream.
///
/// Called when the user presses Escape or Ctrl+C during streaming.
/// Default implementation returns `Ok(())` (no-op).
async fn cancel_response(&self, _agent_id: &str) -> Result<(), AdapterError> ;
// ── Autonomy Mode ──
/// Start an autonomous execution session.
///
/// Returns a stream of [`AutonomyEvent`]s that the SDK displays
/// in the activity feed.
///
/// Only called if `capabilities().autonomy` is `true`.
async fn start_autonomy(
&self,
_agent_id: &str,
_instructions: &str,
) -> Result<BoxStream<'static, AutonomyEvent>, AdapterError> ;
/// Stop the current autonomous execution session.
///
/// Called when the user presses Ctrl+S or `/stop`.
async fn stop_autonomy(&self, _agent_id: &str) -> Result<(), AdapterError> ;
/// Send a human interjection during autonomous execution.
///
/// The adapter should acknowledge receipt via [`InterjectionAck`].
async fn send_interjection(
&self,
_interjection: &HumanInterjection,
) -> Result<InterjectionAck, AdapterError> ;
// ── Approval Management ──
/// Submit an approval decision for a pending request.
///
/// Called when the user approves, denies, or edits an approval request
/// from the approval queue.
async fn submit_approval(
&self,
_request_id: &str,
_action: SdkApprovalAction,
) -> Result<(), AdapterError> ;
// ── UI Rendering Hooks ──
/// Optional hook to render custom content in the sidebar area.
///
/// Called during each frame render. The `area` is the sidebar region
/// from `AppShellState::sidebar_area()`. Default is a no-op.
///
/// This is intentionally **sync** because rendering happens on the
/// main thread inside `terminal.draw()`.
fn render_sidebar(
&self,
_frame: &mut ratatui::Frame,
_area: ratatui::layout::Rect,
_theme: &Theme,
) ;
/// Optional hook to render custom content in the header area.
///
/// Called during each frame render. The `area` is the header region
/// from `AppShellState::header_area()`. Default is a no-op.
fn render_header(
&self,
_frame: &mut ratatui::Frame,
_area: ratatui::layout::Rect,
_theme: &Theme,
) ;
/// Optional hook to request a taller header from the chat screen.
///
/// The default `AppShell` reserves only 1 row for the header. An
/// adapter that wants to paint a banner / mascot / multi-line
/// status returns its desired height here. The chat screen passes
/// `sidebar_collapsed` so the adapter can ask for a tall header
/// only when the sidebar is hidden (and otherwise paint into the
/// sidebar).
fn desired_header_height(&self, _sidebar_collapsed: bool) -> u16 ;
/// Optional hook to request a wider sidebar from the chat screen.
/// Defaults to the SDK's `AppShell` default (25 columns).
fn desired_sidebar_width(&self) -> Option<u16> ;
/// Optional hook to provide live file-mention completions when the
/// user types `@<prefix>` in the input bar.
///
/// `prefix` is everything after the `@` up to the cursor. The
/// adapter returns up to ~50 matching paths (relative to its
/// workspace root). Default: no completions, dropdown stays
/// hidden.
///
/// Path conventions adapters should honour:
/// - `@foo` → fuzzy match anywhere in the workspace
/// - `@./foo` → match relative to the workspace root
/// - `@../foo` → walk up one directory
/// - `@/abs/path` → absolute path on the filesystem
///
/// This is intentionally **sync**: the SDK calls it on every
/// keystroke, so adapters MUST keep it cheap (cache the walk,
/// limit results, never block on I/O).
fn complete_file_mention(&self, _prefix: &str) -> Vec<String> ;
// ── Lifecycle ──
/// Called once when the TUI application starts.
///
/// Use this for any one-time initialization (connecting to backends,
/// spawning background tasks, etc.).
async fn on_startup(&self) -> Result<(), AdapterError> ;
/// Called once when the TUI application is shutting down.
///
/// Use this for cleanup (closing connections, saving state, etc.).
/// The SDK waits up to 5 seconds for this to complete before forcing exit.
async fn on_shutdown(&self) -> Result<(), AdapterError> ;
// ── Settings palette (Ctrl+P) ──
/// Return the current settings snapshot — providers, modes,
/// Flocks CLIs — that the runtime should render in the Ctrl+P
/// palette. The default returns an empty snapshot, which causes
/// the palette to show only the built-in pages.
async fn settings_snapshot(&self) -> Result<SettingsSnapshot, AdapterError> ;
/// Apply a [`SettingsAction`] picked by the user in the
/// settings palette. The default returns
/// `Ok(SettingsApplyResult::fail(...))`, signaling the runtime
/// to display a "not supported" flash.
async fn apply_settings_action(
&self,
_action: SettingsAction,
) -> Result<SettingsApplyResult, AdapterError> ;
}adapters/http.rs
Read declaration text · 4 declaration entries
pub struct HttpAdapter {
}
#[must_use]
pub fn new(base_url: impl Into<String>) -> Self;
#[must_use]
pub fn with_bearer_token(mut self, token: impl Into<String>) -> Self;
#[must_use]
pub fn with_capabilities(mut self, caps: AdapterCapabilities) -> Self;adapters/mod.rs
Read declaration text · 2 declaration entries
pub mod stdio;
#[cfg(feature = "http")]
pub mod http;adapters/stdio.rs
Read declaration text · 3 declaration entries
pub struct StdioAdapter {
}
#[must_use]
pub fn new(program: impl Into<String>, args: &[impl AsRef<str>]) -> Self;
#[must_use]
pub fn with_name(mut self, name: impl Into<String>) -> Self;backtrack.rs
Read declaration text · 3 declaration entries
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BacktrackTarget {
/// Index into `AppState::messages()` (0-based).
pub message_index: usize,
/// User turn ordinal (1, 2, 3 …) — useful as a label.
pub turn_ordinal: usize,
/// Snippet of the user prompt (truncated to ~80 chars) for
/// display.
pub preview: String
}
#[must_use]
pub fn list_backtrack_targets(state: &AppState) -> Vec<BacktrackTarget>;
pub fn rewind_to(state: &mut AppState, target: &BacktrackTarget) -> Result<String, SdkError>;clipboard.rs
Read declaration text · 5 declaration entries
#[derive(Debug, Error)]
pub enum ClipboardError {
/// The platform clipboard is unavailable (no display server,
/// permission denied, etc.).
#[error("clipboard unavailable: {0}")]
Unavailable(String),
/// Underlying clipboard backend error (`arboard::Error`).
#[error("clipboard backend: {0}")]
Backend(String),
}
pub trait Clipboard: Send {
/// Copy `text` to the platform clipboard, replacing prior contents.
fn copy(&mut self, text: &str) -> Result<(), ClipboardError>;
/// Read the current clipboard contents as UTF-8 text. Returns
/// [`ClipboardError::Unavailable`] when the clipboard is empty or
/// holds non-text content.
fn paste(&mut self) -> Result<String, ClipboardError>;
}
pub struct SystemClipboard {
}
pub fn new() -> Result<Self, ClipboardError>;
#[derive(Debug, Default)]
pub struct MemoryClipboard {
}commands/mod.rs
Read declaration text · 1 declaration entries
pub mod slash;commands/slash.rs
Read declaration text · 12 declaration entries
#[derive(Debug, Clone)]
pub enum SlashResult {
/// Command executed, display message to user.
Message(String),
/// Switch to the specified mode.
SwitchMode(Mode),
/// Stop the current autonomy session.
StopAutonomy,
/// Clear the chat history.
ClearHistory,
/// Show help text.
ShowHelp(String),
/// Quit the application.
Quit,
/// Command not found.
NotFound(String),
/// Toggle the command palette.
TogglePalette,
/// List available agents.
ListAgents,
/// Show session status.
ShowStatus,
/// Send expanded text as a chat message to the active agent.
SendAsChat(String),
}
#[derive(Debug, Clone)]
pub struct SlashArg {
/// Argument name (e.g., "mode").
pub name: String,
/// Whether this argument is required.
pub required: bool,
/// Possible values (e.g., \["chat", "auto"\]).
pub options: Vec<String>,
/// Short description (e.g., "The mode to switch to").
pub description: String
}
#[derive(Debug, Clone)]
pub struct SlashCommand {
/// Command name (without the `/` prefix).
pub name: String,
/// Short description.
pub description: String,
/// Source label ("built-in" or plugin name).
pub source: String,
/// Aliases for this command.
pub aliases: Vec<String>,
/// Usage template (e.g., "/mode <chat|auto>").
pub usage: String,
/// Structured argument definitions.
pub args: Vec<SlashArg>
}
pub struct SlashCommandRegistry {
}
#[must_use]
pub fn new() -> Self;
#[must_use]
pub fn with_builtins() -> Self;
#[must_use]
pub fn lookup(&self, name: &str) -> Option<&SlashCommand>;
pub fn register(&mut self, command: SlashCommand);
#[must_use]
pub fn list_commands(&self) -> Vec<&SlashCommand>;
#[must_use]
pub fn command_hints(&self) -> Vec<harness_tui_kit::CommandHint>;
#[must_use]
pub fn dropdown_items(&self) -> Vec<harness_tui_kit::SlashDropdownItem>;
pub fn dispatch_slash(input: &str, registry: &SlashCommandRegistry) -> SlashResult;composer.rs
Read declaration text · 22 declaration entries
pub const MESSAGE_QUEUE_CAPACITY: usize;
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum MessageQueueError {
/// The supplied message was empty after trimming.
#[error("queued message is empty after trimming")]
EmptyMessage,
/// The message exceeds [`MAX_INTERJECTION_LEN`].
#[error("queued message length {0} exceeds limit {MAX_INTERJECTION_LEN}")]
TooLong(usize),
/// The queue is full.
#[error("message queue is full ({0} pending)")]
Full(usize),
}
#[derive(Debug, Clone, Default)]
pub struct MessageQueue {
}
#[must_use]
pub fn new() -> Self;
#[must_use]
pub fn len(&self) -> usize;
#[must_use]
pub fn is_empty(&self) -> bool;
pub fn push(&mut self, message: impl Into<String>) -> Result<(), MessageQueueError>;
pub fn pop(&mut self) -> Option<String>;
pub fn drain(&mut self) -> Vec<String>;
#[must_use]
pub fn peek(&self) -> &VecDeque<String>;
pub fn clear(&mut self);
#[derive(Debug, Clone, Default)]
pub struct HistorySearch {
}
#[must_use]
pub fn new() -> Self;
#[must_use]
pub fn query(&self) -> &str;
#[must_use]
pub fn match_index(&self) -> Option<usize>;
#[must_use]
pub fn has_match(&self) -> bool;
pub fn reset(&mut self);
pub fn push_char(&mut self, ch: char, history: &[String]);
pub fn pop_char(&mut self, history: &[String]);
pub fn update(&mut self, history: &[String]);
pub fn next_match(&mut self, history: &[String]);
#[must_use]
pub fn matched<'h>(&self, history: &'h [String]) -> Option<&'h str>;error.rs
Read declaration text · 4 declaration entries
#[derive(Debug, thiserror::Error)]
pub enum SdkError {
// ── Adapter Errors ──
/// An error from the adapter implementation.
#[error("adapter error: {0}")]
Adapter(#[from] AdapterError),
/// Adapter output failed validation.
#[error("adapter output validation failed: {0}")]
InvalidAdapterOutput(String),
/// Adapter stream timed out.
#[error("adapter stream timeout after {0:?}")]
AdapterTimeout(Duration),
/// Adapter does not support the requested feature.
#[error("adapter does not support {0}")]
NotSupported(String),
// ── Runtime Errors ──
/// Terminal I/O error.
#[error("terminal error: {0}")]
Terminal(#[from] std::io::Error),
/// Event loop error.
#[error("event loop error: {0}")]
EventLoop(String),
/// Invalid mode transition.
#[error("mode transition failed: cannot go from {from} to {to}")]
InvalidModeTransition {
/// The current mode.
from: String,
/// The requested mode.
to: String,
},
// ── Input Errors ──
/// Interjection parse error.
#[error("interjection parse error: {0}")]
InterjectionParse(#[from] ParseError),
/// Slash command error.
#[error("slash command error: {0}")]
SlashCommand(String),
// ── Plugin Errors ──
/// Plugin system error.
#[cfg(feature = "plugins")]
#[error("plugin error: {0}")]
Plugin(#[from] PluginError),
// ── Configuration Errors ──
/// Builder configuration error.
#[error("builder error: {0}")]
Builder(String),
/// Serialization/deserialization error.
#[error("serialization error: {0}")]
Serialization(String),
}
#[derive(Debug, thiserror::Error, Clone)]
pub enum AdapterError {
/// Connection to the agent backend failed.
#[error("connection error: {0}")]
Connection(String),
/// The adapter received an invalid response from the backend.
#[error("protocol error: {0}")]
Protocol(String),
/// An I/O error occurred during adapter communication.
#[error("i/o error: {0}")]
Io(String),
/// The adapter operation timed out.
#[error("timeout: {0}")]
Timeout(String),
/// Authentication failed.
#[error("authentication error: {0}")]
Authentication(String),
/// The requested operation is not supported by this adapter.
#[error("not supported: {0}")]
NotSupported(String),
/// A generic adapter error.
#[error("{0}")]
Other(String),
}
#[derive(Debug, thiserror::Error, Clone, PartialEq, Eq)]
pub enum ParseError {
/// Input was empty or whitespace-only.
#[error("interjection input is empty")]
EmptyInput,
/// Input exceeded the maximum allowed length.
#[error("interjection too long: {0} chars (max {1})")]
TooLong(usize, usize),
/// Targeted agent name is invalid.
#[error("invalid agent target: {0}")]
InvalidTarget(String),
}
#[derive(Debug, thiserror::Error, Clone)]
pub enum PluginError {
/// WASM module failed structural validation.
#[error("WASM module failed validation: {0}")]
InvalidModule(String),
/// WASM module hash does not match the expected hash.
#[error("WASM hash mismatch: expected {expected}, got {actual}")]
HashMismatch {
/// Expected SHA-256 hash.
expected: String,
/// Actual computed SHA-256 hash.
actual: String,
},
/// Plugin does not export a required function.
#[error("plugin '{0}' missing required export: {1}")]
MissingExport(String, String),
/// Plugin requested a capability the host does not provide.
#[error("plugin '{0}' requested unsupported capability: {1}")]
UnsupportedCapability(String, String),
/// Capability was denied by the permission manager.
#[error("capability denied for plugin '{plugin}': {capability} -> {resource}")]
CapabilityDenied {
/// Plugin name.
plugin: String,
/// Capability kind.
capability: String,
/// Requested resource.
resource: String,
},
/// Plugin trapped during execution.
#[error("plugin '{0}' panicked during execution: {1}")]
PluginPanic(String, String),
/// Plugin not found in configured sources.
#[error("plugin '{0}' not found in configured sources")]
NotFound(String),
/// Plugin is disabled.
#[error("plugin '{0}' is disabled")]
Disabled(String),
/// Plugin configuration error.
#[error("plugin config error: {0}")]
Config(String),
/// Host function error.
#[error("plugin '{0}' host function error: {1}")]
HostFunction(String, String),
}external_editor.rs
Read declaration text · 4 declaration entries
#[derive(Debug, Error)]
pub enum ExternalEditorError {
/// Neither `$VISUAL` nor `$EDITOR` is set.
#[error("neither VISUAL nor EDITOR is set")]
MissingEditor,
/// Editor command failed to parse via `shlex` (POSIX) or
/// produced an empty argv on Windows.
#[error("failed to parse editor command")]
ParseFailed,
/// Resolved editor command was empty.
#[error("editor command is empty")]
EmptyCommand,
/// I/O failure (temp file creation, child process spawn, etc.).
#[error("editor io: {0}")]
Io(#[from] io::Error),
/// Editor exited with a non-zero status.
#[error("editor exited with status {0}")]
NonZeroExit(i32),
/// Editor was terminated by signal.
#[error("editor was terminated by signal")]
Terminated,
}
pub fn resolve_editor_command() -> Result<Vec<String>, ExternalEditorError>;
pub fn open_in_editor(seed: &str) -> Result<String, ExternalEditorError>;
pub fn open_with_command(seed: &str, editor_cmd: &[String]) -> Result<String, ExternalEditorError>;harness/component.rs
Read declaration text · 14 declaration entries
pub const HARNESS_COMPONENT_KINDS: &[HarnessComponentKind];
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum HarnessComponentKind {
/// `systemprompt.md` — base behavioral rules and prompt scaffold.
SystemPrompt,
/// `tool_descriptions/*.yaml` — declarations the model sees.
ToolDescriptions,
/// `tools/*` — the executable tool implementations.
ToolImplementations,
/// `middleware/*` — pre/post-processing hooks around tool calls.
Middleware,
/// `skills/{name}/` — reusable cross-task playbooks.
Skills,
/// `sub_agents/*.yaml` — optional sub-agent workflow configs.
SubAgents,
/// `LongTermMEMORY.md` — persistent cross-session knowledge.
LongTermMemory,
/// `ShortTermMEMORY.md` — runtime-only; **not** editable by the
/// evolve agent. Listed for exhaustiveness only.
ShortTermMemory,
}
#[must_use]
pub fn as_key(self) -> &'static str;
#[must_use]
pub fn label(self) -> &'static str;
#[must_use]
pub fn is_editable(self) -> bool;
#[must_use]
pub fn is_single_file(self) -> bool;
#[must_use]
pub fn mount(self) -> &'static Path;
#[must_use]
pub fn from_key(key: &str) -> Option<Self>;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct HarnessComponentEdit {
/// Which component kind the edit targets.
pub kind: HarnessComponentKind,
/// File path relative to the workspace root. For single-file
/// kinds this matches `kind.mount()`; for directory-backed kinds
/// it's a path *under* the directory (e.g. `tools/grep.py`).
pub path: PathBuf,
/// What the edit does.
pub op: HarnessComponentEditKind
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "op", rename_all = "snake_case")]
pub enum HarnessComponentEditKind {
/// Create a new file with the given UTF-8 contents.
Create {
/// Initial contents.
contents: String,
},
/// Replace the entire file with the given UTF-8 contents.
Update {
/// New contents.
contents: String,
},
/// Delete the file.
Delete,
/// Rename the file (path stays the same; the new name lives
/// under the same component kind).
Rename {
/// New path relative to the workspace root.
new_path: PathBuf,
},
}
#[must_use]
pub fn create(
kind: HarnessComponentKind,
path: impl Into<PathBuf>,
contents: impl Into<String>,
) -> Self;
#[must_use]
pub fn update(
kind: HarnessComponentKind,
path: impl Into<PathBuf>,
contents: impl Into<String>,
) -> Self;
#[must_use]
pub fn delete(kind: HarnessComponentKind, path: impl Into<PathBuf>) -> Self;
#[must_use]
pub fn rename(
kind: HarnessComponentKind,
path: impl Into<PathBuf>,
new_path: impl Into<PathBuf>,
) -> Self;harness/evidence.rs
Read declaration text · 19 declaration entries
#[derive(Debug, Error)]
pub enum EvidenceCorpusError {
/// I/O error reaching disk.
#[error("evidence corpus io: {0}")]
Io(#[from] io::Error),
/// Path escapes the iteration root (e.g. `..` segment).
#[error("path {0} escapes the iteration root")]
PathEscape(PathBuf),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TaskAnalysis {
/// Task name (matches `TaskOutcomeMap` keys).
pub task: String,
/// The per-iteration outcome being analyzed.
pub outcome: TaskOutcome,
/// One-line summary used in the overview.
pub summary: String,
/// Root cause hypothesis (free text).
pub root_cause: String,
/// Markdown body — the full evidence the Evolve Agent reads.
pub body_markdown: String
}
#[must_use]
pub fn render_markdown(&self) -> String;
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OverviewReport {
/// Iteration number.
pub iteration: u32,
/// Total tasks run.
pub total: usize,
/// Tasks that passed.
pub passes: usize,
/// Tasks that failed.
pub fails: usize,
/// Tasks that did not run.
pub not_run: usize,
/// Optional headline finding for the iteration.
#[serde(default)]
pub headline: String,
/// Optional markdown body (themes, top failure clusters, etc.).
#[serde(default)]
pub body_markdown: String
}
#[must_use]
pub fn render_markdown(&self) -> String;
#[derive(Debug, Clone)]
pub struct EvidenceCorpus {
}
pub fn open(runs_root: impl AsRef<Path>, iteration: u32) -> Result<Self, EvidenceCorpusError>;
#[must_use]
pub fn root(&self) -> &Path;
#[must_use]
pub fn iteration(&self) -> u32;
pub fn task_analysis_path(&self, task: &str) -> Result<PathBuf, EvidenceCorpusError>;
#[must_use]
pub fn overview_path(&self) -> PathBuf;
pub fn trace_path(&self, task: &str, run_idx: u32) -> Result<PathBuf, EvidenceCorpusError>;
pub fn write_task_analysis(
&self,
analysis: &TaskAnalysis,
) -> Result<PathBuf, EvidenceCorpusError>;
pub fn write_overview(
&self,
overview: &OverviewReport,
) -> Result<PathBuf, EvidenceCorpusError>;
pub fn write_trace(
&self,
task: &str,
run_idx: u32,
contents: &str,
) -> Result<PathBuf, EvidenceCorpusError>;
pub fn read_task_analysis_markdown(
&self,
task: &str,
) -> Result<Option<String>, EvidenceCorpusError>;
pub fn read_overview_markdown(&self) -> Result<Option<String>, EvidenceCorpusError>;
pub fn list_analyzed_tasks(&self) -> Result<Vec<String>, EvidenceCorpusError>;
pub fn list_traces(&self) -> Result<Vec<PathBuf>, EvidenceCorpusError>;harness/loop_driver.rs
Read declaration text · 24 declaration entries
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum HarnessLoopPhase {
/// Phase 1: run the benchmark with the current harness.
Rollout,
/// Phase 2: strip noise from trajectories.
Clean,
/// Phase 3: verify the prior iteration's manifest contracts.
Attribute,
/// Phase 4: AgentDebugger produces the EvidenceCorpus.
Distill,
/// Phase 5: Evolve Agent edits the workspace + emits manifest.
Evolve,
/// Phase 6: git-tag the iteration.
Commit,
}
#[must_use]
pub fn as_key(self) -> &'static str;
#[must_use]
pub fn label(self) -> &'static str;
#[must_use]
pub const fn ordering() -> [HarnessLoopPhase; 6];
#[must_use]
pub fn next(self) -> Option<HarnessLoopPhase>;
#[derive(Debug, Error)]
pub enum HarnessLoopError {
/// The caller invoked a phase out of order (e.g. `Distill`
/// before `Rollout` finished).
#[error("phase {got:?} attempted before {expected:?}")]
PhaseOutOfOrder {
/// Phase that should run next.
expected: HarnessLoopPhase,
/// Phase the caller tried to run.
got: HarnessLoopPhase,
},
/// Iteration is already complete; bump the counter before
/// attempting another phase.
#[error("iteration {iteration} is complete; advance to next iteration")]
IterationComplete {
/// Completed iteration number.
iteration: u32,
},
/// Workspace I/O error.
#[error(transparent)]
Workspace(#[from] HarnessWorkspaceError),
/// Evidence corpus I/O error.
#[error(transparent)]
Evidence(#[from] EvidenceCorpusError),
/// I/O error reaching the runs root.
#[error("loop io: {0}")]
Io(#[from] std::io::Error),
/// Caller-supplied phase callback failed.
#[error("phase {phase:?} failed: {reason}")]
PhaseFailed {
/// Phase whose callback returned an error.
phase: HarnessLoopPhase,
/// Free-form reason from the caller.
reason: String,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct IterationRecord {
/// Iteration number (matches the directory suffix).
pub iteration: u32,
/// Phases completed so far in canonical order.
pub completed_phases: Vec<HarnessLoopPhase>,
/// Per-task outcomes from this iteration's rollout (populated
/// after Phase 1).
#[serde(default)]
pub outcomes: TaskOutcomeMap,
/// Verdicts produced by the Attribute phase against the
/// *previous* iteration's manifest. Empty on iteration 1.
#[serde(default)]
pub verdicts: Vec<AttributionVerdict>,
/// Manifest produced by the Evolve phase. `None` until phase 5
/// completes.
#[serde(default)]
pub manifest: Option<ChangeManifest>,
/// UNIX seconds the iteration was started.
pub started_at_unix_secs: u64
}
#[derive(Debug)]
pub struct StandardHarnessLoop {
}
pub fn start(
runs_root: impl Into<PathBuf>,
workspace: HarnessWorkspace,
iteration: u32,
) -> Result<Self, HarnessLoopError>;
pub fn with_prior(mut self, manifest: ChangeManifest, outcomes: TaskOutcomeMap) -> Self;
#[must_use]
pub fn record(&self) -> &IterationRecord;
#[must_use]
pub fn iteration(&self) -> u32;
#[must_use]
pub fn next_phase(&self) -> Option<HarnessLoopPhase>;
#[must_use]
pub fn is_complete(&self) -> bool;
#[must_use]
pub fn iteration_dir(&self) -> PathBuf;
pub fn open_corpus(&self) -> Result<EvidenceCorpus, HarnessLoopError>;
#[must_use]
pub fn workspace(&self) -> &HarnessWorkspace;
pub fn run_rollout(
&mut self,
outcomes: TaskOutcomeMap,
) -> Result<HarnessLoopPhase, HarnessLoopError>;
pub fn run_clean(
&mut self,
cleanup: impl FnOnce(&Path) -> Result<(), String>,
) -> Result<HarnessLoopPhase, HarnessLoopError>;
pub fn run_attribute(&mut self) -> Result<HarnessLoopPhase, HarnessLoopError>;
pub fn run_distill(
&mut self,
debug: impl FnOnce(&EvidenceCorpus) -> Result<(), String>,
) -> Result<HarnessLoopPhase, HarnessLoopError>;
pub fn run_evolve(
&mut self,
evolve: impl FnOnce(&HarnessWorkspace, &EvidenceCorpus) -> Result<ChangeManifest, String>,
) -> Result<HarnessLoopPhase, HarnessLoopError>;
pub fn run_commit(
&mut self,
commit: impl FnOnce(&IterationRecord) -> Result<(), String>,
) -> Result<HarnessLoopPhase, HarnessLoopError>;
#[must_use]
pub fn loop_record_path(&self) -> PathBuf;harness/manifest.rs
Read declaration text · 32 declaration entries
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TaskOutcome {
/// Task passed.
Pass,
/// Task failed.
Fail,
/// Task was not run (e.g. crashed, skipped).
NotRun,
}
#[must_use]
pub fn is_pass(self) -> bool;
#[must_use]
pub fn is_fail(self) -> bool;
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct TaskOutcomeMap {
/// Map keyed by task name. `BTreeMap` so serialization is
/// deterministic (matters for diffing manifests across runs).
pub outcomes: BTreeMap<String, TaskOutcome>
}
#[must_use]
pub fn from_pairs<I, S>(it: I) -> Self
where
I: IntoIterator<Item = (S, TaskOutcome)>,
S: Into<String>,;
#[must_use]
pub fn outcome(&self, task: &str) -> TaskOutcome;
pub fn set(&mut self, task: impl Into<String>, outcome: TaskOutcome);
pub fn iter(&self) -> impl Iterator<Item = (&str, TaskOutcome)>;
#[must_use]
pub fn len(&self) -> usize;
#[must_use]
pub fn is_empty(&self) -> bool;
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct PredictedImpact {
/// Tasks the evolve agent expects this edit to *fix* (move from
/// `Fail` → `Pass`).
#[serde(default)]
pub expected_fixes: Vec<String>,
/// Tasks the evolve agent flags as at risk of regressing
/// (currently `Pass`, may move to `Fail`).
#[serde(default)]
pub at_risk_regressions: Vec<String>
}
#[must_use]
pub fn new(
expected_fixes: impl IntoIterator<Item = impl Into<String>>,
at_risk_regressions: impl IntoIterator<Item = impl Into<String>>,
) -> Self;
#[must_use]
pub fn is_empty(&self) -> bool;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ManifestEntry {
/// Stable id (uuid string). Lets verdicts and audit trails
/// reference an entry independent of array position.
pub id: String,
/// Free-form list of task failures the edit addresses (e.g.
/// task names + one-line justification).
#[serde(default)]
pub failure_evidence: Vec<String>,
/// Diagnosed root cause behind those failures.
pub root_cause: String,
/// One-line summary of the targeted fix the edit applies.
pub targeted_fix: String,
/// Predicted impact (the falsifiable contract).
pub predicted_impact: PredictedImpact,
/// The actual edit applied to the workspace.
pub edit: HarnessComponentEdit
}
#[must_use]
pub fn new(
failure_evidence: impl IntoIterator<Item = impl Into<String>>,
root_cause: impl Into<String>,
targeted_fix: impl Into<String>,
predicted_impact: PredictedImpact,
edit: HarnessComponentEdit,
) -> Self;
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct ChangeManifest {
/// Iteration this manifest belongs to (e.g. `iteration_007`).
pub iteration: u32,
/// Entries in application order.
pub entries: Vec<ManifestEntry>
}
#[must_use]
pub fn new(iteration: u32) -> Self;
pub fn push(&mut self, entry: ManifestEntry) -> usize;
#[must_use]
pub fn len(&self) -> usize;
#[must_use]
pub fn is_empty(&self) -> bool;
#[must_use]
pub fn find(&self, id: &str) -> Option<&ManifestEntry>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AttributionDecision {
/// Every promised fix landed AND no flagged regression broke.
/// The edit is kept.
Confirmed,
/// Some promised fixes landed; some flagged regressions
/// broke. The loop driver decides whether to keep or revert.
PartiallyConfirmed,
/// No promised fixes landed (or every flagged regression
/// broke). The edit is reverted.
Refuted,
/// The contract was silent (`PredictedImpact::is_empty()`); the
/// edit cannot be falsified and is treated as refuted by
/// default — the AHE paper requires a non-trivial contract.
UnfalsifiableContract,
}
#[must_use]
pub fn is_keep(self) -> bool;
#[must_use]
pub fn is_revert(self) -> bool;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TaskDelta {
/// Task name.
pub task: String,
/// Outcome before the edit (i.e. the prior iteration's run).
pub before: TaskOutcome,
/// Outcome after the edit (this iteration's run).
pub after: TaskOutcome
}
#[must_use]
pub fn is_fix(&self) -> bool;
#[must_use]
pub fn is_regression(&self) -> bool;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AttributionVerdict {
/// Manifest entry id this verdict belongs to.
pub entry_id: String,
/// Decision (`Confirmed` / `PartiallyConfirmed` / `Refuted` /
/// `UnfalsifiableContract`).
pub decision: AttributionDecision,
/// Promised fixes that actually landed.
pub confirmed_fixes: Vec<TaskDelta>,
/// Promised fixes that did **not** land.
pub missed_fixes: Vec<TaskDelta>,
/// Regressions the contract flagged that DID happen.
pub triggered_regressions: Vec<TaskDelta>,
/// Regressions the contract flagged that did NOT happen
/// (kept stable).
pub avoided_regressions: Vec<TaskDelta>
}
#[must_use]
pub fn is_keep(&self) -> bool;
#[must_use]
pub fn is_revert(&self) -> bool;
#[must_use]
pub fn attribute(
manifest: &ChangeManifest,
before: &TaskOutcomeMap,
after: &TaskOutcomeMap,
) -> Vec<AttributionVerdict>;
#[must_use]
pub fn attribute_entry(
entry: &ManifestEntry,
before: &TaskOutcomeMap,
after: &TaskOutcomeMap,
) -> AttributionVerdict;harness/mod.rs
Read declaration text · 10 declaration entries
pub mod component;
pub mod evidence;
pub mod loop_driver;
pub mod manifest;
pub mod workspace;
pub use component::{
HarnessComponentEdit, HarnessComponentEditKind, HarnessComponentKind, HARNESS_COMPONENT_KINDS,
};
pub use evidence::{EvidenceCorpus, EvidenceCorpusError, OverviewReport, TaskAnalysis};
pub use loop_driver::{HarnessLoopError, HarnessLoopPhase, IterationRecord, StandardHarnessLoop};
pub use manifest::{
attribute, attribute_entry, AttributionDecision, AttributionVerdict, ChangeManifest,
ManifestEntry, PredictedImpact, TaskDelta, TaskOutcome, TaskOutcomeMap,
};
pub use workspace::{HarnessWorkspace, HarnessWorkspaceError};harness/workspace.rs
Read declaration text · 11 declaration entries
#[derive(Debug, Error)]
pub enum HarnessWorkspaceError {
/// I/O error reaching the workspace.
#[error("workspace io: {0}")]
Io(#[from] io::Error),
/// A path escapes the workspace root (e.g. `..`).
#[error("path {0} escapes the workspace root")]
PathEscape(PathBuf),
/// An edit targeted a non-editable component (i.e.
/// [`HarnessComponentKind::ShortTermMemory`]).
#[error("component {0:?} is not editable")]
NotEditable(HarnessComponentKind),
/// Edit path does not live under the component's mount point.
#[error("path {path:?} does not live under the {kind:?} mount {mount:?}")]
MountMismatch {
/// The kind whose mount the path was supposed to live under.
kind: HarnessComponentKind,
/// The path the caller supplied.
path: PathBuf,
/// The expected mount.
mount: PathBuf,
},
}
#[derive(Debug, Clone)]
pub struct HarnessWorkspace {
}
pub fn open(root: impl Into<PathBuf>) -> Result<Self, HarnessWorkspaceError>;
#[must_use]
pub fn root(&self) -> &Path;
#[must_use]
pub fn mount_path(&self, kind: HarnessComponentKind) -> PathBuf;
pub fn read_single_file(
&self,
kind: HarnessComponentKind,
) -> Result<Option<String>, HarnessWorkspaceError>;
pub fn write_single_file(
&self,
kind: HarnessComponentKind,
contents: &str,
) -> Result<PathBuf, HarnessWorkspaceError>;
pub fn list_directory(
&self,
kind: HarnessComponentKind,
) -> Result<Vec<PathBuf>, HarnessWorkspaceError>;
pub fn read_directory_file(
&self,
kind: HarnessComponentKind,
path: impl AsRef<Path>,
) -> Result<Option<String>, HarnessWorkspaceError>;
pub fn apply_edit(
&self,
edit: &HarnessComponentEdit,
) -> Result<PathBuf, HarnessWorkspaceError>;
pub fn apply_batch(
&self,
edits: &[HarnessComponentEdit],
) -> Result<Vec<PathBuf>, HarnessWorkspaceError>;interjection/delivery.rs
Read declaration text · 1 declaration entries
pub async fn deliver_interjection(
adapter: &Arc<dyn AgentAdapter>,
interjection: &HumanInterjection,
) -> Result<InterjectionAck, SdkError>;interjection/mod.rs
Read declaration text · 3 declaration entries
pub mod delivery;
pub mod parser;
pub mod sanitizer;interjection/parser.rs
Read declaration text · 1 declaration entries
pub fn parse_interjection(raw: &str) -> Result<HumanInterjection, ParseError>;interjection/sanitizer.rs
Read declaration text · 2 declaration entries
#[must_use]
pub fn sanitize_input(input: &str) -> String;
#[must_use]
pub fn sanitize_output(text: &str) -> String;keymap/action.rs
Read declaration text · 2 declaration entries
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Action {
// ── Composer ──
/// Submit the current input.
Submit,
/// Cancel the current operation (clears input, dismisses overlay,
/// stops a streaming response, etc. — the handler decides).
Cancel,
/// Insert a literal newline in the composer.
InsertNewline,
// ── App lifecycle ──
/// Quit the application.
Quit,
/// Clear the chat / activity log.
ClearHistory,
/// Clear the terminal scrollback.
ClearTerminal,
// ── Layout ──
/// Toggle the sidebar between expanded and collapsed.
ToggleSidebar,
/// Switch between Chat and Autonomy modes.
ToggleMode,
/// Stop the active autonomy session.
StopAutonomy,
// ── Overlays ──
/// Open the slash-command palette.
OpenPalette,
/// Open the transcript / pager overlay.
OpenTranscript,
/// Open the resume picker.
OpenResumePicker,
/// Open the user's `$EDITOR` for the current draft.
OpenExternalEditor,
// ── Scrolling ──
/// Scroll one page up.
ScrollPageUp,
/// Scroll one page down.
ScrollPageDown,
/// Scroll one half-page up.
ScrollHalfPageUp,
/// Scroll one half-page down.
ScrollHalfPageDown,
/// Jump to the top of the chat / pager.
ScrollHome,
/// Jump to the bottom of the chat / pager.
ScrollEnd,
// ── Approvals ──
/// Approve the current pending request once.
ApproveOnce,
/// Approve the current pending request and persist the suggested
/// glob pattern.
ApproveAlways,
/// Deny the current pending request.
Deny,
}
#[must_use]
pub fn key(self) -> &'static str;keymap/binding.rs
Read declaration text · 10 declaration entries
#[derive(Debug, Error, PartialEq, Eq)]
pub enum KeySpecError {
/// The spec is empty or whitespace-only.
#[error("empty key spec")]
Empty,
/// A modifier token was not one of `ctrl`, `alt`, `shift`, `meta`.
#[error("unknown modifier: {0}")]
UnknownModifier(String),
/// The terminal token did not name a key we know.
#[error("unknown key: {0}")]
UnknownKey(String),
/// The chord referenced more than the supported two segments.
#[error("chord too long: {0}")]
ChordTooLong(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct KeyBinding {
/// Optional first half of a chord (`Ctrl+X` in `Ctrl+X Ctrl+E`).
/// `None` for non-chord bindings.
pub prefix: Option<KeyChordHalf>,
/// The terminal half (always set).
pub terminal: KeyChordHalf
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct KeyChordHalf {
/// The key code.
pub code: KeyCode,
/// Modifier mask.
pub modifiers: KeyModifiers
}
#[must_use]
pub fn single(code: KeyCode, modifiers: KeyModifiers) -> Self;
#[must_use]
pub fn chord(prefix: KeyChordHalf, terminal: KeyChordHalf) -> Self;
#[must_use]
pub fn is_chord(&self) -> bool;
#[must_use]
pub fn matches_event(&self, ev: &KeyEvent) -> bool;
#[must_use]
pub fn matches_prefix(&self, ev: &KeyEvent) -> bool;
pub fn parse_key_spec(spec: &str) -> Result<KeyBinding, KeySpecError>;
pub fn parse_key_spec_chord(spec: &str) -> Result<KeyBinding, KeySpecError>;keymap/contextual.rs
Read declaration text · 7 declaration entries
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum KeymapContext {
/// App-wide bindings always active (Ctrl+C quit, Ctrl+B sidebar
/// toggle, …).
App,
/// Chat surface focused.
Chat,
/// Composer / input bar focused.
Composer,
/// Pager overlay open.
Pager,
/// Generic list picker (resume / theme / model / backtrack /
/// component-tree).
List,
/// Approval modal up.
Approval,
}
#[derive(Debug, Clone)]
pub struct ContextualKeymap {
}
#[must_use]
pub fn with_defaults() -> Self;
#[must_use]
pub fn for_context_mut(&mut self, ctx: KeymapContext) -> &mut Keymap;
#[must_use]
pub fn for_context(&self, ctx: KeymapContext) -> &Keymap;
#[must_use]
pub fn resolve(&self, ctx: KeymapContext, ev: &KeyEvent) -> Option<Action>;
pub fn apply_override(
&mut self,
ctx: KeymapContext,
overrides: &std::collections::HashMap<Action, Vec<String>>,
) -> Result<(), KeymapError>;keymap/mod.rs
Read declaration text · 4 declaration entries
pub use action::Action;
pub use binding::{parse_key_spec, parse_key_spec_chord, KeyBinding, KeySpecError};
pub use contextual::{ContextualKeymap, KeymapContext};
pub use runtime::{Keymap, KeymapError};keymap/runtime.rs
Read declaration text · 9 declaration entries
#[derive(Debug, Error)]
pub enum KeymapError {
/// One of the override spec strings failed to parse.
#[error("invalid key spec for {action:?}: {source}")]
Spec {
/// Which action's binding spec failed.
action: Action,
/// Original parse error.
#[source]
source: KeySpecError,
},
}
#[derive(Debug, Clone)]
pub struct Keymap {
}
#[must_use]
pub fn with_defaults() -> Self;
#[must_use]
pub fn empty() -> Self;
pub fn from_overrides(overrides: &HashMap<Action, Vec<String>>) -> Result<Self, KeymapError>;
#[must_use]
pub fn bindings_for(&self, action: Action) -> &[KeyBinding];
#[must_use]
pub fn resolve(&self, ev: &KeyEvent) -> Option<Action>;
#[must_use]
pub fn resolve_chord_prefix(&self, ev: &KeyEvent) -> Option<Action>;
#[must_use]
pub fn resolve_chord_terminal(
&self,
prefix_event: &KeyEvent,
terminal_event: &KeyEvent,
) -> Option<Action>;lib.rs
Read declaration text · 41 declaration entries
pub mod adapter;
pub mod backtrack;
pub mod clipboard;
pub mod composer;
pub mod error;
pub mod external_editor;
pub mod harness;
pub mod keymap;
pub mod onboarding;
pub mod session;
pub mod settings;
pub mod types;
pub mod workspace;
pub mod interjection;
pub mod validation;
pub mod commands;
pub mod modes;
pub mod runtime;
pub mod screens;
pub mod adapters;
#[cfg(feature = "plugins")]
pub mod plugins;
pub use error::{AdapterError, ParseError, PluginError, SdkError};
pub use session::{
JsonlSessionStore, SessionMetadata, SessionRecord, SessionRecordKind, SessionStore,
SessionStoreError,
};
pub use keymap::{
parse_key_spec, parse_key_spec_chord, Action, ContextualKeymap, KeyBinding, KeySpecError,
Keymap, KeymapContext, KeymapError,
};
pub use backtrack::{list_backtrack_targets, rewind_to, BacktrackTarget};
pub use composer::{HistorySearch, MessageQueue, MessageQueueError, MESSAGE_QUEUE_CAPACITY};
pub use settings::{
FlocksCli, ModeInfo, ModelInfo, ProviderInfo, ProviderKind, ProviderSettingField,
ProviderSettingKind, ProviderSettingOption, SettingsAction, SettingsApplyResult,
SettingsSnapshot,
};
pub use clipboard::{Clipboard, ClipboardError, MemoryClipboard, SystemClipboard};
pub use external_editor::{
open_in_editor, open_with_command, resolve_editor_command, ExternalEditorError,
};
pub use onboarding::{OnboardingError, OnboardingFlow, OnboardingSelection, OnboardingStep};
pub use workspace::complete_workspace_paths;
pub use harness::{
attribute, attribute_entry, AttributionDecision, AttributionVerdict, ChangeManifest,
EvidenceCorpus, EvidenceCorpusError, HarnessComponentEdit, HarnessComponentEditKind,
HarnessComponentKind, HarnessLoopError, HarnessLoopPhase, HarnessWorkspace,
HarnessWorkspaceError, IterationRecord, ManifestEntry, OverviewReport, PredictedImpact,
StandardHarnessLoop, TaskAnalysis, TaskDelta, TaskOutcome, TaskOutcomeMap,
HARNESS_COMPONENT_KINDS,
};
pub use types::{
ActivityLevel, AdapterCapabilities, AutonomyEvent, HumanInterjection, InterjectionAck,
InterjectionKind, InterjectionPriority, Mode, ResponseChunk, SdkAgentInfo, SdkAgentStatus,
SdkApprovalAction, SdkApprovalRequest, SdkRiskLevel, SdkRole, SessionInfo,
};
pub use types::{
DEFAULT_MAX_MESSAGES, DEFAULT_STREAM_TIMEOUT, MAX_AGENT_ID_LEN, MAX_AGENT_NAME_LEN,
MAX_CHUNK_SIZE, MAX_INTERJECTION_LEN, MAX_TOOL_INPUT_SIZE,
};
pub use adapter::AgentAdapter;
pub use runtime::app::{AgentApp, AgentAppBuilder};
pub use runtime::terminal_control::{
clear_title, hyperlink, ring_bell, set_title, write_hyperlink, MAX_HYPERLINK_URL_LEN,
MAX_TITLE_LEN,
};
pub use runtime::notifications::{
KindMask, NotificationKind, Notifier, NotifierConfig, MAX_NOTIFICATION_LEN,
};
pub use screens::custom::{CustomScreen, ScreenEvent, ScreenResult};
pub use adapters::stdio::StdioAdapter;
#[cfg(feature = "http")]
pub use adapters::http::HttpAdapter;modes/autonomy.rs
Read declaration text · 4 declaration entries
pub async fn start_autonomy_session(
state: &mut AppState,
adapter: &Arc<dyn AgentAdapter>,
instructions: &str,
) -> Result<futures::stream::BoxStream<'static, AutonomyEvent>, SdkError>;
pub async fn stop_autonomy_session(
state: &mut AppState,
adapter: &Arc<dyn AgentAdapter>,
) -> Result<(), SdkError>;
pub fn handle_autonomy_event(state: &mut AppState, event: AutonomyEvent) -> Result<(), SdkError>;
pub async fn submit_approval(
state: &mut AppState,
adapter: &Arc<dyn AgentAdapter>,
request_id: &str,
action: SdkApprovalAction,
) -> Result<(), SdkError>;modes/chat.rs
Read declaration text · 2 declaration entries
pub async fn send_chat_message(
state: &mut AppState,
adapter: &Arc<dyn AgentAdapter>,
message: String,
) -> Result<futures::stream::BoxStream<'static, ResponseChunk>, SdkError>;
pub fn handle_response_chunk(state: &mut AppState, chunk: ResponseChunk) -> Result<(), SdkError>;modes/mod.rs
Read declaration text · 2 declaration entries
pub mod autonomy;
pub mod chat;onboarding.rs
Read declaration text · 16 declaration entries
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum OnboardingStep {
/// Initial welcome screen (one-time intro copy + ToS confirm).
Welcome,
/// Theme picker.
ChooseTheme,
/// Model picker.
ChooseModel,
/// Workspace root confirmation (the cwd Codex / clausen will
/// operate inside).
ConfirmWorkspace,
/// Onboarding finished.
Done,
}
#[derive(Debug, Error, PartialEq, Eq)]
pub enum OnboardingError {
/// `advance` / `back` was called from a state that does not allow
/// the requested transition (already at start / end).
#[error("invalid transition from {from:?} via {action}")]
InvalidTransition {
/// State the flow was in.
from: OnboardingStep,
/// Attempted action ("advance", "back", "skip", …).
action: &'static str,
},
/// A required selection was missing when `advance` was called.
#[error("step {step:?} requires a selection before advancing")]
SelectionRequired {
/// Step that needs a selection.
step: OnboardingStep,
},
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct OnboardingSelection {
/// Selected theme id (e.g. `"monochrome"`). `None` until the
/// user activates a row in the theme picker.
pub theme_id: Option<String>,
/// Selected model id (e.g. `"claude-opus-4-7"`). `None` until
/// the user activates a row in the model picker.
pub model_id: Option<String>,
/// Confirmed workspace root display string. `None` until
/// confirmed.
pub workspace_root: Option<String>,
/// Whether the user accepted the ToS / first-launch notice.
pub welcome_accepted: bool
}
#[derive(Debug, Clone)]
pub struct OnboardingFlow {
}
#[must_use]
pub fn new() -> Self;
#[must_use]
pub fn from_selection(selection: OnboardingSelection) -> Self;
#[must_use]
pub fn step(&self) -> OnboardingStep;
#[must_use]
pub fn selection(&self) -> &OnboardingSelection;
pub fn accept_welcome(&mut self);
pub fn set_theme(&mut self, theme_id: impl Into<String>);
pub fn set_model(&mut self, model_id: impl Into<String>);
pub fn set_workspace(&mut self, workspace_root: impl Into<String>);
pub fn advance(&mut self) -> Result<OnboardingStep, OnboardingError>;
pub fn back(&mut self) -> Result<OnboardingStep, OnboardingError>;
pub fn skip(&mut self) -> Result<OnboardingStep, OnboardingError>;
#[must_use]
pub fn is_done(&self) -> bool;plugins/capability.rs
Read declaration text · 12 declaration entries
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Capability {
/// The kind of capability.
pub kind: CapabilityKind,
/// The specific resource (URL, path, command).
pub resource: String
}
#[must_use]
pub fn new(kind: CapabilityKind, resource: impl Into<String>) -> Self;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum CapabilityKind {
/// Network access (HTTP, DNS, WebSocket).
Network,
/// Filesystem read access.
FileRead,
/// Filesystem write access.
FileWrite,
/// Shell command execution.
Shell,
/// Plugin state storage (scoped to the plugin).
Storage,
}
#[must_use]
pub const fn label(&self) -> &'static str;
#[must_use]
pub const fn risk_level(&self) -> u8;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct CapabilityGrants {
}
#[must_use]
pub fn new() -> Self;
pub fn add(&mut self, kind: CapabilityKind, mode: ApprovalMode);
#[must_use]
pub fn has(&self, kind: CapabilityKind) -> bool;
#[must_use]
pub fn mode(&self, kind: CapabilityKind) -> Option<&ApprovalMode>;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ApprovalMode {
/// Always allow without asking.
Allow,
/// Always deny without asking.
Deny,
/// Ask the user each time.
Prompt,
/// Allow if the resource matches a pattern.
AllowPattern(String),
}
#[must_use]
pub fn requires_user_input(&self) -> bool;plugins/config.rs
Read declaration text · 4 declaration entries
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct PluginConfig {
/// Directory containing plugin WASM files.
pub plugin_dir: Option<PathBuf>,
/// Path to `plugins.toml` for persisted permission rules.
pub config_path: Option<PathBuf>,
/// Per-plugin configuration overrides.
pub plugins: HashMap<String, PluginEntry>
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PluginEntry {
/// Whether the plugin is enabled.
pub enabled: bool,
/// Path to the WASM file (overrides manifest).
pub path: Option<String>,
/// Permission rules for this plugin.
#[serde(default)]
pub permissions: Vec<PermissionRuleConfig>
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PermissionRuleConfig {
/// Capability kind as string.
pub capability: String,
/// Glob pattern.
pub pattern: String,
/// "allow", "deny", or "prompt".
pub mode: String
}
#[must_use]
pub fn load_or_default(path: Option<&PathBuf>) -> Self;plugins/draw_command.rs
Read declaration text · 2 declaration entries
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum DrawCommand {
/// Draw text at a position.
Text {
/// X coordinate (column).
x: u16,
/// Y coordinate (row).
y: u16,
/// Text content.
text: String,
/// Foreground color as RGB hex (e.g., "#ff0000").
fg: Option<String>,
/// Background color as RGB hex.
bg: Option<String>,
/// Whether to render as bold.
bold: bool,
},
/// Fill a rectangle with a character.
Fill {
/// X coordinate.
x: u16,
/// Y coordinate.
y: u16,
/// Width.
width: u16,
/// Height.
height: u16,
/// Fill character.
char: char,
/// Foreground color.
fg: Option<String>,
/// Background color.
bg: Option<String>,
},
/// Draw a horizontal line.
HLine {
/// X coordinate.
x: u16,
/// Y coordinate.
y: u16,
/// Length.
length: u16,
/// Character to use.
char: char,
},
/// Draw a vertical line.
VLine {
/// X coordinate.
x: u16,
/// Y coordinate.
y: u16,
/// Length.
length: u16,
/// Character to use.
char: char,
},
/// Clear a rectangular area.
Clear {
/// X coordinate.
x: u16,
/// Y coordinate.
y: u16,
/// Width.
width: u16,
/// Height.
height: u16,
},
}
#[must_use]
pub fn parse_hex_color(hex: &str) -> Option<(u8, u8, u8)>;plugins/host_functions.rs
Read declaration text · 4 declaration entries
pub fn check_capability(
permissions: &PermissionManager,
plugin: &str,
capability: &Capability,
) -> Result<CapabilityCheckResult, PluginError>;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CapabilityCheckResult {
/// The capability is allowed.
Allowed,
/// The user needs to be prompted.
NeedsPrompt,
}
pub fn validate_file_path(plugin: &str, path: &str) -> Result<String, PluginError>;
#[must_use]
pub fn scoped_storage_key(plugin: &str, key: &str) -> String;plugins/manifest.rs
Read declaration text · 5 declaration entries
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PluginManifest {
/// Plugin name (unique identifier).
pub name: String,
/// Semantic version string.
pub version: String,
/// Short description.
pub description: String,
/// Author name or organization.
pub author: String,
/// Path to the WASM module file.
pub wasm_path: String,
/// Expected SHA-256 hash of the WASM module (hex-encoded).
pub wasm_sha256: Option<String>,
/// Capabilities the plugin requires.
pub capabilities: Vec<CapabilityKind>,
/// Slash commands the plugin registers.
pub commands: Vec<PluginCommand>,
/// Agent tools the plugin provides.
pub tools: Vec<PluginTool>
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PluginCommand {
/// Command name (without `/` prefix).
pub name: String,
/// Short description.
pub description: String
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PluginTool {
/// Tool name.
pub name: String,
/// Tool description.
pub description: String,
/// JSON schema for tool input (as a string).
pub input_schema: String
}
pub fn from_path(path: &str) -> Result<Self, PluginError>;
pub fn validate(&self) -> Result<(), PluginError>;plugins/mod.rs
Read declaration text · 18 declaration entries
pub mod capability;
pub mod config;
pub mod draw_command;
pub mod host_functions;
pub mod manifest;
pub mod permission;
pub mod registry;
pub mod wasm;
pub struct PluginManager {
}
#[must_use]
pub fn new() -> Self;
#[must_use]
pub fn with_config(config: PluginConfig) -> Self;
pub async fn load_plugin(&self, path: &str) -> Result<(), PluginError>;
pub async fn unload_plugin(&self, name: &str) -> Result<(), PluginError>;
pub async fn list_plugins(&self) -> Vec<String>;
pub async fn is_enabled(&self, name: &str) -> bool;
pub async fn call_command(
&self,
plugin: &str,
command: &str,
args: &str,
) -> Result<Option<String>, PluginError>;
pub async fn call_tool(
&self,
plugin: &str,
tool: &str,
input: &str,
) -> Result<Option<String>, PluginError>;
#[must_use]
pub fn permissions(&self) -> &Arc<PermissionManager>;plugins/permission.rs
Read declaration text · 9 declaration entries
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PermissionRule {
/// Plugin name this rule applies to.
pub plugin: String,
/// Capability kind.
pub kind: CapabilityKind,
/// Glob pattern matching the resource.
pub pattern: String,
/// What to do when the pattern matches.
pub mode: ApprovalMode
}
#[derive(Debug)]
pub struct PendingPermission {
/// The plugin requesting the capability.
pub plugin: String,
/// The requested capability.
pub capability: Capability,
/// Channel to send the user's decision.
pub response_tx: tokio::sync::oneshot::Sender<PermissionDecision>
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PermissionDecision {
/// Allow this specific request once.
AllowOnce,
/// Always allow requests matching the given pattern.
AlwaysAllow(String),
/// Deny this request.
Deny,
}
pub struct PermissionManager {
}
#[must_use]
pub fn new() -> Self;
pub fn add_rule(&self, rule: PermissionRule);
#[must_use]
pub fn check(&self, plugin: &str, capability: &Capability) -> Option<ApprovalMode>;
pub fn revoke_all(&self, plugin: &str);
#[must_use]
pub fn rules_for(&self, plugin: &str) -> Vec<PermissionRule>;plugins/registry.rs
Read declaration text · 5 declaration entries
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum PluginSource {
/// A local filesystem path.
Local {
/// Path to the plugin directory or WASM file.
path: String,
},
/// A Git repository.
Git {
/// Git repository URL.
url: String,
/// Branch or tag (default: main).
#[serde(default = "default_git_ref")]
git_ref: String,
/// Path within the repository.
path: Option<String>,
},
/// A plugin index/registry.
Index {
/// Registry URL.
url: String,
/// Plugin name.
name: String,
/// Version constraint.
version: Option<String>,
},
}
#[must_use]
pub fn local(path: impl Into<String>) -> Self;
#[must_use]
pub fn git(url: impl Into<String>) -> Self;
#[must_use]
pub fn index(url: impl Into<String>, name: impl Into<String>) -> Self;
pub fn verify_wasm_hash(path: &str, expected_hash: &str) -> Result<(), PluginError>;plugins/wasm.rs
Read declaration text · 13 declaration entries
pub const DEFAULT_MEMORY_LIMIT: usize;
pub struct PluginData {
/// Plugin name for scoping operations and error messages.
pub name: String,
/// Plugin state storage (key-value, scoped by plugin name).
pub storage: HashMap<String, Vec<u8>>,
/// Log buffer for captured plugin output.
pub log_buffer: Vec<String>,
/// Permission manager reference for capability checks.
pub permissions: Arc<PermissionManager>
}
pub struct PluginInstance {
}
pub fn create_engine() -> Result<Engine, PluginError>;
pub fn compile_module(engine: &Engine, path: &str) -> Result<Module, PluginError>;
pub fn validate_exports(module: &Module, plugin_name: &str) -> Result<(), PluginError>;
pub fn instantiate_plugin(
engine: &Engine,
module: &Module,
name: &str,
permissions: Arc<PermissionManager>,
) -> Result<PluginInstance, PluginError>;
#[must_use]
pub fn plugin_name(&self) -> &str;
pub fn call_init(&mut self) -> Result<(), PluginError>;
pub fn call_name(&mut self) -> Result<String, PluginError>;
pub fn call_command(
&mut self,
cmd_name: &str,
args_json: &str,
) -> Result<Option<String>, PluginError>;
pub fn call_tool(
&mut self,
tool_name: &str,
input_json: &str,
) -> Result<Option<String>, PluginError>;
pub fn drain_logs(&mut self) -> Vec<String>;runtime/app.rs
Read declaration text · 12 declaration entries
pub struct AgentApp {
}
#[must_use]
pub fn builder() -> AgentAppBuilder;
pub async fn run(self) -> Result<(), SdkError>;
pub struct AgentAppBuilder {
}
#[must_use]
pub fn welcome(mut self, config: WelcomeConfig) -> Self;
#[must_use]
pub fn name(mut self, name: impl Into<String>) -> Self;
#[must_use]
pub fn adapter<A: AgentAdapter>(mut self, adapter: A) -> Self;
#[must_use]
pub fn adapter_arc(mut self, adapter: Arc<dyn AgentAdapter>) -> Self;
#[must_use]
pub fn theme(mut self, theme: Theme) -> Self;
#[must_use]
pub fn commands(mut self, commands: SlashCommandRegistry) -> Self;
#[must_use]
pub fn max_messages(mut self, max: usize) -> Self;
pub fn build(self) -> Result<AgentApp, SdkError>;runtime/event.rs
Read declaration text · 3 declaration entries
#[derive(Debug)]
pub enum AppEvent {
/// A terminal event (keyboard, mouse, resize).
Terminal(CrosstermEvent),
/// A response chunk from the adapter's response stream.
AdapterResponse(ResponseChunk),
/// An autonomy event from the adapter's autonomy stream.
Autonomy(AutonomyEvent),
/// An approval decision from the user.
ApprovalDecision {
/// The approval request ID.
request_id: String,
/// The user's decision.
action: SdkApprovalAction,
},
/// A tick event for animations and elapsed time updates.
Tick,
/// A shutdown signal was received.
Shutdown,
}
#[must_use]
pub fn is_shutdown(&self) -> bool;
#[must_use]
pub fn is_terminal(&self) -> bool;runtime/event_loop.rs
Read declaration text · 1 declaration entries
pub async fn run_event_loop(
terminal: &mut SdkTerminal,
state: &mut AppState,
adapter: Arc<dyn AgentAdapter>,
theme: &Theme,
mut shutdown_rx: mpsc::Receiver<()>,
commands: &SlashCommandRegistry,
) -> Result<(), SdkError>;runtime/mod.rs
Read declaration text · 8 declaration entries
pub mod app;
pub mod event;
pub mod event_loop;
pub mod notifications;
pub mod signals;
pub mod state;
pub mod terminal;
pub mod terminal_control;runtime/notifications.rs
Read declaration text · 15 declaration entries
pub const MAX_NOTIFICATION_LEN: usize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum NotificationKind {
/// Streaming response just finished.
AgentTurnComplete,
/// Adapter raised an approval request that requires user input.
ApprovalNeeded,
/// A long-running tool call completed.
ToolCallComplete,
/// Catastrophic failure surfaced to the user.
Error,
}
#[must_use]
pub fn title(self) -> &'static str;
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum NotifierConfig {
/// Disable notifications entirely.
Disabled,
/// Emit `OSC 9 ; title — body BEL` to the supplied writer.
/// Default channel.
#[default]
TerminalOsc9,
/// Spawn a user-supplied command, passing the body on argv.
/// `argv[0]` is the program; remaining items are static
/// arguments. The notification body is appended as the last
/// argument when [`Notifier::notify`] is called.
ExternalCommand { argv: Vec<String> },
}
#[derive(Debug, Clone, Default)]
pub struct Notifier {
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct KindMask {
}
#[must_use]
pub fn without(mut self, kind: NotificationKind) -> Self;
#[must_use]
pub fn allows(&self, kind: NotificationKind) -> bool;
#[must_use]
pub fn new(config: NotifierConfig) -> Self;
#[must_use]
pub fn with_mask(mut self, mask: KindMask) -> Self;
#[must_use]
pub fn is_enabled(&self) -> bool;
#[must_use]
pub fn allows(&self, kind: NotificationKind) -> bool;
#[must_use]
pub fn osc9_payload(kind: NotificationKind, body: &str) -> String;
pub fn notify<W: Write>(
&self,
writer: &mut W,
kind: NotificationKind,
body: &str,
) -> io::Result<()>;
#[must_use]
pub fn external_command(&self, kind: NotificationKind, body: &str) -> Option<Vec<String>>;runtime/signals.rs
Read declaration text · 1 declaration entries
pub fn spawn_signal_handlers(shutdown_tx: mpsc::Sender<()>);runtime/state.rs
Read declaration text · 40 declaration entries
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum DropdownKind {
/// `/` — slash command autocomplete.
#[default]
Slash,
/// `@` — file-mention autocomplete (live workspace search,
/// `./`, `../`, absolute paths).
Mention,
}
pub struct AppState {
/// Persistent state for the kit's `ThinkingAnimation`. The
/// runtime calls
/// [`harness_tui_kit::ThinkingAnimationState::advance`] each
/// render frame while [`Self::is_thinking`] is true.
pub thinking_state: ThinkingAnimationState,
// ── Kit component states ──
/// Chat timeline state.
pub timeline_state: ChatTimelineState,
/// Input bar state.
pub input_state: InputBarState,
/// App shell state.
pub shell_state: AppShellState,
/// Tabs state.
pub tabs_state: TabsState,
/// Approval queue state.
pub approval_state: ApprovalQueueState,
/// Log viewer state (for autonomy mode activity feed).
pub log_viewer_state: LogViewerState,
/// Command palette state.
pub palette_state: CommandPaletteState,
/// Whether the command palette is open.
pub palette_open: bool,
/// Slash dropdown state (inline autocomplete above input bar).
pub dropdown_state: SlashDropdownState,
/// Items for the dropdown (shared between slash commands and `@`
/// file mentions).
pub dropdown_items: Vec<SlashDropdownItem>,
/// Which trigger is currently driving the dropdown — `Slash` when
/// the input begins with `/`, `Mention` when the input contains an
/// `@<prefix>` token at the end. Determines the substitution
/// behaviour on `Enter`/`Tab` confirmation.
pub dropdown_kind: DropdownKind,
/// When `dropdown_kind == Mention`, the literal prefix (including
/// the leading `@`) currently being completed. The confirmation
/// path uses this to know which substring of the input to replace
/// with the chosen path.
pub mention_prefix: String,
/// Error message to display (cleared after one render).
pub error_flash: Option<String>,
/// Info message to display (cleared after one render).
pub info_flash: Option<String>,
/// Ctrl+P settings palette state — visibility, current page,
/// cursor, filter.
pub settings_palette_state: SettingsPaletteState
}
#[must_use]
pub fn new(app_name: impl Into<String>) -> Self;
pub fn set_settings_snapshot(&mut self, snapshot: SettingsSnapshot);
#[must_use]
pub fn settings_snapshot(&self) -> &SettingsSnapshot;
#[must_use]
pub fn live_welcome_config(&self) -> Option<harness_tui_kit::WelcomeConfig>;
pub fn set_welcome(&mut self, welcome: harness_tui_kit::WelcomeConfig);
#[must_use]
pub fn welcome(&self) -> Option<&harness_tui_kit::WelcomeConfig>;
#[must_use]
pub fn app_name(&self) -> &str;
#[must_use]
pub fn mode(&self) -> Mode;
#[must_use]
pub fn should_quit(&self) -> bool;
#[must_use]
pub fn active_agent_id(&self) -> Option<&str>;
#[must_use]
pub fn agents(&self) -> &HashMap<String, SdkAgentInfo>;
#[must_use]
pub fn messages(&self) -> &[harness_tui_kit::ChatMessage];
#[must_use]
pub fn is_streaming(&self) -> bool;
#[must_use]
pub fn is_thinking(&self) -> bool;
#[must_use]
pub fn approval_queue(&self) -> &[SdkApprovalRequest];
#[must_use]
pub fn activity_log(&self) -> &[harness_tui_kit::LogEntry];
#[must_use]
pub fn session(&self) -> &SessionInfo;
#[must_use]
pub fn elapsed(&self) -> Duration;
pub fn set_quit(&mut self);
pub fn set_streaming(&mut self, streaming: bool);
pub fn set_thinking(&mut self, thinking: bool);
pub fn tick_thinking(&mut self);
pub fn push_streaming_delta(&mut self, delta: &str);
#[must_use]
pub fn has_active_markdown_stream(&self) -> bool;
pub fn set_mode(&mut self, mode: Mode) -> Result<(), crate::SdkError>;
pub fn set_active_agent(&mut self, agent_id: Option<String>);
pub fn set_max_messages(&mut self, max: usize);
pub fn set_agents(&mut self, agents: Vec<SdkAgentInfo>);
pub fn update_agent(&mut self, agent: SdkAgentInfo);
pub fn add_message(&mut self, msg: harness_tui_kit::ChatMessage);
pub fn append_to_last_message(&mut self, text: &str);
pub fn clear_messages(&mut self);
pub fn truncate_messages_at(&mut self, idx: usize);
pub fn add_approval(&mut self, request: SdkApprovalRequest);
pub fn remove_approval(&mut self, request_id: &str);
pub fn add_activity(&mut self, entry: harness_tui_kit::LogEntry);
pub fn update_usage(&mut self, input_tokens: u64, output_tokens: u64, cost_cents: f64);
pub fn tick(&mut self);runtime/terminal.rs
Read declaration text · 4 declaration entries
pub type SdkTerminal = Terminal<CrosstermBackend<Stdout>>;
pub fn init_terminal() -> io::Result<SdkTerminal>;
pub fn restore_terminal() -> io::Result<()>;
pub fn install_panic_hook();runtime/terminal_control.rs
Read declaration text · 7 declaration entries
pub const MAX_TITLE_LEN: usize;
pub const MAX_HYPERLINK_URL_LEN: usize;
pub fn set_title<W: Write>(writer: &mut W, title: &str) -> io::Result<()>;
pub fn clear_title<W: Write>(writer: &mut W) -> io::Result<()>;
pub fn ring_bell<W: Write>(writer: &mut W) -> io::Result<()>;
#[must_use]
pub fn hyperlink(url: &str, label: &str) -> String;
pub fn write_hyperlink<W: Write>(writer: &mut W, url: &str, label: &str) -> io::Result<()>;screens/autonomy_screen.rs
Read declaration text · 1 declaration entries
pub fn render_autonomy_screen(frame: &mut Frame, state: &mut AppState, theme: &Theme);screens/chat_screen.rs
Read declaration text · 1 declaration entries
pub fn render_chat_screen(
frame: &mut Frame,
state: &mut AppState,
theme: &Theme,
adapter: &dyn AgentAdapter,
);screens/custom.rs
Read declaration text · 3 declaration entries
#[derive(Debug, Clone)]
pub enum ScreenResult {
/// Event was consumed by the screen.
Consumed,
/// Event was not handled — pass to default handler.
Ignored,
/// Screen requests navigation to another screen.
Navigate(String),
/// Screen requests closing itself.
Close,
}
#[derive(Debug, Clone)]
pub enum ScreenEvent {
/// A terminal event (keyboard, mouse, resize).
Terminal(CrosstermEvent),
/// A tick for animations.
Tick,
}
pub trait CustomScreen: Send + Sync {
/// The screen's display name (shown in tab bar).
fn name(&self) -> &str;
/// Render the screen into the given area.
fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme);
/// Handle an event. Return `ScreenResult::Consumed` if the event
/// was handled, `ScreenResult::Ignored` to pass it through.
fn handle_event(&mut self, event: ScreenEvent) -> ScreenResult;
/// Called when the screen becomes the active tab.
fn on_focus(&mut self) ;
/// Called when the screen loses focus.
fn on_blur(&mut self) ;
}screens/mod.rs
Read declaration text · 3 declaration entries
pub mod autonomy_screen;
pub mod chat_screen;
pub mod custom;session/metadata.rs
Read declaration text · 2 declaration entries
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionMetadata {
/// Session id (matches the file stem on disk).
pub session_id: Uuid,
/// Application name (which app wrote this session).
pub app_name: String,
/// Workspace root the session was started in (display only).
#[serde(default)]
pub workspace_root: String,
/// First user message (truncated) — shown as the picker preview.
#[serde(default)]
pub preview: String,
/// When the session started.
pub started_at: DateTime<Utc>,
/// When the session was last appended to.
pub last_updated_at: DateTime<Utc>,
/// Number of records persisted so far.
#[serde(default)]
pub record_count: u64
}
#[must_use]
pub fn truncate_preview(s: &str, max_chars: usize) -> String;session/mod.rs
Read declaration text · 3 declaration entries
pub use metadata::SessionMetadata;
pub use record::{SessionRecord, SessionRecordKind};
pub use store::{JsonlSessionStore, SessionStore, SessionStoreError};session/record.rs
Read declaration text · 3 declaration entries
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SessionRecordKind {
/// User input.
User,
/// Assistant turn (markdown body).
Assistant,
/// Tool invocation.
Tool,
/// Shell exec.
Exec,
/// Unified diff.
Diff,
/// Approval request + resolution.
Approval,
/// System notice.
System,
/// Adapter-supplied opaque state (config, model id, tokens).
Snapshot,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionRecord {
/// Per-record id (independent of session id; useful for dedup
/// when resume crosses fork boundaries).
pub id: Uuid,
/// UTC timestamp when the record was written.
pub at: DateTime<Utc>,
/// Discriminator.
pub kind: SessionRecordKind,
/// Optional sender label (agent id, user, system).
#[serde(default)]
pub sender: String,
/// Structured payload — schema is owned by the SDK consumer.
pub body: serde_json::Value
}
#[must_use]
pub fn new(
kind: SessionRecordKind,
sender: impl Into<String>,
body: serde_json::Value,
) -> Self;session/store.rs
Read declaration text · 6 declaration entries
#[derive(Debug, Error)]
pub enum SessionStoreError {
/// I/O error reaching the underlying storage.
#[error("session store i/o: {0}")]
Io(#[from] std::io::Error),
/// Serialization error encoding a record.
#[error("session store serde: {0}")]
Serde(#[from] serde_json::Error),
/// The home directory could not be located. The default JSONL
/// store falls back to the system temp directory before
/// surfacing this.
#[error("home directory not available")]
NoHome,
/// The requested session id is not present in the store.
#[error("session not found: {0}")]
NotFound(Uuid),
}
pub trait SessionStore: Send + Sync {
/// Begin a new session, persisting its metadata as the first
/// line. Returns the freshly-minted session id.
fn begin(&self, meta: SessionMetadata) -> Result<Uuid, SessionStoreError>;
/// Append a single record to a session.
fn append(&self, session_id: Uuid, record: &SessionRecord) -> Result<(), SessionStoreError>;
/// Read the metadata line for one session.
fn metadata(&self, session_id: Uuid) -> Result<SessionMetadata, SessionStoreError>;
/// Replay all records for a session in append order.
fn replay(&self, session_id: Uuid) -> Result<Vec<SessionRecord>, SessionStoreError>;
/// List every session in the store, sorted by `last_updated_at`
/// descending (most-recent first). Limit caps the number of
/// rows returned (use `usize::MAX` for "all").
fn list(&self, app_name: &str, limit: usize)
-> Result<Vec<SessionMetadata>, SessionStoreError>;
/// Delete a session.
fn delete(&self, session_id: Uuid) -> Result<(), SessionStoreError>;
}
#[derive(Debug, Clone)]
pub struct JsonlSessionStore {
}
pub fn standard(app_name: &str) -> Result<Self, SessionStoreError>;
pub fn rooted_at(root: impl Into<PathBuf>) -> Result<Self, SessionStoreError>;
#[must_use]
pub fn root(&self) -> &Path;settings.rs
Read declaration text · 15 declaration entries
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ProviderKind {
/// Local / remote Flocks engine — drives an underlying coding CLI
/// (Claude Code, Codex, Gemini-CLI, etc.) which talks to a model.
Flocks,
/// Foundry inference gateway — vendor-agnostic, routes to many
/// upstreams.
Foundry,
/// Forge ANVIL agent — direct provider integration (e.g.,
/// Anthropic, OpenAI, Google) bound to an OAS-identified agent.
Forge,
/// Direct provider integration without a routing layer.
Direct,
}
#[must_use]
pub fn label(self) -> &'static str;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProviderInfo {
/// Stable identifier (used to apply selection back to the adapter).
pub id: String,
/// User-visible name.
pub name: String,
/// Source category.
pub kind: ProviderKind,
/// One-line description shown in the palette.
pub description: String,
/// Whether the provider is currently reachable / authenticated.
pub healthy: bool,
/// `true` when this is the currently-selected provider.
pub active: bool
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ModelInfo {
/// Stable identifier scoped to its provider.
pub id: String,
/// User-visible name (e.g. `"Claude Opus 4.7"`).
pub name: String,
/// Provider that hosts this model.
pub provider_id: String,
/// Optional context window in tokens.
pub context_window: Option<u32>,
/// Optional capability tags ("coding", "vision", "tool-use", …).
pub capabilities: Vec<String>,
/// `true` when this is the currently-selected model.
pub active: bool
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ModeInfo {
/// Stable identifier (e.g. `"build"`, `"plan"`, `"read"`, `"auto"`).
pub id: String,
/// User-visible name.
pub name: String,
/// Single-sentence summary shown in the palette.
pub description: String,
/// Default provider when this mode activates.
pub default_provider: Option<String>,
/// Default model when this mode activates.
pub default_model: Option<String>,
/// `true` when this is the currently-selected mode.
pub active: bool
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProviderSettingField {
/// Stable identifier (e.g. `"api_key"`, `"base_url"`, `"timeout_seconds"`).
pub id: String,
/// User-visible label.
pub label: String,
/// One-line description.
pub description: String,
/// Field kind — drives palette rendering + input handling.
pub kind: ProviderSettingKind,
/// Current value (already redacted for secret fields).
pub value: String,
/// `true` when the value is sensitive — palette displays as
/// `••••••` and the runtime never logs it.
pub secret: bool,
/// `true` when this field is the primary "selected" entry of an
/// enum/picker (e.g. the active Flocks CLI inside the Flocks
/// provider's settings).
pub active: bool
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "kebab-case")]
pub enum ProviderSettingKind {
/// Free-form string input (api keys, urls).
Text,
/// Integer (timeouts, retries, max-tokens).
Integer,
/// Boolean toggle.
Bool,
/// Drill-in picker — selecting this opens a sub-page listing
/// `options`.
Picker {
/// Available choices.
options: Vec<ProviderSettingOption>,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProviderSettingOption {
pub id: String,
pub label: String,
pub description: String
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct FlocksCli {
/// Stable identifier (e.g. `"claude-code"`, `"codex"`, `"gemini-cli"`).
pub id: String,
/// User-visible name.
pub name: String,
/// Path or command resolved by the runtime.
pub command: String,
/// Models this CLI can drive.
pub models: Vec<ModelInfo>,
/// `true` when this CLI is the currently-selected Flocks driver.
pub active: bool
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct SettingsSnapshot {
/// Provider catalogue (Flocks / Foundry / Forge / Direct …).
pub providers: Vec<ProviderInfo>,
/// Mode catalogue (Build / Plan / Auto / Read …).
pub modes: Vec<ModeInfo>,
/// Flat list of every model the adapter knows about, *including*
/// the models exposed by Flocks CLIs. Each `ModelInfo` carries
/// its `provider_id` so the palette can filter by provider.
/// Adapters that only support Flocks may leave this empty and
/// rely on `flocks_clis` instead.
#[serde(default)]
pub models: Vec<ModelInfo>,
/// Flocks-CLI catalogue (each CLI carries its own model list).
pub flocks_clis: Vec<FlocksCli>,
/// Per-provider configurable fields keyed by `provider_id`. The
/// palette renders this as the "Settings" tab on each provider's
/// drill-in. Adapters typically populate this from Forge's
/// `ProviderSettings` introspection.
#[serde(default)]
pub provider_settings: std::collections::HashMap<String, Vec<ProviderSettingField>>
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "kebab-case")]
pub enum SettingsAction {
/// Swap to a different provider. Adapter is expected to re-route
/// future `send_message` calls.
SetProvider { provider_id: String },
/// Swap to a model on the currently-active provider.
SetModel {
provider_id: String,
model_id: String,
},
/// Activate a mode (which may in turn change provider+model).
SetMode { mode_id: String },
/// Configure Flocks to drive a specific CLI.
SetFlocksCli { cli_id: String },
/// Configure a model for a specific Flocks CLI.
SetFlocksCliModel { cli_id: String, model_id: String },
/// Update a provider configuration field (api key, base URL,
/// timeout, etc.). The adapter validates the value and may
/// reject it via [`SettingsApplyResult::fail`].
SetProviderSetting {
provider_id: String,
field_id: String,
value: String,
},
/// Open a settings sub-page that the adapter may want to handle
/// out-of-band (e.g. opening an external editor).
OpenSubPage { page_id: String },
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SettingsApplyResult {
/// Whether the action succeeded.
pub ok: bool,
/// Optional human-readable status message (shown as a flash).
pub message: Option<String>
}
#[must_use]
pub fn ok() -> Self;
#[must_use]
pub fn ok_with(message: impl Into<String>) -> Self;
#[must_use]
pub fn fail(message: impl Into<String>) -> Self;types.rs
Read declaration text · 62 declaration entries
pub const MAX_AGENT_ID_LEN: usize;
pub const MAX_AGENT_NAME_LEN: usize;
pub const MAX_CHUNK_SIZE: usize;
pub const MAX_TOOL_INPUT_SIZE: usize;
pub const MAX_INTERJECTION_LEN: usize;
pub const DEFAULT_STREAM_TIMEOUT: Duration;
pub const DEFAULT_MAX_MESSAGES: usize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Mode {
/// Interactive chat mode — user sends messages, agent responds.
Chat,
/// Autonomous execution mode — agent works independently with interjections.
Autonomy,
/// Transient state while draining autonomy events and cleaning up.
Stopping,
}
#[must_use]
pub const fn label(&self) -> &'static str;
#[must_use]
pub const fn is_autonomy(&self) -> bool;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SdkRole {
/// A human end-user.
User,
/// An AI agent, optionally identified by name.
Agent(String),
/// A system-generated message.
System,
/// Output from a tool invocation.
Tool,
}
#[must_use]
pub const fn label(&self) -> &'static str;
#[must_use]
pub fn to_kit_role(&self) -> harness_tui_kit::Role;
#[must_use]
pub fn agent_name(&self) -> &str;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SdkAgentInfo {
/// Unique identifier for this agent.
pub id: String,
/// Human-readable display name.
pub name: String,
/// Short description of the agent's role or purpose.
pub role_description: String,
/// Model identifier (e.g., "claude-opus-4-6").
pub model: String,
/// Current lifecycle status.
pub status: SdkAgentStatus,
/// Capabilities this agent supports.
pub capabilities: Vec<String>,
/// Tools available to this agent.
pub tools: Vec<String>,
/// Additional metadata (adapter-specific, not logged at INFO+).
pub metadata: std::collections::HashMap<String, String>
}
#[must_use]
pub fn new(id: impl Into<String>, name: impl Into<String>, model: impl Into<String>) -> Self;
#[must_use]
pub fn with_role(mut self, role: impl Into<String>) -> Self;
#[must_use]
pub fn with_status(mut self, status: SdkAgentStatus) -> Self;
#[must_use]
pub fn with_capabilities(mut self, caps: Vec<String>) -> Self;
#[must_use]
pub fn with_tools(mut self, tools: Vec<String>) -> Self;
#[must_use]
pub fn to_kit_agent_info(&self) -> harness_tui_kit::AgentInfo;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SdkAgentStatus {
/// Connected and ready.
#[default]
Online,
/// Actively executing.
Working,
/// Reasoning/planning.
Thinking,
/// Connected, no pending work.
Idle,
/// Blocked on external resource or human.
Waiting,
/// Encountered an error.
Error,
/// Permanently shut down.
Terminated,
/// Disconnected/unreachable.
Offline,
}
#[must_use]
pub const fn label(&self) -> &'static str;
#[must_use]
pub const fn is_active(&self) -> bool;
#[must_use]
pub const fn is_terminal(&self) -> bool;
#[must_use]
pub fn to_kit_status(&self) -> harness_tui_kit::AgentStatus;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ResponseChunk {
/// A fragment of the agent's text response.
TextDelta {
/// The text fragment.
text: String,
/// The agent that produced this text.
agent_id: String,
},
/// A tool call has started.
ToolCallStart {
/// Unique ID for this tool call.
call_id: String,
/// Tool name.
tool_name: String,
/// Tool input (JSON).
input: String,
/// The agent making the tool call.
agent_id: String,
},
/// A tool call has completed.
ToolCallEnd {
/// Unique ID matching the `ToolCallStart`.
call_id: String,
/// Tool output.
output: String,
/// Whether the tool call succeeded.
success: bool,
/// Wall-clock duration in milliseconds.
duration_ms: u64,
},
/// A fragment of the agent's thinking/reasoning (if exposed).
ThinkingDelta {
/// The thinking text fragment.
text: String,
/// The agent that is thinking.
agent_id: String,
},
/// The agent's status has changed.
StatusChange {
/// The agent whose status changed.
agent_id: String,
/// The new status.
status: SdkAgentStatus,
},
/// An approval is needed from the user.
ApprovalNeeded {
/// The approval request details.
request: SdkApprovalRequest,
},
/// A cost/usage update.
UsageUpdate {
/// Input tokens consumed.
input_tokens: u64,
/// Output tokens consumed.
output_tokens: u64,
/// Estimated cost in USD (cents).
cost_cents: f64,
},
/// The response stream has ended successfully.
Done {
/// The agent that finished.
agent_id: String,
},
/// The response stream ended with an error.
Error {
/// Error message.
message: String,
/// The agent that errored (if known).
agent_id: String,
},
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum AutonomyEvent {
/// An activity log entry from an agent.
ActivityLog {
/// The agent producing this log.
agent_id: String,
/// Log message.
message: String,
/// Severity level.
level: ActivityLevel,
},
/// An agent's status changed during autonomy.
AgentStatusChange {
/// The agent whose status changed.
agent_id: String,
/// The new status.
status: SdkAgentStatus,
},
/// An agent needs approval to proceed.
ApprovalRequired {
/// The approval request.
request: SdkApprovalRequest,
},
/// A previously requested approval was resolved (by timeout or cancel).
ApprovalResolved {
/// The approval request ID.
request_id: String,
/// How it was resolved.
resolution: String,
},
/// A task was created or updated.
TaskUpdate {
/// Task identifier.
task_id: String,
/// Task title.
title: String,
/// Task status.
status: String,
/// The agent working on this task.
agent_id: String,
},
/// Metrics/usage update during autonomy.
MetricsUpdate {
/// Total input tokens.
total_input_tokens: u64,
/// Total output tokens.
total_output_tokens: u64,
/// Total cost in USD cents.
total_cost_cents: f64,
/// Elapsed time in seconds.
elapsed_secs: u64,
},
/// Autonomy session has ended.
SessionEnded {
/// Reason for ending.
reason: String,
},
/// Error during autonomy (non-fatal).
Error {
/// The agent that errored.
agent_id: String,
/// Error message.
message: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ActivityLevel {
/// Trace-level detail.
Trace,
/// Debug information.
Debug,
/// General information.
#[default]
Info,
/// Warning condition.
Warn,
/// Error condition.
Error,
}
#[must_use]
pub const fn label(&self) -> &'static str;
#[must_use]
pub fn to_kit_log_level(&self) -> harness_tui_kit::LogLevel;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SdkApprovalRequest {
/// Unique identifier for this request.
pub id: String,
/// Name of the agent requesting approval.
pub agent_name: String,
/// ID of the agent requesting approval.
pub agent_id: String,
/// Short summary of the proposed action.
pub action_summary: String,
/// Detailed reasoning for the action.
pub reasoning: String,
/// Expected impact description.
pub impact: String,
/// Resources affected by the action.
pub resources: Vec<String>,
/// Assessed risk level.
pub risk_level: SdkRiskLevel,
/// ISO-8601 timestamp of when the request was created.
pub created_at: String
}
#[must_use]
pub fn new(
id: impl Into<String>,
agent_name: impl Into<String>,
action_summary: impl Into<String>,
) -> Self;
#[must_use]
pub fn with_agent_id(mut self, agent_id: impl Into<String>) -> Self;
#[must_use]
pub fn with_risk_level(mut self, risk_level: SdkRiskLevel) -> Self;
#[must_use]
pub fn with_reasoning(mut self, reasoning: impl Into<String>) -> Self;
#[must_use]
pub fn with_impact(mut self, impact: impl Into<String>) -> Self;
#[must_use]
pub fn with_resources(mut self, resources: Vec<String>) -> Self;
#[must_use]
pub fn with_created_at(mut self, created_at: impl Into<String>) -> Self;
#[must_use]
pub fn to_kit_approval_request(&self) -> harness_tui_kit::ApprovalRequest;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SdkRiskLevel {
/// Low risk, routine action.
#[default]
Low,
/// Medium risk, warrants attention.
Medium,
/// High risk, requires careful review.
High,
/// Critical risk, potentially destructive.
Critical,
}
#[must_use]
pub const fn label(&self) -> &'static str;
#[must_use]
pub const fn requires_review(&self) -> bool;
#[must_use]
pub const fn weight(&self) -> u8;
#[must_use]
pub fn to_kit_risk_level(&self) -> harness_tui_kit::RiskLevel;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SdkApprovalAction {
/// Approve the request as-is.
Approve,
/// Deny the request.
Deny,
/// Approve with modifications.
Edit {
/// Description of the modification.
modification: String,
},
}
#[must_use]
pub fn is_approved(&self) -> bool;
#[must_use]
pub fn to_kit_approval_action(&self) -> harness_tui_kit::ApprovalAction;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct HumanInterjection {
/// Original raw input text.
pub raw: String,
/// Cleaned text content (prefix markers stripped).
pub text: String,
/// Priority level.
pub priority: InterjectionPriority,
/// Kind of interjection.
pub kind: InterjectionKind,
/// Target agent name, if specified (via `@Agent` syntax).
pub target: Option<String>
}
#[must_use]
pub fn is_urgent(&self) -> bool;
#[must_use]
pub fn is_targeted(&self) -> bool;
#[must_use]
pub fn is_broadcast(&self) -> bool;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum InterjectionPriority {
/// Standard priority.
#[default]
Normal,
/// High priority — should interrupt current work.
High,
/// Urgent — must be processed immediately.
Urgent,
}
#[must_use]
pub const fn label(&self) -> &'static str;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum InterjectionKind {
/// A direct instruction to the agent(s).
#[default]
Instruction,
/// A question for the agent(s).
Question,
/// A new mission directive.
Mission,
/// A general message or comment.
Message,
}
#[must_use]
pub const fn label(&self) -> &'static str;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct InterjectionAck {
/// Whether the adapter accepted the interjection.
pub received: bool,
/// Optional message from the adapter.
pub message: String
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AdapterCapabilities {
/// Supports chat mode.
pub chat: bool,
/// Supports autonomy mode.
pub autonomy: bool,
/// Supports multi-agent operations.
pub multi_agent: bool,
/// Supports usage/cost metrics.
pub metrics: bool,
/// Supports streaming responses.
pub streaming: bool,
/// Supports tool calls.
pub tool_calls: bool,
/// Supports thinking/reasoning display.
pub thinking: bool
}
#[must_use]
pub fn chat_only() -> Self;
#[must_use]
pub fn full() -> Self;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SessionInfo {
/// Unique session identifier.
pub id: String,
/// ISO-8601 timestamp of session start.
pub started_at: String,
/// Total messages in this session.
pub message_count: usize,
/// Total input tokens consumed.
pub total_input_tokens: u64,
/// Total output tokens consumed.
pub total_output_tokens: u64,
/// Total estimated cost in USD cents.
pub total_cost_cents: f64,
/// Elapsed duration.
pub elapsed: Duration
}
#[must_use]
pub fn new(id: impl Into<String>) -> Self;validation/adapter_output.rs
Read declaration text · 3 declaration entries
pub fn validate_agent_info(info: &SdkAgentInfo) -> Result<(), SdkError>;
pub fn validate_response_chunk(chunk: &ResponseChunk) -> Result<(), SdkError>;
pub fn validate_approval_request(request: &SdkApprovalRequest) -> Result<(), SdkError>;validation/mod.rs
Read declaration text · 1 declaration entries
pub mod adapter_output;workspace.rs
Read declaration text · 1 declaration entries
#[must_use]
pub fn complete_workspace_paths(
workspace_root: &Path,
prefix: &str,
max_results: usize,
) -> Vec<String>;Continue
harness-sdk-forge
Forge ↔ Harness bridge — implements harness-sdk's AgentAdapter for forge-rs agents and re-exports the full forge SDK so harness apps get every Forge primitive in one import.
harness-spec
HarnessSpec v0.1 contract layer — fail-closed TOML manifest parsing, validation, and canonical BLAKE3 hashing (FINAL_SPEC §5)