leviath-cli 0.3.2

Command-line interface for Leviath agent framework
Documentation
[package]
name = "leviath-cli"
description = "Command-line interface for Leviath agent framework"
version.workspace = true
edition.workspace = true
license.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
rust-version.workspace = true
keywords.workspace = true
categories = ["command-line-utilities"]
# docs.rs is near-useless for a binary crate; send crates.io's Documentation
# link to the real docs site instead.
documentation = "https://leviath.dev"
readme = "README.md"

[lib]
name = "leviath_cli"
path = "src/lib.rs"

[[bin]]
name = "lev"
path = "src/main.rs"

[features]
default = ["mimalloc-allocator"]
debug-http = ["leviath-providers/debug-http"]
# The lev binary's global allocator (see main.rs). A feature so the two
# allocators can be benchmarked against each other on identical code
# (`--no-default-features` builds on the system allocator), and so an
# embedder-style build can opt out entirely.
mimalloc-allocator = ["dep:mimalloc", "dep:leviath-alloc", "leviath-alloc/mimalloc"]

[dependencies]
# The binary's global allocator (see main.rs). Kept out of the workspace dep
# table on purpose: only the composition-root binary should pick an allocator,
# never a library crate.
mimalloc = { version = "0.1", optional = true }
leviath-alloc = { path = "../leviath-alloc", version = "0.3.2", optional = true }
leviath-core = { workspace = true }
# The outbound-request policy (SSRF checks + the shared client).
leviath-net = { workspace = true }
leviath-agent-client = { workspace = true }
leviath-runtime = { workspace = true, features = ["control-socket"] }
leviath-telemetry = { workspace = true }
leviath-providers = { workspace = true }
leviath-mcp = { workspace = true }
leviath-package = { workspace = true }
leviath-scripting = { workspace = true }
clap = { workspace = true }
tokio = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
toml = { workspace = true }
anyhow = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
rhai = { workspace = true }
glob = { workspace = true }
dirs = { workspace = true }
chrono = { workspace = true }
bevy_ecs = { workspace = true }
crossterm = { workspace = true }
ratatui = { workspace = true }
unicode-width = { workspace = true }
futures = { workspace = true }
dotenvy = { workspace = true }
leviath-tools = { workspace = true }
leviath-sys = { workspace = true }
async-trait = { workspace = true }
libc = { workspace = true }
pulldown-cmark = { workspace = true }
ratatui-textarea = { workspace = true }
axum = { workspace = true }
axum-server = { workspace = true }
tower-http = { workspace = true }
reqwest = { workspace = true }
url = { workspace = true }
tower = { version = "0.5", features = ["util"] }
hmac = { workspace = true }
sha2 = { workspace = true }
hex = { workspace = true }
rand = { workspace = true }

# Randomly named, owner-only temp files for the interactive task editor: a
# predictable `/tmp` name is a symlink-attack target on a shared host.
tempfile = "3"

[dev-dependencies]
leviath-testkit = { workspace = true }
# `SO_LINGER(0)` on one websocket test's socket, to force an RST rather than a
# FIN. Tokio deprecates its own `set_linger` because the option blocks a runtime
# thread on drop - a real hazard, and irrelevant to a socket the test closes
# immediately. socket2 is the layer that owns socket options, is already in the
# tree as a tokio dependency, and makes no claim about a runtime, so this is
# using the right API rather than silencing the wrong one.
socket2 = "0.6"


# A TLS *client*, so the HTTPS server is tested with a real handshake against a
# root store holding exactly the test certificate. Verifying rather than
# skipping verification is the point: a client that accepted anything would
# pass against a server that never presented a certificate at all. Both come in
# with `axum-server`'s `tls-rustls`, so this adds nothing to the tree.
tokio-rustls = { version = "0.26", default-features = false, features = ["aws-lc-rs"] }
# PEM parsing for that root store. `rustls-pki-types` rather than the more
# obvious `rustls-pemfile`, which is unmaintained (RUSTSEC-2025-0134) and whose
# API moved here. Already in the tree via `axum-server`.
rustls-pki-types = { version = "1", features = ["std"] }
# `start_paused`, so the daemon-readiness backoff is tested by moving a virtual
# clock rather than by sleeping through its five-second timeout.
tokio = { workspace = true, features = ["test-util"] }
# An in-memory credential store installed as the process default, so the
# `KeychainStore` adapter is tested against the real `leviath_sys::keychain`
# path rather than a stand-in. No CI runner has an unlocked login keychain, and
# reaching a developer's real one would raise an OS prompt and hang.
keyring-core = "1"

tempfile = "3"
temp-env = { workspace = true, features = ["async_closure"] }
# Validates the bundled blueprints against the published JSON Schema. A test
# dependency only: nothing at runtime reads that schema, it exists so an agent
# authoring a blueprint has something to write against.
jsonschema = { workspace = true }
# In-memory OTLP exporters for the logging reload-slot test - it asserts a
# tracing event actually comes out of the installed bridge layer.
opentelemetry_sdk = { workspace = true, features = ["testing"] }

[lints]
workspace = true

# A copy of the workspace root's [profile.release], and it must be kept in
# sync with it. Inside the workspace this section is ignored (cargo prints a
# one-line "profiles for the non root package" warning and uses the root's),
# but a `cargo install leviath-cli` build has no workspace: this manifest IS
# the root there, and without this section cargo's defaults apply - which
# silently drops `overflow-checks` and lets token/budget arithmetic wrap
# instead of panic. The GitHub release binaries and the crates.io install
# must behave the same, so the warning is the price.
[profile.release]
overflow-checks = true
lto = "fat"
codegen-units = 1
strip = "symbols"