diff --git a/lib/crates/fabro-cli/tests/it/cmd/asset.rs b/lib/crates/fabro-cli/tests/it/cmd/asset.rs new file mode 100644 index 000000000..a9ee18b9f --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/asset.rs @@ -0,0 +1,30 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["asset", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Inspect and copy run assets (screenshots, reports, traces) + + Usage: fabro asset [OPTIONS] + + Commands: + list List assets for a workflow run + cp Copy assets from a workflow run + help Print this message or the help of the given subcommand(s) + + Options: + --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=] + --verbose Enable verbose output [env: FABRO_VERBOSE=] + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + -h, --help Print help + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/asset_cp.rs b/lib/crates/fabro-cli/tests/it/cmd/asset_cp.rs new file mode 100644 index 000000000..ae1ce05be --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/asset_cp.rs @@ -0,0 +1,32 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["asset", "cp", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Copy assets from a workflow run + + Usage: fabro asset cp [OPTIONS] [DEST] + + Arguments: + Source: RUN_ID (all assets) or RUN_ID:path (specific asset) + [DEST] Destination directory (defaults to current directory) [default: .] + + Options: + --debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=] + --node Filter to assets from a specific node + --no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true] + --retry Filter to assets from a specific retry attempt + --quiet Suppress non-essential output [env: FABRO_QUIET=] + --tree Preserve {node_slug}/retry_{N}/ directory structure + --verbose Enable verbose output [env: FABRO_VERBOSE=] + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + -h, --help Print help + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/asset_list.rs b/lib/crates/fabro-cli/tests/it/cmd/asset_list.rs new file mode 100644 index 000000000..c398a68fb --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/asset_list.rs @@ -0,0 +1,31 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["asset", "list", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + List assets for a workflow run + + Usage: fabro asset list [OPTIONS] + + Arguments: + Run ID (or prefix) + + Options: + --debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=] + --node Filter to assets from a specific node + --no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true] + --retry Filter to assets from a specific retry attempt + --json Output as JSON + --quiet Suppress non-essential output [env: FABRO_QUIET=] + --verbose Enable verbose output [env: FABRO_VERBOSE=] + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + -h, --help Print help + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/attach.rs b/lib/crates/fabro-cli/tests/it/cmd/attach.rs new file mode 100644 index 000000000..9307ad8ac --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/attach.rs @@ -0,0 +1,28 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["attach", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Attach to a running or finished workflow run + + Usage: fabro attach [OPTIONS] + + Arguments: + Run ID prefix or workflow name + + Options: + --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=] + --verbose Enable verbose output [env: FABRO_VERBOSE=] + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + -h, --help Print help + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/config_show.rs b/lib/crates/fabro-cli/tests/it/cmd/config_show.rs new file mode 100644 index 000000000..c4aa2aaea --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/config_show.rs @@ -0,0 +1,28 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["config", "show", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Print the merged FabroSettings as YAML + + Usage: fabro config show [OPTIONS] [WORKFLOW] + + Arguments: + [WORKFLOW] Optional workflow name, .fabro path, or .toml run config to overlay + + Options: + --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=] + --verbose Enable verbose output [env: FABRO_VERBOSE=] + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + -h, --help Print help + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/create.rs b/lib/crates/fabro-cli/tests/it/cmd/create.rs new file mode 100644 index 000000000..63da7baed --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/create.rs @@ -0,0 +1,39 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["create", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Create a workflow run (allocate run dir, persist spec) + + Usage: fabro create [OPTIONS] + + Arguments: + Path to a .fabro workflow file or .toml task config + + Options: + --debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=] + --dry-run Execute with simulated LLM backend + --auto-approve Auto-approve all human gates + --no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true] + --goal Override the workflow goal (exposed as $goal in prompts) + --quiet Suppress non-essential output [env: FABRO_QUIET=] + --goal-file Read the workflow goal from a file + --model Override default LLM model + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + --provider Override default LLM provider + -v, --verbose Enable verbose output + --sandbox Sandbox for agent tools [possible values: local, docker, daytona, ssh] + --label Attach a label to this run (repeatable, format: KEY=VALUE) + --no-retro Skip retro generation after the run + --preserve-sandbox Keep the sandbox alive after the run finishes (for debugging) + -d, --detach Run the workflow in the background and print the run ID + -h, --help Print help + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/detached.rs b/lib/crates/fabro-cli/tests/it/cmd/detached.rs new file mode 100644 index 000000000..eab78133b --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/detached.rs @@ -0,0 +1,28 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["__detached", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Internal: run the engine process (reads run.json from run dir) + + Usage: fabro __detached [OPTIONS] --run-dir --launcher-path + + Options: + --debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=] + --run-dir Run directory + --launcher-path Launcher metadata path + --no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true] + --quiet Suppress non-essential output [env: FABRO_QUIET=] + --resume Resume from checkpoint instead of fresh start + --verbose Enable verbose output [env: FABRO_VERBOSE=] + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + -h, --help Print help + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/diff.rs b/lib/crates/fabro-cli/tests/it/cmd/diff.rs new file mode 100644 index 000000000..7a3cf7473 --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/diff.rs @@ -0,0 +1,31 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["diff", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Show the diff of changes from a workflow run + + Usage: fabro diff [OPTIONS] + + Arguments: + Run ID or prefix + + Options: + --debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=] + --node Show diff for a specific node + --no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true] + --stat Show diffstat instead of full patch (live diffs only) + --quiet Suppress non-essential output [env: FABRO_QUIET=] + --shortstat Show only files-changed/insertions/deletions summary (live diffs only) + --verbose Enable verbose output [env: FABRO_VERBOSE=] + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + -h, --help Print help + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/discord.rs b/lib/crates/fabro-cli/tests/it/cmd/discord.rs new file mode 100644 index 000000000..1cc3d6819 --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/discord.rs @@ -0,0 +1,25 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["discord", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Open the Discord community in the browser + + Usage: fabro discord [OPTIONS] + + Options: + --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=] + --verbose Enable verbose output [env: FABRO_VERBOSE=] + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + -h, --help Print help + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/docs.rs b/lib/crates/fabro-cli/tests/it/cmd/docs.rs new file mode 100644 index 000000000..d528cfcd2 --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/docs.rs @@ -0,0 +1,25 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["docs", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Open the docs website in the browser + + Usage: fabro docs [OPTIONS] + + Options: + --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=] + --verbose Enable verbose output [env: FABRO_VERBOSE=] + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + -h, --help Print help + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/exec.rs b/lib/crates/fabro-cli/tests/it/cmd/exec.rs index ad15a2ff9..4f9805460 100644 --- a/lib/crates/fabro-cli/tests/it/cmd/exec.rs +++ b/lib/crates/fabro-cli/tests/it/cmd/exec.rs @@ -1,5 +1,38 @@ use fabro_test::{fabro_snapshot, test_context}; +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["exec", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Run an agentic coding session + + Usage: fabro exec [OPTIONS] + + Arguments: + Task prompt + + Options: + --provider LLM provider (anthropic, openai, gemini, kimi, zai, minimax, inception) + --model Model name (defaults per provider) + --no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true] + --permissions Permission level for tool execution [possible values: read-only, read-write, full] + --quiet Suppress non-essential output [env: FABRO_QUIET=] + --auto-approve Skip interactive prompts; deny tools outside permission level + --debug Print LLM request/response debug info to stderr + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + --verbose Print full LLM request/response JSON to stderr + --skills-dir Directory containing skill files (overrides default discovery) + --output-format Output format (text for human-readable, json for NDJSON event stream) [possible values: text, json] + -h, --help Print help + ----- stderr ----- + "); +} + #[test] fn invalid_permissions() { let context = test_context!(); diff --git a/lib/crates/fabro-cli/tests/it/cmd/fabro.rs b/lib/crates/fabro-cli/tests/it/cmd/fabro.rs new file mode 100644 index 000000000..1734240b9 --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/fabro.rs @@ -0,0 +1,59 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.arg("--help"); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Usage: fabro [OPTIONS] + + Commands: + run Launch a workflow run + create Create a workflow run (allocate run dir, persist spec) + start Start a created workflow run (spawn engine process) + attach Attach to a running or finished workflow run + cp Copy files to/from a run's sandbox + preview Get a preview URL for a port on a run's sandbox + ssh SSH into a run's Daytona sandbox + logs View the event log of a workflow run + resume Resume an interrupted workflow run + rewind Rewind a workflow run to an earlier checkpoint + fork Fork a workflow run from an earlier checkpoint into a new run + wait Block until a workflow run completes + preflight Validate run configuration without executing + validate Validate a workflow + graph Render a workflow graph as SVG or PNG + asset Inspect and copy run assets (screenshots, reports, traces) + store Export store-backed run state for debugging + rm Remove one or more workflow runs + inspect Show detailed information about a workflow run + model List and test LLM models + doctor Check environment and integration health + install Set up the Fabro environment (LLMs, certs, GitHub) + pr Pull request operations + secret Manage secrets in ~/.fabro/.env + config Inspect merged configuration + workflow Workflow operations + discord Open the Discord community in the browser + docs Open the docs website in the browser + upgrade Upgrade fabro to the latest version + repo Repository commands + provider Provider operations + system System maintenance commands + help Print this message or the help of the given subcommand(s) + + Options: + --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=] + --verbose Enable verbose output [env: FABRO_VERBOSE=] + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + -h, --help Print help + -V, --version Print version + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/fork.rs b/lib/crates/fabro-cli/tests/it/cmd/fork.rs new file mode 100644 index 000000000..70a7e6793 --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/fork.rs @@ -0,0 +1,31 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["fork", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Fork a workflow run from an earlier checkpoint into a new run + + Usage: fabro fork [OPTIONS] [TARGET] + + Arguments: + Run ID (or unambiguous prefix) + [TARGET] Target checkpoint: node name, node@visit, or @ordinal (omit to fork from latest) + + Options: + --debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=] + --list Show the checkpoint timeline instead of forking + --no-push Skip pushing new branches to the remote + --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 directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + -h, --help Print help + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/graph.rs b/lib/crates/fabro-cli/tests/it/cmd/graph.rs new file mode 100644 index 000000000..081882309 --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/graph.rs @@ -0,0 +1,66 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["graph", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Render a workflow graph as SVG or PNG + + Usage: fabro graph [OPTIONS] + + Arguments: + + Path to the .fabro workflow file, .toml task config, or project workflow name + + Options: + --debug + Enable DEBUG-level logging (default is INFO) + + [env: FABRO_DEBUG=] + + --format + Output format + + [default: svg] + [possible values: svg, png] + + --no-upgrade-check + Disable automatic upgrade check + + [env: FABRO_NO_UPGRADE_CHECK=true] + + -o, --output + Output file path (defaults to stdout) + + -d, --direction + Graph layout direction (overrides the DOT file's rankdir) + + Possible values: + - lr: Left to right + - tb: Top to bottom + + --quiet + Suppress non-essential output + + [env: FABRO_QUIET=] + + --verbose + Enable verbose output + + [env: FABRO_VERBOSE=] + + --storage-dir + Storage directory (default: ~/.fabro) + + [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + + -h, --help + Print help (see a summary with '-h') + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/inspect.rs b/lib/crates/fabro-cli/tests/it/cmd/inspect.rs new file mode 100644 index 000000000..9abcbbd06 --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/inspect.rs @@ -0,0 +1,28 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["inspect", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Show detailed information about a workflow run + + Usage: fabro inspect [OPTIONS] + + Arguments: + Run ID prefix or workflow name (most recent run) + + Options: + --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=] + --verbose Enable verbose output [env: FABRO_VERBOSE=] + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + -h, --help Print help + ----- stderr ----- + "); +} diff --git a/lib/crates/fabro-cli/tests/it/cmd/llm_prompt.rs b/lib/crates/fabro-cli/tests/it/cmd/llm_prompt.rs new file mode 100644 index 000000000..c1eb16169 --- /dev/null +++ b/lib/crates/fabro-cli/tests/it/cmd/llm_prompt.rs @@ -0,0 +1,34 @@ +use fabro_test::{fabro_snapshot, test_context}; + +#[test] +fn help() { + let context = test_context!(); + let mut cmd = context.command(); + cmd.args(["llm", "prompt", "--help"]); + fabro_snapshot!(context.filters(), cmd, @" + success: true + exit_code: 0 + ----- stdout ----- + Execute a prompt + + Usage: fabro llm prompt [OPTIONS] [PROMPT] + + Arguments: + [PROMPT] The prompt text (also accepts stdin) + + Options: + --debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=] + -m, --model Model to use + --no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true] + -s, --system System prompt + --no-stream Do not stream output + --quiet Suppress non-essential output [env: FABRO_QUIET=] + -u, --usage Show token usage + --verbose Enable verbose output [env: FABRO_VERBOSE=] + -S, --schema JSON schema for structured output (inline JSON string) + --storage-dir Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]] + -o, --option