# ABOUTME: Standalone LLM runner library wrapping 12 AI CLI tools as pluggable providers
# ABOUTME: Wraps CLI tools (Claude Code, Copilot, Cursor Agent, OpenCode, Gemini, Codex, Goose, Cline, Continue, Warp, Kiro, Kilo) and ACP

[workspace]
members = [".", "crates/embacle-mcp", "crates/embacle-server"]

[package]
name = "embacle"
version = "0.17.0"
edition = "2021"
license = "Apache-2.0"
description = "LLM runner library — wraps 12 AI CLI tools as pluggable LLM providers with agent loop, guardrails, and cost tracking"
repository = "https://github.com/dravr-ai/dravr-embacle"
homepage = "https://github.com/dravr-ai/dravr-embacle"
documentation = "https://docs.rs/embacle"
keywords = ["llm", "cli", "ai", "mcp", "openai"]
categories = ["command-line-utilities", "api-bindings"]
readme = "README.md"
exclude = [".claude/", ".githooks/", ".github/", "scripts/", "AGENTS.md", "crates/"]

# ============================================================================
# Build Profiles
# ============================================================================

[profile.release]
lto = "thin"
codegen-units = 1
panic = "abort"
strip = true

# ============================================================================
# Workspace Lint Configuration
# ============================================================================
# Shared across all workspace crates via [lints] workspace = true.
# Individual crates inherit these settings automatically.
#
# ZERO TOLERANCE ENFORCEMENT:
#   cargo clippy (reads this config, applies level = "deny")

[workspace.lints.rust]
unsafe_code = "deny"

[workspace.lints.clippy]
# Base configuration: Enable clippy lint groups at DENY level
all = { level = "deny", priority = -1 }
pedantic = { level = "deny", priority = -1 }
nursery = { level = "deny", priority = -1 }

# Type conversion casts - allowed when properly validated
cast_possible_truncation = "allow"
cast_sign_loss = "allow"
cast_precision_loss = "allow"

# Const fn suggestions - clippy suggests const for methods that can't be const
missing_const_for_fn = "allow"

# Significant drop tightening - false positives with async lock guards
significant_drop_tightening = "allow"

# Module naming - allow repetition for clarity
module_name_repetitions = "allow"

# Enforce `use` imports over inline qualified paths (crate::foo::bar)
# Idiomatic Rust prefers imports at top of file for readability
absolute_paths = "deny"

# Multiple dependency versions - unavoidable in some transitive deps
multiple_crate_versions = "allow"

# Missing errors doc - not all error returns need doc comments
missing_errors_doc = "allow"

# must_use candidate - too noisy for builders and constructors
must_use_candidate = "allow"

# return_self_not_must_use - builder pattern methods
return_self_not_must_use = "allow"

# redundant_pub_crate - explicit visibility is clearer
redundant_pub_crate = "allow"

# unnecessary_literal_bound - false positives with async trait lifetimes
unnecessary_literal_bound = "allow"

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[lib]
crate-type = ["lib", "staticlib"]

[features]
default = []
# Enable AG-UI (Agent-User Interaction) protocol event schema and emitter trait.
# See https://github.com/ag-ui-protocol/ag-ui. Pulls in no extra dependencies.
agui = []
# Enable Copilot Headless provider (ACP protocol via copilot --acp)
copilot-headless = ["dep:agent-client-protocol-schema", "tokio/sync"]
# Enable OpenAI-compatible HTTP API client runner (reqwest-based)
openai-api = ["dep:reqwest", "tokio/sync"]
# Enable browser-driven web-UI provider (drives Claude.ai via a headless profile)
web-ui = ["dep:dravr-browser", "dep:toml", "tokio/sync"]
# Enable TOML-based configuration file loading
config-file = ["dep:toml", "dep:dirs"]
# Enable OpenTelemetry metrics export
otel = ["dep:opentelemetry", "dep:opentelemetry_sdk"]
# Enable C FFI static library for Swift/C integration (implies copilot-headless)
ffi = ["copilot-headless"]

[dependencies]
async-trait = "0.1"
base64 = "0.22"
bitflags = { version = "2", features = ["serde"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tempfile = "3"
tokio = { version = "1.45", features = ["process", "io-util", "time", "rt", "rt-multi-thread", "macros", "fs"] }
tokio-stream = { version = "0.1", features = ["io-util"] }
tracing = "0.1"
uuid = { version = "1.22", features = ["v4", "serde"] }
which = "7"

# Optional: ACP schema types for Copilot Headless (copilot --acp)
agent-client-protocol-schema = { version = "0.12", optional = true }

# Optional: HTTP client for OpenAI-compatible API runner
reqwest = { version = "0.12", default-features = false, features = ["json", "stream", "rustls-tls"], optional = true }

# Optional: TOML config file support
toml = { version = "1.1", optional = true }
dirs = { version = "6", optional = true }

# Optional: shared headless-browser primitives for the web-ui runner
dravr-browser = { version = "0.1", optional = true }

# Optional: OpenTelemetry metrics export
opentelemetry = { version = "0.32", optional = true }
opentelemetry_sdk = { version = "0.32", optional = true }

[dev-dependencies]
tokio = { version = "1.45", features = ["full", "test-util"] }
serde_json = "1.0"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

[[example]]
name = "test_claude_e2e"
path = "examples/test_claude_e2e.rs"

[[example]]
name = "web_login"
path = "examples/web_login.rs"
required-features = ["web-ui"]

[[example]]
name = "web_query"
path = "examples/web_query.rs"
required-features = ["web-ui"]

[lints]
workspace = true
