mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-07 08:27:12 +00:00
refactor(cli): remove global execution mode
This commit is contained in:
parent
5f6a5ced6b
commit
260460aebf
84 changed files with 520 additions and 338 deletions
|
|
@ -110,11 +110,9 @@ Send the `X-Fabro-Demo: 1` header on any API request to get static mock data wit
|
|||
|
||||
## Pointing the CLI at a server
|
||||
|
||||
The CLI can delegate commands to a running Fabro server instead of executing locally. Set `mode = "server"` in `~/.fabro/user.toml`:
|
||||
The CLI can target a running Fabro server for commands that support a remote API. Configure `~/.fabro/user.toml`:
|
||||
|
||||
```toml title="user.toml"
|
||||
mode = "server"
|
||||
|
||||
[server]
|
||||
base_url = "https://fabro.example.com:3000/api/v1"
|
||||
```
|
||||
|
|
@ -125,7 +123,9 @@ Or use the `--server-url` flag:
|
|||
fabro --server-url https://fabro.example.com:3000/api/v1 model list
|
||||
```
|
||||
|
||||
This applies to commands like `fabro model list`, `fabro model test`, and `fabro exec`. See [User Configuration](/reference/user-configuration#mode) for the full options including mTLS setup.
|
||||
`fabro model list` and `fabro model test` honor `[server].base_url` by default unless you explicitly pass `--storage-dir`. `fabro exec` remains a local agent session and only uses the server when you pass `--server-url`.
|
||||
|
||||
See [User Configuration](/reference/user-configuration#server-section) for the full connection options, including mTLS setup.
|
||||
|
||||
## Next steps
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ These flags apply to all subcommands:
|
|||
|---|---|
|
||||
| `--debug` | Enable DEBUG-level logging (default is INFO) |
|
||||
| `--no-upgrade-check` | Skip the automatic background upgrade check |
|
||||
| `--storage-dir <DIR>` | Storage directory for local run data (default: `~/.fabro`). Implies standalone mode. |
|
||||
| `--server-url <URL>` | Fabro API server URL (overrides `server.base_url` from `user.toml`). Implies server mode. |
|
||||
| `--storage-dir <DIR>` | Local storage directory for Fabro data (default: `~/.fabro`). |
|
||||
| `--server-url <URL>` | Fabro API server URL for commands that support a remote target (overrides `server.base_url` from `user.toml`). |
|
||||
| `-h, --help` | Print help |
|
||||
| `-V, --version` | Print version |
|
||||
|
||||
|
|
@ -31,9 +31,14 @@ output_format = "text"
|
|||
|
||||
[llm]
|
||||
model = "claude-sonnet-4-5"
|
||||
|
||||
[server]
|
||||
base_url = "https://fabro.example.com:3000/api/v1"
|
||||
```
|
||||
|
||||
`[exec]` config applies to `fabro exec`. `[llm]` sets the default workflow model/provider for commands like `fabro run` and `fabro preflight`.
|
||||
`[exec]` config applies to `fabro exec`. `[llm]` sets the default workflow model/provider for commands like `fabro run` and `fabro preflight`. `[server]` stores connection info for commands that can target a remote Fabro API.
|
||||
|
||||
`fabro model` uses `[server].base_url` by default when no explicit `--storage-dir` is passed. `fabro exec` remains a local session unless you pass `--server-url`, even if `[server].base_url` is configured.
|
||||
|
||||
CLI flags always override `user.toml` values, which override hardcoded defaults.
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ CLI flags always take the highest priority:
|
|||
```toml title="user.toml"
|
||||
verbose = true
|
||||
upgrade_check = true
|
||||
mode = "server"
|
||||
|
||||
[server]
|
||||
base_url = "https://fabro.example.com:3000/api/v1"
|
||||
|
|
@ -148,31 +147,22 @@ Customize the git author identity used for checkpoint commits. Overrides the ser
|
|||
| `name` | Git author name | `"fabro"` |
|
||||
| `email` | Git author email | `"fabro@local"` |
|
||||
|
||||
## `mode`
|
||||
|
||||
Controls the default execution mode when neither `--storage-dir` nor `--server-url` is passed.
|
||||
|
||||
| Value | Description |
|
||||
|---|---|
|
||||
| `"standalone"` | Execute locally (default) |
|
||||
| `"server"` | Delegate to an Fabro API server |
|
||||
|
||||
For a single invocation, `--storage-dir` implies standalone mode and `--server-url` implies server mode.
|
||||
|
||||
## `[server]` section
|
||||
|
||||
Configuration for server mode.
|
||||
Connection info for commands that can target a remote Fabro API server.
|
||||
|
||||
| Key | Description | Default |
|
||||
|---|---|---|
|
||||
| `base_url` | Server URL | `"http://localhost:3000/api/v1"` |
|
||||
|
||||
Passing `--server-url` implies server mode and overrides `server.base_url`:
|
||||
`fabro model` uses `[server].base_url` by default when no explicit `--storage-dir` is passed. `--server-url` overrides `server.base_url`:
|
||||
|
||||
```bash
|
||||
fabro --server-url https://fabro.example.com:3000/api/v1 model list
|
||||
```
|
||||
|
||||
`fabro exec` does not automatically use `[server].base_url`. It only routes model traffic through a Fabro server when you pass `--server-url` for that invocation.
|
||||
|
||||
### `[server.tls]` section
|
||||
|
||||
Optional mTLS configuration for authenticating with the server. When present, the CLI presents a client certificate during the TLS handshake.
|
||||
|
|
|
|||
|
|
@ -36,11 +36,11 @@ pub(crate) struct GlobalArgs {
|
|||
#[arg(long, global = true, env = "FABRO_VERBOSE", value_parser = clap::builder::BoolishValueParser::new(), conflicts_with = "quiet")]
|
||||
pub verbose: bool,
|
||||
|
||||
/// Storage directory (default: ~/.fabro)
|
||||
/// Local storage directory (default: ~/.fabro)
|
||||
#[arg(long, global = true, env = "FABRO_STORAGE_DIR")]
|
||||
pub storage_dir: Option<PathBuf>,
|
||||
|
||||
/// Server URL (overrides server.base_url from user.toml)
|
||||
/// Fabro API server URL (overrides server.base_url from user.toml when supported)
|
||||
#[arg(
|
||||
long,
|
||||
global = true,
|
||||
|
|
|
|||
|
|
@ -24,40 +24,33 @@ pub(crate) async fn execute(mut args: AgentArgs, globals: &GlobalArgs) -> Result
|
|||
if globals.json {
|
||||
args.output_format = Some(OutputFormat::Json);
|
||||
}
|
||||
let resolved = user_config::resolve_mode(
|
||||
globals.storage_dir.as_deref(),
|
||||
globals.server_url.as_deref(),
|
||||
&cli_settings,
|
||||
);
|
||||
let server_target = user_config::exec_server_target(globals, &cli_settings);
|
||||
let mcp_servers: Vec<McpServerSettings> = cli_settings
|
||||
.mcp_servers
|
||||
.into_iter()
|
||||
.map(|(name, entry): (String, McpServerEntry)| entry.into_config(name))
|
||||
.collect();
|
||||
match resolved.mode {
|
||||
user_config::ExecutionMode::Server => {
|
||||
tracing::info!(mode = "server", "Agent session starting");
|
||||
let http_client = user_config::build_server_client(resolved.tls.as_ref())?;
|
||||
let provider_name = args
|
||||
.provider
|
||||
.clone()
|
||||
.unwrap_or_else(|| "anthropic".to_string());
|
||||
let adapter = Arc::new(FabroServerAdapter::new(
|
||||
http_client,
|
||||
&resolved.server_base_url,
|
||||
&provider_name,
|
||||
));
|
||||
let mut client = Client::new(HashMap::new(), None, vec![]);
|
||||
client
|
||||
.register_provider(adapter)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to register fabro server adapter: {e}"))?;
|
||||
run_with_args_and_client(args, Some(client), mcp_servers).await?;
|
||||
}
|
||||
user_config::ExecutionMode::Standalone => {
|
||||
tracing::info!(mode = "standalone", "Agent session starting");
|
||||
run_with_args(args, mcp_servers).await?;
|
||||
}
|
||||
if let Some(target) = server_target {
|
||||
tracing::info!(transport = "server", "Agent session starting");
|
||||
let http_client = user_config::build_server_client(target.tls.as_ref())?;
|
||||
let provider_name = args
|
||||
.provider
|
||||
.clone()
|
||||
.unwrap_or_else(|| "anthropic".to_string());
|
||||
let adapter = Arc::new(FabroServerAdapter::new(
|
||||
http_client,
|
||||
&target.server_base_url,
|
||||
&provider_name,
|
||||
));
|
||||
let mut client = Client::new(HashMap::new(), None, vec![]);
|
||||
client
|
||||
.register_provider(adapter)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to register fabro server adapter: {e}"))?;
|
||||
run_with_args_and_client(args, Some(client), mcp_servers).await?;
|
||||
} else {
|
||||
tracing::info!(transport = "direct", "Agent session starting");
|
||||
run_with_args(args, mcp_servers).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -39,13 +39,9 @@ struct ModelTestOutput {
|
|||
|
||||
pub(crate) async fn execute(command: Option<ModelsCommand>, globals: &GlobalArgs) -> Result<()> {
|
||||
let cli_settings = user_config::load_user_settings_with_globals(globals)?;
|
||||
let client = match globals.server_url.as_deref() {
|
||||
Some(base_url) => {
|
||||
let tls = cli_settings
|
||||
.server
|
||||
.as_ref()
|
||||
.and_then(|server| server.tls.as_ref());
|
||||
server_client::connect_remote_api_client(base_url, tls)?
|
||||
let client = match user_config::model_server_target(globals, &cli_settings) {
|
||||
Some(target) => {
|
||||
server_client::connect_remote_api_client(&target.server_base_url, target.tls.as_ref())?
|
||||
}
|
||||
None => server_client::connect_api_client(&cli_settings.storage_dir()).await?,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
use std::path::Path;
|
||||
|
||||
pub(crate) use fabro_config::user::*;
|
||||
|
||||
use fabro_config::ConfigLayer;
|
||||
|
|
@ -24,55 +22,70 @@ pub(crate) fn load_user_settings_with_globals(globals: &GlobalArgs) -> anyhow::R
|
|||
pub(crate) fn apply_global_overrides(mut layer: ConfigLayer, globals: &GlobalArgs) -> ConfigLayer {
|
||||
if let Some(dir) = &globals.storage_dir {
|
||||
layer.storage_dir = Some(dir.clone());
|
||||
layer.mode = Some(ExecutionMode::Standalone);
|
||||
}
|
||||
|
||||
if let Some(url) = &globals.server_url {
|
||||
layer.server.get_or_insert_with(Default::default).base_url = Some(url.clone());
|
||||
layer.mode = Some(ExecutionMode::Server);
|
||||
}
|
||||
|
||||
layer
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub(crate) struct ResolvedMode {
|
||||
pub mode: ExecutionMode,
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub(crate) struct ServerTarget {
|
||||
pub server_base_url: String,
|
||||
pub tls: Option<ClientTlsSettings>,
|
||||
}
|
||||
|
||||
const DEFAULT_SERVER_URL: &str = "http://localhost:3000/api/v1";
|
||||
fn configured_server_target(settings: &Settings) -> Option<ServerTarget> {
|
||||
settings.server.as_ref().and_then(|server| {
|
||||
server.base_url.clone().map(|server_base_url| ServerTarget {
|
||||
server_base_url,
|
||||
tls: server.tls.clone(),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_mode(
|
||||
cli_storage_dir: Option<&Path>,
|
||||
cli_server_url: Option<&str>,
|
||||
pub(crate) fn exec_server_target(
|
||||
globals: &GlobalArgs,
|
||||
settings: &Settings,
|
||||
) -> ResolvedMode {
|
||||
let mode = if cli_server_url.is_some() {
|
||||
ExecutionMode::Server
|
||||
} else if cli_storage_dir.is_some() {
|
||||
ExecutionMode::Standalone
|
||||
) -> Option<ServerTarget> {
|
||||
let target = globals
|
||||
.server_url
|
||||
.as_ref()
|
||||
.map(|server_base_url| ServerTarget {
|
||||
server_base_url: server_base_url.clone(),
|
||||
tls: settings
|
||||
.server
|
||||
.as_ref()
|
||||
.and_then(|server| server.tls.clone()),
|
||||
});
|
||||
debug!(has_target = target.is_some(), "Resolved exec server target");
|
||||
target
|
||||
}
|
||||
|
||||
pub(crate) fn model_server_target(
|
||||
globals: &GlobalArgs,
|
||||
settings: &Settings,
|
||||
) -> Option<ServerTarget> {
|
||||
let target = if let Some(server_base_url) = globals.server_url.as_ref() {
|
||||
Some(ServerTarget {
|
||||
server_base_url: server_base_url.clone(),
|
||||
tls: settings
|
||||
.server
|
||||
.as_ref()
|
||||
.and_then(|server| server.tls.clone()),
|
||||
})
|
||||
} else if globals.storage_dir.is_some() {
|
||||
None
|
||||
} else {
|
||||
settings.mode.clone().unwrap_or_default()
|
||||
configured_server_target(settings)
|
||||
};
|
||||
|
||||
let server_defaults = settings.server.as_ref();
|
||||
|
||||
let server_base_url = cli_server_url
|
||||
.map(String::from)
|
||||
.or_else(|| server_defaults.and_then(|s| s.base_url.clone()))
|
||||
.unwrap_or_else(|| DEFAULT_SERVER_URL.to_string());
|
||||
|
||||
let tls = server_defaults.and_then(|s| s.tls.clone());
|
||||
|
||||
debug!(mode = ?mode, base_url = %server_base_url, tls = tls.is_some(), "CLI mode resolved");
|
||||
|
||||
ResolvedMode {
|
||||
mode,
|
||||
server_base_url,
|
||||
tls,
|
||||
}
|
||||
debug!(
|
||||
has_target = target.is_some(),
|
||||
"Resolved model server target"
|
||||
);
|
||||
target
|
||||
}
|
||||
|
||||
pub(crate) fn build_server_client(
|
||||
|
|
@ -108,63 +121,44 @@ pub(crate) fn build_server_client(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::*;
|
||||
|
||||
// --- resolve_mode precedence ---
|
||||
fn globals() -> GlobalArgs {
|
||||
GlobalArgs {
|
||||
json: false,
|
||||
debug: false,
|
||||
no_upgrade_check: false,
|
||||
quiet: false,
|
||||
verbose: false,
|
||||
storage_dir: None,
|
||||
server_url: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_mode_defaults_to_standalone() {
|
||||
fn exec_has_no_server_target_by_default() {
|
||||
let settings = Settings::default();
|
||||
let resolved = resolve_mode(None, None, &settings);
|
||||
assert_eq!(resolved.mode, ExecutionMode::Standalone);
|
||||
assert_eq!(resolved.server_base_url, DEFAULT_SERVER_URL);
|
||||
assert_eq!(resolved.tls, None);
|
||||
assert_eq!(exec_server_target(&globals(), &settings), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_mode_storage_dir_forces_standalone() {
|
||||
let settings = Settings {
|
||||
mode: Some(ExecutionMode::Server),
|
||||
..Settings::default()
|
||||
};
|
||||
let resolved = resolve_mode(Some(Path::new("/tmp/fabro")), None, &settings);
|
||||
assert_eq!(resolved.mode, ExecutionMode::Standalone);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_mode_server_url_forces_server() {
|
||||
let settings = Settings {
|
||||
mode: Some(ExecutionMode::Standalone),
|
||||
server: Some(ServerSettings {
|
||||
base_url: Some("https://config.example.com".to_string()),
|
||||
fn exec_uses_cli_server_url() {
|
||||
let settings = Settings::default();
|
||||
let mut globals = globals();
|
||||
globals.server_url = Some("https://cli.example.com".to_string());
|
||||
assert_eq!(
|
||||
exec_server_target(&globals, &settings),
|
||||
Some(ServerTarget {
|
||||
server_base_url: "https://cli.example.com".to_string(),
|
||||
tls: None,
|
||||
}),
|
||||
..Settings::default()
|
||||
};
|
||||
let resolved = resolve_mode(None, Some("https://cli.example.com"), &settings);
|
||||
assert_eq!(resolved.mode, ExecutionMode::Server);
|
||||
assert_eq!(resolved.server_base_url, "https://cli.example.com");
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_mode_config_overrides_default() {
|
||||
let settings = Settings {
|
||||
mode: Some(ExecutionMode::Server),
|
||||
server: Some(ServerSettings {
|
||||
base_url: Some("https://config.example.com".to_string()),
|
||||
tls: None,
|
||||
}),
|
||||
..Settings::default()
|
||||
};
|
||||
let resolved = resolve_mode(None, None, &settings);
|
||||
assert_eq!(resolved.mode, ExecutionMode::Server);
|
||||
assert_eq!(resolved.server_base_url, "https://config.example.com");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_mode_cli_url_overrides_config_url() {
|
||||
fn exec_ignores_configured_server_base_url_without_cli_server_url() {
|
||||
let settings = Settings {
|
||||
server: Some(ServerSettings {
|
||||
base_url: Some("https://config.example.com".to_string()),
|
||||
|
|
@ -172,12 +166,63 @@ mod tests {
|
|||
}),
|
||||
..Settings::default()
|
||||
};
|
||||
let resolved = resolve_mode(None, Some("https://cli.example.com"), &settings);
|
||||
assert_eq!(resolved.server_base_url, "https://cli.example.com");
|
||||
assert_eq!(exec_server_target(&globals(), &settings), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_mode_tls_from_config() {
|
||||
fn model_uses_configured_server_base_url() {
|
||||
let settings = Settings {
|
||||
server: Some(ServerSettings {
|
||||
base_url: Some("https://config.example.com".to_string()),
|
||||
tls: None,
|
||||
}),
|
||||
..Settings::default()
|
||||
};
|
||||
assert_eq!(
|
||||
model_server_target(&globals(), &settings),
|
||||
Some(ServerTarget {
|
||||
server_base_url: "https://config.example.com".to_string(),
|
||||
tls: None,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn model_cli_server_url_overrides_config_url() {
|
||||
let settings = Settings {
|
||||
server: Some(ServerSettings {
|
||||
base_url: Some("https://config.example.com".to_string()),
|
||||
tls: None,
|
||||
}),
|
||||
..Settings::default()
|
||||
};
|
||||
let mut globals = globals();
|
||||
globals.server_url = Some("https://cli.example.com".to_string());
|
||||
assert_eq!(
|
||||
model_server_target(&globals, &settings),
|
||||
Some(ServerTarget {
|
||||
server_base_url: "https://cli.example.com".to_string(),
|
||||
tls: None,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn model_storage_dir_suppresses_configured_remote_target() {
|
||||
let settings = Settings {
|
||||
server: Some(ServerSettings {
|
||||
base_url: Some("https://config.example.com".to_string()),
|
||||
tls: None,
|
||||
}),
|
||||
..Settings::default()
|
||||
};
|
||||
let mut globals = globals();
|
||||
globals.storage_dir = Some(PathBuf::from("/tmp/fabro"));
|
||||
assert_eq!(model_server_target(&globals, &settings), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remote_target_uses_tls_from_config() {
|
||||
let tls = ClientTlsSettings {
|
||||
cert: PathBuf::from("cert.pem"),
|
||||
key: PathBuf::from("key.pem"),
|
||||
|
|
@ -190,7 +235,14 @@ mod tests {
|
|||
}),
|
||||
..Settings::default()
|
||||
};
|
||||
let resolved = resolve_mode(None, None, &settings);
|
||||
assert_eq!(resolved.tls, Some(tls));
|
||||
let mut globals = globals();
|
||||
globals.server_url = Some("https://cli.example.com".to_string());
|
||||
assert_eq!(
|
||||
exec_server_target(&globals, &settings),
|
||||
Some(ServerTarget {
|
||||
server_base_url: "https://cli.example.com".to_string(),
|
||||
tls: Some(tls),
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ fn help() {
|
|||
--tree Preserve {node_slug}/retry_{N}/ directory structure
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
@ -444,7 +444,6 @@ fn attach_json_errors_without_prompting_for_human_input() {
|
|||
"model": "gpt-5.4",
|
||||
"provider": "openai"
|
||||
},
|
||||
"mode": "standalone",
|
||||
"no_retro": true,
|
||||
"sandbox": {
|
||||
"daytona": null,
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use fabro_config::mcp::McpTransport;
|
||||
use fabro_config::user::ExecutionMode;
|
||||
use fabro_test::{fabro_snapshot, test_context};
|
||||
use fabro_types::Settings;
|
||||
use predicates::prelude::*;
|
||||
|
|
@ -31,8 +30,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
@ -585,9 +584,7 @@ fn settings_server_url_overrides_cli_defaults() {
|
|||
let existing = std::fs::read_to_string(&user_toml_path).unwrap();
|
||||
context.write_home(
|
||||
".fabro/user.toml",
|
||||
format!(
|
||||
"{existing}\nmode = \"standalone\"\n[server]\nbase_url = \"https://config.example.com\"\n"
|
||||
),
|
||||
format!("{existing}\n[server]\nbase_url = \"https://config.example.com\"\n"),
|
||||
);
|
||||
|
||||
let output = context
|
||||
|
|
@ -602,7 +599,6 @@ fn settings_server_url_overrides_cli_defaults() {
|
|||
.clone();
|
||||
|
||||
let cfg = parse_settings(&output);
|
||||
assert_eq!(cfg.mode, Some(ExecutionMode::Server));
|
||||
assert_eq!(
|
||||
cfg.server
|
||||
.as_ref()
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ fn help() {
|
|||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--model <MODEL> Override default LLM model
|
||||
--provider <PROVIDER> Override default LLM provider
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-v, --verbose Enable verbose output
|
||||
--sandbox <SANDBOX> Sandbox for agent tools [possible values: local, docker, daytona]
|
||||
--label <KEY=VALUE> Attach a label to this run (repeatable, format: KEY=VALUE)
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ fn help() {
|
|||
--shortstat Show only files-changed/insertions/deletions summary (live diffs only)
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ fn help() {
|
|||
--dry-run Skip live service probes (LLM, sandbox, API, web, Brave Search)
|
||||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
use std::process::Output;
|
||||
|
||||
use fabro_test::{fabro_snapshot, test_context};
|
||||
use httpmock::MockServer;
|
||||
|
||||
async fn run_success_output(mut cmd: assert_cmd::Command) -> Output {
|
||||
tokio::task::spawn_blocking(move || cmd.assert().success().get_output().clone())
|
||||
|
|
@ -35,9 +36,9 @@ fn help() {
|
|||
--auto-approve Skip interactive prompts; deny tools outside permission level
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--debug Print LLM request/response debug info to stderr
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--verbose Print full LLM request/response JSON to stderr
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
--skills-dir <SKILLS_DIR> Directory containing skill files (overrides default discovery)
|
||||
--output-format <OUTPUT_FORMAT> Output format (text for human-readable, json for NDJSON event stream) [possible values: text, json]
|
||||
-h, --help Print help
|
||||
|
|
@ -119,6 +120,125 @@ fn exec_uses_user_config_defaults() {
|
|||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_server_url_uses_remote_transport_instead_of_local_api_key_resolution() {
|
||||
let context = test_context!();
|
||||
let server = MockServer::start();
|
||||
server.mock(|when, then| {
|
||||
when.method("POST").path("/api/v1/completions");
|
||||
then.status(500).body("server-routed-marker");
|
||||
});
|
||||
|
||||
let mut cmd = context.exec_cmd();
|
||||
cmd.env_clear();
|
||||
cmd.env("HOME", &context.home_dir);
|
||||
cmd.env("FABRO_NO_UPGRADE_CHECK", "true");
|
||||
cmd.args([
|
||||
"--server-url",
|
||||
&format!("{}/api/v1", server.base_url()),
|
||||
"--provider",
|
||||
"openai",
|
||||
"--model",
|
||||
"gpt-5.4-mini",
|
||||
"test prompt",
|
||||
]);
|
||||
|
||||
let output = cmd.assert().failure().get_output().clone();
|
||||
let stderr = String::from_utf8(output.stderr).expect("valid utf8");
|
||||
assert!(
|
||||
stderr.contains("server-routed-marker"),
|
||||
"expected remote server failure marker, got: {stderr}"
|
||||
);
|
||||
assert!(
|
||||
!stderr.contains("API key not set"),
|
||||
"exec should not fail local API key validation when --server-url is set: {stderr}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_configured_server_base_url_alone_does_not_reroute_exec() {
|
||||
let context = test_context!();
|
||||
let server = MockServer::start();
|
||||
server.mock(|when, then| {
|
||||
when.method("POST").path("/api/v1/completions");
|
||||
then.status(500).body("config-should-not-be-used");
|
||||
});
|
||||
context.write_home(
|
||||
".fabro/user.toml",
|
||||
format!("[server]\nbase_url = \"{}/api/v1\"\n", server.base_url()),
|
||||
);
|
||||
|
||||
let mut cmd = context.exec_cmd();
|
||||
cmd.env_clear();
|
||||
cmd.env("HOME", &context.home_dir);
|
||||
cmd.env("FABRO_NO_UPGRADE_CHECK", "true");
|
||||
cmd.args([
|
||||
"--provider",
|
||||
"openai",
|
||||
"--model",
|
||||
"gpt-5.4-mini",
|
||||
"test prompt",
|
||||
]);
|
||||
|
||||
let output = cmd.assert().failure().get_output().clone();
|
||||
let stderr = String::from_utf8(output.stderr).expect("valid utf8");
|
||||
assert!(
|
||||
stderr.contains("API key not set for provider 'openai'"),
|
||||
"expected local API key validation failure, got: {stderr}"
|
||||
);
|
||||
assert!(
|
||||
!stderr.contains("config-should-not-be-used"),
|
||||
"exec should ignore configured server.base_url without --server-url: {stderr}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_cli_server_url_overrides_configured_server_base_url() {
|
||||
let context = test_context!();
|
||||
let config_server = MockServer::start();
|
||||
config_server.mock(|when, then| {
|
||||
when.method("POST").path("/api/v1/completions");
|
||||
then.status(500).body("config-should-not-be-used");
|
||||
});
|
||||
let cli_server = MockServer::start();
|
||||
cli_server.mock(|when, then| {
|
||||
when.method("POST").path("/api/v1/completions");
|
||||
then.status(500).body("cli-override-marker");
|
||||
});
|
||||
context.write_home(
|
||||
".fabro/user.toml",
|
||||
format!(
|
||||
"[server]\nbase_url = \"{}/api/v1\"\n",
|
||||
config_server.base_url()
|
||||
),
|
||||
);
|
||||
|
||||
let mut cmd = context.exec_cmd();
|
||||
cmd.env_clear();
|
||||
cmd.env("HOME", &context.home_dir);
|
||||
cmd.env("FABRO_NO_UPGRADE_CHECK", "true");
|
||||
cmd.args([
|
||||
"--server-url",
|
||||
&format!("{}/api/v1", cli_server.base_url()),
|
||||
"--provider",
|
||||
"openai",
|
||||
"--model",
|
||||
"gpt-5.4-mini",
|
||||
"test prompt",
|
||||
]);
|
||||
|
||||
let output = cmd.assert().failure().get_output().clone();
|
||||
let stderr = String::from_utf8(output.stderr).expect("valid utf8");
|
||||
assert!(
|
||||
stderr.contains("cli-override-marker"),
|
||||
"expected CLI server URL to win, got: {stderr}"
|
||||
);
|
||||
assert!(
|
||||
!stderr.contains("config-should-not-be-used"),
|
||||
"configured server.base_url should not be used when --server-url is passed: {stderr}"
|
||||
);
|
||||
}
|
||||
|
||||
#[fabro_macros::e2e_test(live("ANTHROPIC_API_KEY"))]
|
||||
fn exec_creates_file() {
|
||||
let context = test_context!();
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
-V, --version Print version
|
||||
----- stderr -----
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -62,12 +62,12 @@ fn help() {
|
|||
[env: FABRO_VERBOSE=]
|
||||
|
||||
--storage-dir <STORAGE_DIR>
|
||||
Storage directory (default: ~/.fabro)
|
||||
Local storage directory (default: ~/.fabro)
|
||||
|
||||
[env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
|
||||
--server-url <SERVER_URL>
|
||||
Server URL (overrides server.base_url from user.toml)
|
||||
Fabro API server URL (overrides server.base_url from user.toml when supported)
|
||||
|
||||
[env: FABRO_SERVER_URL=]
|
||||
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ fn help() {
|
|||
-p, --pretty Formatted colored output with rendered assistant text
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
"#);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use fabro_test::{fabro_snapshot, test_context};
|
||||
use httpmock::MockServer;
|
||||
|
||||
#[test]
|
||||
fn help() {
|
||||
|
|
@ -24,8 +25,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
@ -175,3 +176,61 @@ fn list_invalid_provider_errors() {
|
|||
error: unknown provider: not-a-provider
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_uses_configured_server_base_url_without_server_url_flag() {
|
||||
let context = test_context!();
|
||||
let server = MockServer::start();
|
||||
let mock = server.mock(|when, then| {
|
||||
when.method("GET");
|
||||
then.status(200)
|
||||
.header("Content-Type", "application/json")
|
||||
.body(
|
||||
serde_json::json!({
|
||||
"data": [{
|
||||
"id": "remote-model",
|
||||
"display_name": "Remote Model",
|
||||
"provider": "openai",
|
||||
"family": "test",
|
||||
"aliases": ["remote"],
|
||||
"limits": {
|
||||
"context_window": 131_072,
|
||||
"max_output": 4096
|
||||
},
|
||||
"training": null,
|
||||
"knowledge_cutoff": null,
|
||||
"features": {
|
||||
"tools": true,
|
||||
"vision": false,
|
||||
"reasoning": false,
|
||||
"effort": false
|
||||
},
|
||||
"costs": {
|
||||
"input_cost_per_mtok": 1.0,
|
||||
"output_cost_per_mtok": 2.0,
|
||||
"cache_input_cost_per_mtok": null
|
||||
},
|
||||
"estimated_output_tps": 42.0,
|
||||
"default": false
|
||||
}],
|
||||
"meta": { "has_more": false }
|
||||
})
|
||||
.to_string(),
|
||||
);
|
||||
});
|
||||
context.write_home(
|
||||
".fabro/user.toml",
|
||||
format!("[server]\nbase_url = \"{}/api/v1\"\n", server.base_url()),
|
||||
);
|
||||
|
||||
let mut cmd = context.model();
|
||||
cmd.env_remove("FABRO_STORAGE_DIR");
|
||||
cmd.args(["list", "--json"]);
|
||||
let output = cmd.assert().success().get_output().stdout.clone();
|
||||
let models: serde_json::Value =
|
||||
serde_json::from_slice(&output).expect("model list json should parse");
|
||||
|
||||
mock.assert();
|
||||
assert_eq!(models.as_array().map(Vec::len), Some(1));
|
||||
assert_eq!(models[0]["id"].as_str(), Some("remote-model"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ fn help() {
|
|||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
-v, --verbose Enable verbose output
|
||||
--sandbox <SANDBOX> Sandbox for agent tools [possible values: local, docker, daytona]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ fn help() {
|
|||
-a, --all Show all runs, not just running (like docker ps -a)
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
-q, --quiet Only display run IDs
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
@ -112,8 +112,8 @@ fn test_repo_init_help_does_not_show_skill() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ fn help() {
|
|||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--model <MODEL> Override default LLM model
|
||||
--provider <PROVIDER> Override default LLM provider
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-v, --verbose Enable verbose output
|
||||
--sandbox <SANDBOX> Sandbox for agent tools [possible values: local, docker, daytona]
|
||||
--label <KEY=VALUE> Attach a label to this run (repeatable, format: KEY=VALUE)
|
||||
|
|
@ -374,7 +374,6 @@ fn json_run_implies_auto_approve_for_human_gates() {
|
|||
"model": "[LLM_MODEL]",
|
||||
"provider": "[LLM_PROVIDER]"
|
||||
},
|
||||
"mode": "standalone",
|
||||
"no_retro": true,
|
||||
"sandbox": {
|
||||
"daytona": null,
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ fn help() {
|
|||
--open Open URL in browser (implies --signed)
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -46,11 +46,11 @@ fn help() {
|
|||
--sandbox <SANDBOX>
|
||||
Sandbox for agent tools
|
||||
--storage-dir <STORAGE_DIR>
|
||||
Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--max-concurrent-runs <MAX_CONCURRENT_RUNS>
|
||||
Maximum number of concurrent run executions
|
||||
--server-url <SERVER_URL>
|
||||
Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
--config <CONFIG>
|
||||
Path to server config file (default: ~/.fabro/server.toml)
|
||||
-h, --help
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ fn help() {
|
|||
--debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=]
|
||||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ fn help() {
|
|||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--older-than <DURATION> Only prune runs older than this duration (e.g. 24h, 7d). Default: 24h when no explicit filters are set
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--yes Actually delete (default is dry-run)
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
"#);
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ fn help() {
|
|||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
||||
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Server URL (overrides server.base_url from user.toml) [env: FABRO_SERVER_URL=]
|
||||
--storage-dir <STORAGE_DIR> Local storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
||||
--server-url <SERVER_URL> Fabro API server URL (overrides server.base_url from user.toml when supported) [env: FABRO_SERVER_URL=]
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use crate::run::{
|
|||
};
|
||||
use crate::sandbox::SandboxConfig;
|
||||
use crate::server::{self, ApiConfig, FeaturesConfig, GitConfig, LogConfig, WebConfig};
|
||||
use crate::user::{self, ExecConfig, ExecutionMode, ServerConfig};
|
||||
use crate::user::{self, ExecConfig, ServerConfig};
|
||||
use fabro_types::Settings;
|
||||
|
||||
fn is_default_checkpoint(c: &CheckpointConfig) -> bool {
|
||||
|
|
@ -77,9 +77,6 @@ pub struct ConfigLayer {
|
|||
pub github: Option<GitHubConfig>,
|
||||
|
||||
// --- User config fields ---
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub mode: Option<ExecutionMode>,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub server: Option<ServerConfig>,
|
||||
|
||||
|
|
@ -161,7 +158,6 @@ impl Combine for ConfigLayer {
|
|||
hooks,
|
||||
mcp_servers: self.mcp_servers.combine(other.mcp_servers),
|
||||
github: self.github.combine(other.github),
|
||||
mode: self.mode.combine(other.mode),
|
||||
server: self.server.combine(other.server),
|
||||
exec: self.exec.combine(other.exec),
|
||||
prevent_idle_sleep: self.prevent_idle_sleep.combine(other.prevent_idle_sleep),
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ impl TryFrom<ConfigLayer> for Settings {
|
|||
hooks: value.hooks,
|
||||
mcp_servers: value.mcp_servers,
|
||||
github: value.github.map(Into::into),
|
||||
mode: value.mode,
|
||||
server: value.server.map(TryInto::try_into).transpose()?,
|
||||
exec: value.exec.map(Into::into),
|
||||
prevent_idle_sleep: value.prevent_idle_sleep,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
|||
use crate::config::ConfigLayer;
|
||||
|
||||
pub use fabro_types::settings::user::{
|
||||
ClientTlsSettings, ExecSettings, ExecutionMode, OutputFormat, PermissionLevel, ServerSettings,
|
||||
ClientTlsSettings, ExecSettings, OutputFormat, PermissionLevel, ServerSettings,
|
||||
};
|
||||
|
||||
pub const USER_CONFIG_FILENAME: &str = "user.toml";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use axum::body::Body;
|
||||
use axum::body::{Body, to_bytes};
|
||||
use axum::http::{Method, Request, StatusCode};
|
||||
use fabro_server::jwt_auth::AuthMode;
|
||||
use fabro_server::server::{build_router, create_app_state};
|
||||
use tower::ServiceExt;
|
||||
|
||||
|
|
@ -7,10 +8,7 @@ use crate::helpers::body_json;
|
|||
|
||||
#[tokio::test]
|
||||
async fn old_unversioned_routes_return_404() {
|
||||
let app = build_router(
|
||||
create_app_state(),
|
||||
fabro_server::jwt_auth::AuthMode::Disabled,
|
||||
);
|
||||
let app = build_router(create_app_state(), AuthMode::Disabled);
|
||||
|
||||
let cases = [(Method::POST, "/completions")];
|
||||
|
||||
|
|
@ -27,10 +25,7 @@ async fn old_unversioned_routes_return_404() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn root_and_health_stay_at_root() {
|
||||
let app = build_router(
|
||||
create_app_state(),
|
||||
fabro_server::jwt_auth::AuthMode::Disabled,
|
||||
);
|
||||
let app = build_router(create_app_state(), AuthMode::Disabled);
|
||||
|
||||
let root_req = Request::builder()
|
||||
.method("GET")
|
||||
|
|
@ -39,7 +34,7 @@ async fn root_and_health_stay_at_root() {
|
|||
.unwrap();
|
||||
let root_response = app.clone().oneshot(root_req).await.unwrap();
|
||||
assert_eq!(root_response.status(), StatusCode::OK);
|
||||
let root_body = axum::body::to_bytes(root_response.into_body(), usize::MAX)
|
||||
let root_body = to_bytes(root_response.into_body(), usize::MAX)
|
||||
.await
|
||||
.unwrap();
|
||||
let root_html = String::from_utf8(root_body.to_vec()).unwrap();
|
||||
|
|
@ -58,10 +53,7 @@ async fn root_and_health_stay_at_root() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn moved_routes_not_at_root_of_api_prefix() {
|
||||
let app = build_router(
|
||||
create_app_state(),
|
||||
fabro_server::jwt_auth::AuthMode::Disabled,
|
||||
);
|
||||
let app = build_router(create_app_state(), AuthMode::Disabled);
|
||||
|
||||
for path in ["/api/v1/health", "/api/v1/"] {
|
||||
let req = Request::builder()
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use axum::body::Body;
|
||||
use axum::body::{Body, to_bytes};
|
||||
use axum::http::{Request, StatusCode};
|
||||
use fabro_server::jwt_auth::AuthMode;
|
||||
use fabro_server::server::{
|
||||
AppState, build_router, create_app_state, create_app_state_with_options, spawn_scheduler,
|
||||
};
|
||||
use fabro_types::Settings;
|
||||
use tokio::time::sleep;
|
||||
use tower::ServiceExt;
|
||||
|
||||
pub(crate) const MINIMAL_DOT: &str = r#"digraph Test {
|
||||
|
|
@ -47,7 +48,7 @@ pub(crate) fn api(path: &str) -> String {
|
|||
}
|
||||
|
||||
pub(crate) async fn body_json(body: Body) -> serde_json::Value {
|
||||
let bytes = axum::body::to_bytes(body, usize::MAX).await.unwrap();
|
||||
let bytes = to_bytes(body, usize::MAX).await.unwrap();
|
||||
serde_json::from_slice(&bytes).unwrap()
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +99,7 @@ pub(crate) async fn wait_for_run_status(
|
|||
if expected.iter().any(|candidate| *candidate == status) {
|
||||
return status;
|
||||
}
|
||||
tokio::time::sleep(POLL_INTERVAL).await;
|
||||
sleep(POLL_INTERVAL).await;
|
||||
}
|
||||
panic!("run {run_id} did not reach any of {expected:?}");
|
||||
}
|
||||
|
|
@ -114,7 +115,7 @@ pub(crate) async fn wait_for_run_status_not_in(
|
|||
if unexpected.iter().all(|candidate| *candidate != status) {
|
||||
return status;
|
||||
}
|
||||
tokio::time::sleep(POLL_INTERVAL).await;
|
||||
sleep(POLL_INTERVAL).await;
|
||||
}
|
||||
panic!("run {run_id} stayed in {unexpected:?}");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@ use std::sync::Arc;
|
|||
use axum::body::Body;
|
||||
use axum::http::{Request, StatusCode};
|
||||
use fabro_interview::Interviewer;
|
||||
use fabro_server::server::{build_router, create_app_state_with_registry_factory};
|
||||
use fabro_server::jwt_auth::AuthMode;
|
||||
use fabro_server::server::{build_router, create_app_state_with_registry_factory, spawn_scheduler};
|
||||
use fabro_workflow::handler::HandlerRegistry;
|
||||
use fabro_workflow::handler::agent::AgentHandler;
|
||||
use fabro_workflow::handler::exit::ExitHandler;
|
||||
use fabro_workflow::handler::human::HumanHandler;
|
||||
use fabro_workflow::handler::start::StartHandler;
|
||||
use tokio::time::sleep;
|
||||
use tower::ServiceExt;
|
||||
|
||||
use crate::helpers::{
|
||||
|
|
@ -42,7 +44,7 @@ async fn wait_for_question_id(app: &axum::Router, run_id: &str) -> String {
|
|||
{
|
||||
return question_id;
|
||||
}
|
||||
tokio::time::sleep(POLL_INTERVAL).await;
|
||||
sleep(POLL_INTERVAL).await;
|
||||
}
|
||||
panic!("question should have appeared");
|
||||
}
|
||||
|
|
@ -66,11 +68,8 @@ const GATE_DOT: &str = r#"digraph GateTest {
|
|||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn full_http_lifecycle_approve_and_complete() {
|
||||
let state = create_app_state_with_registry_factory(gate_registry);
|
||||
fabro_server::server::spawn_scheduler(Arc::clone(&state));
|
||||
let app = build_router(
|
||||
Arc::clone(&state),
|
||||
fabro_server::jwt_auth::AuthMode::Disabled,
|
||||
);
|
||||
spawn_scheduler(Arc::clone(&state));
|
||||
let app = build_router(Arc::clone(&state), AuthMode::Disabled);
|
||||
|
||||
// 1. Create run
|
||||
let req = Request::builder()
|
||||
|
|
@ -134,11 +133,8 @@ async fn full_http_lifecycle_approve_and_complete() {
|
|||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn full_http_lifecycle_cancel() {
|
||||
let state = create_app_state_with_registry_factory(gate_registry);
|
||||
fabro_server::server::spawn_scheduler(Arc::clone(&state));
|
||||
let app = build_router(
|
||||
Arc::clone(&state),
|
||||
fabro_server::jwt_auth::AuthMode::Disabled,
|
||||
);
|
||||
spawn_scheduler(Arc::clone(&state));
|
||||
let app = build_router(Arc::clone(&state), AuthMode::Disabled);
|
||||
|
||||
// Create and start a run that will block at the human gate
|
||||
let req = Request::builder()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use axum::body::Body;
|
||||
use axum::http::{Request, StatusCode};
|
||||
use fabro_server::server::create_app_state_with_options;
|
||||
use tokio::time::sleep;
|
||||
use tower::ServiceExt;
|
||||
|
||||
use crate::helpers::{
|
||||
|
|
@ -27,7 +28,7 @@ async fn attach_run_events_returns_sse_stream() {
|
|||
let run_id = create_and_start_run(&app, MINIMAL_DOT).await;
|
||||
|
||||
// Wait for scheduler to promote run.
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
sleep(std::time::Duration::from_millis(100)).await;
|
||||
|
||||
let req = Request::builder()
|
||||
.method("GET")
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use axum::body::Body;
|
|||
use axum::http::{Request, StatusCode};
|
||||
use fabro_server::server::create_app_state_with_options;
|
||||
use http_body_util::BodyExt;
|
||||
use tokio::time::{sleep, timeout};
|
||||
use tower::ServiceExt;
|
||||
|
||||
use crate::helpers::{
|
||||
|
|
@ -30,7 +31,7 @@ async fn wait_for_checkpoint(app: &axum::Router, run_id: &str) -> serde_json::Va
|
|||
if response.status() == StatusCode::OK {
|
||||
return body_json(response.into_body()).await;
|
||||
}
|
||||
tokio::time::sleep(POLL_INTERVAL).await;
|
||||
sleep(POLL_INTERVAL).await;
|
||||
}
|
||||
panic!("checkpoint did not become available for {run_id}");
|
||||
}
|
||||
|
|
@ -72,8 +73,7 @@ async fn sse_stream_contains_expected_event_types() {
|
|||
// Collect SSE frames with a timeout
|
||||
let mut body = response.into_body();
|
||||
let mut sse_data = String::new();
|
||||
while let Ok(Some(Ok(frame))) = tokio::time::timeout(Duration::from_secs(2), body.frame()).await
|
||||
{
|
||||
while let Ok(Some(Ok(frame))) = timeout(Duration::from_secs(2), body.frame()).await {
|
||||
if let Some(data) = frame.data_ref() {
|
||||
sse_data.push_str(&String::from_utf8_lossy(data));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use axum::body::Body;
|
||||
use axum::http::{Request, StatusCode};
|
||||
use fabro_server::server::create_app_state_with_options;
|
||||
use tokio::time::sleep;
|
||||
use tower::ServiceExt;
|
||||
|
||||
use crate::helpers::{
|
||||
|
|
@ -35,7 +36,7 @@ async fn aggregate_usage_increments_after_run_completes() {
|
|||
if total_runs == 1 {
|
||||
break;
|
||||
}
|
||||
tokio::time::sleep(POLL_INTERVAL).await;
|
||||
sleep(POLL_INTERVAL).await;
|
||||
}
|
||||
assert_eq!(total_runs, 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ fn stop_session_server(storage_dir: &Path) {
|
|||
let Ok(record) = serde_json::from_str::<serde_json::Value>(&content) else {
|
||||
return;
|
||||
};
|
||||
let Some(pid) = record["pid"].as_u64().map(|p| p as u32) else {
|
||||
let Some(pid) = record["pid"].as_u64().and_then(|p| u32::try_from(p).ok()) else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@ pub use server::{
|
|||
GitProvider, GitSettings, LogSettings, TlsSettings, WebSettings, WebhookSettings,
|
||||
WebhookStrategy,
|
||||
};
|
||||
pub use user::{
|
||||
ClientTlsSettings, ExecSettings, ExecutionMode, OutputFormat, PermissionLevel, ServerSettings,
|
||||
};
|
||||
pub use user::{ClientTlsSettings, ExecSettings, OutputFormat, PermissionLevel, ServerSettings};
|
||||
|
||||
fn is_default_checkpoint(c: &CheckpointSettings) -> bool {
|
||||
c.exclude_globs.is_empty()
|
||||
|
|
@ -73,8 +71,6 @@ pub struct Settings {
|
|||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub github: Option<GitHubSettings>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub mode: Option<ExecutionMode>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub server: Option<ServerSettings>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub exec: Option<ExecSettings>,
|
||||
|
|
|
|||
|
|
@ -19,15 +19,6 @@ pub enum PermissionLevel {
|
|||
Full,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize, crate::Combine)]
|
||||
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum ExecutionMode {
|
||||
#[default]
|
||||
Standalone,
|
||||
Server,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub struct ClientTlsSettings {
|
||||
pub cert: PathBuf,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue