diff --git a/AGENTS.md b/AGENTS.md index 66f4bfabb..443dce2f1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -88,6 +88,12 @@ When working on Rust crates, read the relevant strategy doc **before** making ch When interpolating values into shell command strings (in `fabro-exe` and `fabro-workflows`), always use the `shell_quote()` helper (backed by `shlex::try_quote`). Never use manual `replace('\'', "'\\''")` or unquoted interpolation. This applies to file paths, branch names, URLs, env vars, image names, glob patterns, and any other user-controlled input assembled into a shell script. +## Rust import style + +- **Types** (structs, enums, traits): import by name — `use crate::outcome::Outcome;` +- **Functions**: import the parent module, call as `module::function()` — `use fabro_workflows::operations; operations::create(...)` +- **No glob imports** in production code (`use foo::*`). Globs are acceptable in test modules and preludes. Enforced by clippy `wildcard_imports` lint. + ## Testing workflows - `fabro run ` — run a workflow by name (resolves `fabro/workflows//workflow.toml`), e.g. `fabro run repl` diff --git a/Cargo.toml b/Cargo.toml index 9f5adefd2..4b705a094 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,9 @@ exec = "0.3" slatedb = "0.11.2" object_store = "0.12.5" +[workspace.lints.clippy] +wildcard_imports = "warn" + [profile.release] lto = "thin" strip = true diff --git a/lib/crates/fabro-agent/Cargo.toml b/lib/crates/fabro-agent/Cargo.toml index 6f8f57370..088c48748 100644 --- a/lib/crates/fabro-agent/Cargo.toml +++ b/lib/crates/fabro-agent/Cargo.toml @@ -17,6 +17,9 @@ quarantine = [] [lib] doctest = false +[lints] +workspace = true + [dependencies] clap.workspace = true anyhow.workspace = true diff --git a/lib/crates/fabro-api-types/Cargo.toml b/lib/crates/fabro-api-types/Cargo.toml index 6217715fb..e99adbc03 100644 --- a/lib/crates/fabro-api-types/Cargo.toml +++ b/lib/crates/fabro-api-types/Cargo.toml @@ -8,6 +8,9 @@ description = "Generated Rust types from the Fabro API OpenAPI spec" [lib] doctest = false +[lints] +workspace = true + [dependencies] chrono = { workspace = true, features = ["serde"] } serde.workspace = true diff --git a/lib/crates/fabro-api/Cargo.toml b/lib/crates/fabro-api/Cargo.toml index 1334b4b1e..342d9f009 100644 --- a/lib/crates/fabro-api/Cargo.toml +++ b/lib/crates/fabro-api/Cargo.toml @@ -8,6 +8,9 @@ description = "HTTP API server for Fabro pipelines" [lib] doctest = false +[lints] +workspace = true + [dependencies] fabro-config = { path = "../fabro-config", features = ["exedev"] } fabro-graphviz = { path = "../fabro-graphviz" } diff --git a/lib/crates/fabro-api/src/lib.rs b/lib/crates/fabro-api/src/lib.rs index 4e5f48bb6..1a2dc05bb 100644 --- a/lib/crates/fabro-api/src/lib.rs +++ b/lib/crates/fabro-api/src/lib.rs @@ -1,3 +1,4 @@ +#[allow(clippy::wildcard_imports)] mod demo; pub mod error; pub mod github_webhooks; diff --git a/lib/crates/fabro-cli/Cargo.toml b/lib/crates/fabro-cli/Cargo.toml index 79610093f..0310bf3af 100644 --- a/lib/crates/fabro-cli/Cargo.toml +++ b/lib/crates/fabro-cli/Cargo.toml @@ -15,6 +15,9 @@ server = ["dep:fabro-api"] exedev = ["fabro-sandbox/exe", "fabro-config/exedev", "fabro-workflows/exedev", "fabro-types/exedev"] sleep_inhibitor = ["dep:core-foundation"] +[lints] +workspace = true + [dependencies] fabro-config = { path = "../fabro-config" } fabro-llm = { path = "../fabro-llm" } diff --git a/lib/crates/fabro-cli/src/main.rs b/lib/crates/fabro-cli/src/main.rs index 61257dc78..89e36843d 100644 --- a/lib/crates/fabro-cli/src/main.rs +++ b/lib/crates/fabro-cli/src/main.rs @@ -7,7 +7,7 @@ mod shared; mod sleep_inhibitor; use anyhow::Result; -use args::*; +use args::{Commands, GlobalArgs, RunCommands, LONG_VERSION}; use clap::Parser; use tracing::debug; @@ -239,6 +239,7 @@ async fn main_inner() -> (String, Result<()>) { #[cfg(test)] mod tests { use super::*; + use args::{ConfigCommand, ConfigNamespace, ProviderCommand, ProviderNamespace}; use clap::Parser; #[test] diff --git a/lib/crates/fabro-config/Cargo.toml b/lib/crates/fabro-config/Cargo.toml index c75f21ada..56bc85c0f 100644 --- a/lib/crates/fabro-config/Cargo.toml +++ b/lib/crates/fabro-config/Cargo.toml @@ -13,6 +13,9 @@ default = [] exedev = ["fabro-types/exedev"] clap = ["dep:clap", "fabro-types/clap"] +[lints] +workspace = true + [dependencies] anyhow.workspace = true clap = { workspace = true, optional = true } diff --git a/lib/crates/fabro-core/Cargo.toml b/lib/crates/fabro-core/Cargo.toml index 5e19030f5..9546c827c 100644 --- a/lib/crates/fabro-core/Cargo.toml +++ b/lib/crates/fabro-core/Cargo.toml @@ -8,6 +8,9 @@ description = "Generic workflow execution engine" [lib] doctest = false +[lints] +workspace = true + [dependencies] async-trait.workspace = true fabro-types = { path = "../fabro-types" } diff --git a/lib/crates/fabro-db/Cargo.toml b/lib/crates/fabro-db/Cargo.toml index f8ae3d71b..4562d8aab 100644 --- a/lib/crates/fabro-db/Cargo.toml +++ b/lib/crates/fabro-db/Cargo.toml @@ -8,6 +8,9 @@ description = "SQLite persistence layer for Fabro" [lib] doctest = false +[lints] +workspace = true + [dependencies] sqlx = { workspace = true, features = ["sqlite"] } chrono.workspace = true diff --git a/lib/crates/fabro-devcontainer/Cargo.toml b/lib/crates/fabro-devcontainer/Cargo.toml index aa70a07ed..438f1e032 100644 --- a/lib/crates/fabro-devcontainer/Cargo.toml +++ b/lib/crates/fabro-devcontainer/Cargo.toml @@ -8,6 +8,9 @@ description = "Parse and resolve devcontainer.json into Dockerfiles and lifecycl [lib] doctest = false +[lints] +workspace = true + [dependencies] fabro-util = { path = "../fabro-util" } serde = { workspace = true } diff --git a/lib/crates/fabro-git-storage/Cargo.toml b/lib/crates/fabro-git-storage/Cargo.toml index 0aac7cafa..999d4a2ec 100644 --- a/lib/crates/fabro-git-storage/Cargo.toml +++ b/lib/crates/fabro-git-storage/Cargo.toml @@ -9,6 +9,9 @@ repository = "https://github.com/brynary/arc" [lib] doctest = false +[lints] +workspace = true + [dependencies] git2.workspace = true thiserror.workspace = true diff --git a/lib/crates/fabro-github/Cargo.toml b/lib/crates/fabro-github/Cargo.toml index 25a672417..b263edb4d 100644 --- a/lib/crates/fabro-github/Cargo.toml +++ b/lib/crates/fabro-github/Cargo.toml @@ -8,6 +8,9 @@ description = "GitHub App authentication and API helpers for Fabro" [lib] doctest = false +[lints] +workspace = true + [dependencies] serde.workspace = true serde_json.workspace = true diff --git a/lib/crates/fabro-graphviz/Cargo.toml b/lib/crates/fabro-graphviz/Cargo.toml index f3c0027cb..5c281b6f3 100644 --- a/lib/crates/fabro-graphviz/Cargo.toml +++ b/lib/crates/fabro-graphviz/Cargo.toml @@ -8,6 +8,9 @@ description = "Graphviz DOT parser and typed graph data model" [lib] doctest = false +[lints] +workspace = true + [dependencies] anyhow.workspace = true fabro-types = { path = "../fabro-types" } diff --git a/lib/crates/fabro-hooks/Cargo.toml b/lib/crates/fabro-hooks/Cargo.toml index 8df300bed..c6d10dd68 100644 --- a/lib/crates/fabro-hooks/Cargo.toml +++ b/lib/crates/fabro-hooks/Cargo.toml @@ -8,6 +8,9 @@ description = "User-defined lifecycle hooks for Fabro workflows" [lib] doctest = false +[lints] +workspace = true + [dependencies] fabro-agent = { path = "../fabro-agent" } fabro-config = { path = "../fabro-config" } diff --git a/lib/crates/fabro-interview/Cargo.toml b/lib/crates/fabro-interview/Cargo.toml index ef57afbe6..4ad6d8c38 100644 --- a/lib/crates/fabro-interview/Cargo.toml +++ b/lib/crates/fabro-interview/Cargo.toml @@ -8,6 +8,9 @@ description = "Human-in-the-loop interviewer traits and implementations" [lib] doctest = false +[lints] +workspace = true + [dependencies] serde.workspace = true serde_json.workspace = true diff --git a/lib/crates/fabro-llm/Cargo.toml b/lib/crates/fabro-llm/Cargo.toml index 087d52a0a..2702805a9 100644 --- a/lib/crates/fabro-llm/Cargo.toml +++ b/lib/crates/fabro-llm/Cargo.toml @@ -12,6 +12,9 @@ categories = ["api-bindings"] [lib] doctest = false +[lints] +workspace = true + [dependencies] anyhow.workspace = true thiserror.workspace = true diff --git a/lib/crates/fabro-mcp/Cargo.toml b/lib/crates/fabro-mcp/Cargo.toml index 912d6b66b..f6e505b5b 100644 --- a/lib/crates/fabro-mcp/Cargo.toml +++ b/lib/crates/fabro-mcp/Cargo.toml @@ -8,6 +8,9 @@ description = "MCP (Model Context Protocol) client for connecting to external to [lib] doctest = false +[lints] +workspace = true + [dependencies] anyhow.workspace = true fabro-config = { path = "../fabro-config" } diff --git a/lib/crates/fabro-model/Cargo.toml b/lib/crates/fabro-model/Cargo.toml index 6c80932c3..a925942d0 100644 --- a/lib/crates/fabro-model/Cargo.toml +++ b/lib/crates/fabro-model/Cargo.toml @@ -8,6 +8,9 @@ description = "LLM model catalog: provider identity, model metadata, and resolut [lib] doctest = false +[lints] +workspace = true + [dependencies] serde.workspace = true serde_json.workspace = true diff --git a/lib/crates/fabro-openai-oauth/Cargo.toml b/lib/crates/fabro-openai-oauth/Cargo.toml index 164315ce0..dcb4a14ba 100644 --- a/lib/crates/fabro-openai-oauth/Cargo.toml +++ b/lib/crates/fabro-openai-oauth/Cargo.toml @@ -8,6 +8,9 @@ description = "OpenAI OAuth PKCE token acquisition for Fabro" [lib] doctest = false +[lints] +workspace = true + [dependencies] serde.workspace = true serde_json.workspace = true diff --git a/lib/crates/fabro-retro/Cargo.toml b/lib/crates/fabro-retro/Cargo.toml index 0d5301a15..898fc4b39 100644 --- a/lib/crates/fabro-retro/Cargo.toml +++ b/lib/crates/fabro-retro/Cargo.toml @@ -8,6 +8,9 @@ description = "Retrospective analysis for Fabro workflow runs" [lib] doctest = false +[lints] +workspace = true + [dependencies] anyhow = "1" chrono = { workspace = true, features = ["serde"] } diff --git a/lib/crates/fabro-sandbox/Cargo.toml b/lib/crates/fabro-sandbox/Cargo.toml index 62a29a039..f0e159fa8 100644 --- a/lib/crates/fabro-sandbox/Cargo.toml +++ b/lib/crates/fabro-sandbox/Cargo.toml @@ -18,6 +18,9 @@ test-support = [] [lib] doctest = false +[lints] +workspace = true + [dependencies] anyhow.workspace = true async-trait.workspace = true diff --git a/lib/crates/fabro-sandbox/src/read_guard.rs b/lib/crates/fabro-sandbox/src/read_guard.rs index 04ea61afb..e04d64b51 100644 --- a/lib/crates/fabro-sandbox/src/read_guard.rs +++ b/lib/crates/fabro-sandbox/src/read_guard.rs @@ -1,4 +1,4 @@ -use crate::*; +use crate::Sandbox; use std::collections::HashSet; use std::path::{Component, PathBuf}; use std::sync::{Arc, Mutex}; @@ -101,6 +101,7 @@ crate::delegate_sandbox! { mod tests { use super::*; use crate::test_support::MockSandbox; + use crate::GrepOptions; use std::collections::HashMap; fn mock_with_files(files: HashMap) -> MockSandbox { diff --git a/lib/crates/fabro-slack/Cargo.toml b/lib/crates/fabro-slack/Cargo.toml index 7780ed663..1d2a16997 100644 --- a/lib/crates/fabro-slack/Cargo.toml +++ b/lib/crates/fabro-slack/Cargo.toml @@ -8,6 +8,9 @@ description = "Slack Socket Mode integration for Fabro interviewer" [lib] doctest = false +[lints] +workspace = true + [dependencies] fabro-interview = { path = "../fabro-interview" } fabro-workflows = { path = "../fabro-workflows" } diff --git a/lib/crates/fabro-store/Cargo.toml b/lib/crates/fabro-store/Cargo.toml index 3d0e906a4..9c413f321 100644 --- a/lib/crates/fabro-store/Cargo.toml +++ b/lib/crates/fabro-store/Cargo.toml @@ -7,6 +7,9 @@ license.workspace = true [lib] doctest = false +[lints] +workspace = true + [dependencies] fabro-types = { path = "../fabro-types" } slatedb.workspace = true diff --git a/lib/crates/fabro-telemetry/Cargo.toml b/lib/crates/fabro-telemetry/Cargo.toml index 201ee48f9..dfdb3f54a 100644 --- a/lib/crates/fabro-telemetry/Cargo.toml +++ b/lib/crates/fabro-telemetry/Cargo.toml @@ -8,6 +8,9 @@ description = "Telemetry, analytics, and crash reporting" [lib] doctest = false +[lints] +workspace = true + [dependencies] anyhow.workspace = true base64.workspace = true diff --git a/lib/crates/fabro-tracker/Cargo.toml b/lib/crates/fabro-tracker/Cargo.toml index 459189ba5..a162ebe53 100644 --- a/lib/crates/fabro-tracker/Cargo.toml +++ b/lib/crates/fabro-tracker/Cargo.toml @@ -8,6 +8,9 @@ description = "Tracker trait and types for issue tracking integrations" [lib] doctest = false +[lints] +workspace = true + [dependencies] fabro-github = { path = "../fabro-github" } async-trait.workspace = true diff --git a/lib/crates/fabro-types-derive/Cargo.toml b/lib/crates/fabro-types-derive/Cargo.toml index bff293941..5ff8d3eb1 100644 --- a/lib/crates/fabro-types-derive/Cargo.toml +++ b/lib/crates/fabro-types-derive/Cargo.toml @@ -8,6 +8,9 @@ description = "Derive macros for fabro-types" [lib] proc-macro = true +[lints] +workspace = true + [dependencies] proc-macro2 = "1" quote = "1" diff --git a/lib/crates/fabro-types/Cargo.toml b/lib/crates/fabro-types/Cargo.toml index d1eb407d4..7bf29a394 100644 --- a/lib/crates/fabro-types/Cargo.toml +++ b/lib/crates/fabro-types/Cargo.toml @@ -13,6 +13,9 @@ default = [] exedev = [] clap = ["dep:clap"] +[lints] +workspace = true + [dependencies] chrono = { workspace = true, features = ["serde"] } clap = { workspace = true, optional = true } diff --git a/lib/crates/fabro-util/Cargo.toml b/lib/crates/fabro-util/Cargo.toml index b67fe905e..aa29a992c 100644 --- a/lib/crates/fabro-util/Cargo.toml +++ b/lib/crates/fabro-util/Cargo.toml @@ -8,6 +8,9 @@ description = "Shared utilities: secret redaction and terminal styling" [lib] doctest = false +[lints] +workspace = true + [dependencies] console.workspace = true rand.workspace = true diff --git a/lib/crates/fabro-validate/Cargo.toml b/lib/crates/fabro-validate/Cargo.toml index cd7db2a61..cc3387085 100644 --- a/lib/crates/fabro-validate/Cargo.toml +++ b/lib/crates/fabro-validate/Cargo.toml @@ -8,6 +8,9 @@ description = "Validation and lint rules for Fabro workflow graphs" [lib] doctest = false +[lints] +workspace = true + [dependencies] fabro-graphviz = { path = "../fabro-graphviz" } fabro-model = { path = "../fabro-model" } diff --git a/lib/crates/fabro-workflows/Cargo.toml b/lib/crates/fabro-workflows/Cargo.toml index 80a1fa89d..ecc0dafc0 100644 --- a/lib/crates/fabro-workflows/Cargo.toml +++ b/lib/crates/fabro-workflows/Cargo.toml @@ -16,6 +16,9 @@ doctest = false default = [] exedev = ["fabro-sandbox/exe", "fabro-config/exedev", "fabro-types/exedev"] +[lints] +workspace = true + [dependencies] anyhow.workspace = true dotenvy.workspace = true