Rename setup CLI command to onboard for compatibility

Serde alias on `onboard_completed` preserves existing settings.json files
that still have the old `setup_completed` key.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
This commit is contained in:
Illia Polosukhin
2026-02-06 09:56:32 -08:00
co-authored by Claude Opus 4.6
parent 48ab73574e
commit 8be390afab
8 changed files with 31 additions and 28 deletions
+3 -1
View File
@@ -450,7 +450,9 @@ async fn get_secrets_store() -> anyhow::Result<Arc<dyn SecretsStore + Send + Syn
let config = Config::from_env()?;
let master_key = config.secrets.master_key().ok_or_else(|| {
anyhow::anyhow!("SECRETS_MASTER_KEY not set. Run 'ironclaw setup' first or set it in .env")
anyhow::anyhow!(
"SECRETS_MASTER_KEY not set. Run 'ironclaw onboard' first or set it in .env"
)
})?;
let store = Store::new(&config.database).await?;
+5 -5
View File
@@ -2,7 +2,7 @@
//!
//! Provides subcommands for:
//! - Running the agent (`run`)
//! - Interactive setup wizard (`setup`)
//! - Interactive onboarding wizard (`onboard`)
//! - Managing configuration (`config list`, `config get`, `config set`)
//! - Managing WASM tools (`tool install`, `tool list`, `tool remove`)
//! - Managing MCP servers (`mcp add`, `mcp auth`, `mcp list`, `mcp test`)
@@ -53,9 +53,9 @@ pub struct Cli {
#[arg(short, long, global = true)]
pub config: Option<std::path::PathBuf>,
/// Skip first-run setup check
/// Skip first-run onboarding check
#[arg(long, global = true)]
pub no_setup: bool,
pub no_onboard: bool,
}
#[derive(Subcommand, Debug)]
@@ -63,8 +63,8 @@ pub enum Command {
/// Run the agent (default if no subcommand given)
Run,
/// Interactive setup wizard
Setup {
/// Interactive onboarding wizard
Onboard {
/// Skip authentication (use existing session)
#[arg(long)]
skip_auth: bool,
+1 -1
View File
@@ -40,7 +40,7 @@ pub async fn run_status_command() -> anyhow::Result<()> {
if session_path.exists() {
println!("found ({})", session_path.display());
} else {
println!("not found (run `ironclaw setup`)");
println!("not found (run `ironclaw onboard`)");
}
// Secrets
+3 -1
View File
@@ -717,7 +717,9 @@ async fn auth_tool(name: String, dir: Option<PathBuf>, user_id: String) -> anyho
// Initialize secrets store
let config = Config::from_env()?;
let master_key = config.secrets.master_key().ok_or_else(|| {
anyhow::anyhow!("SECRETS_MASTER_KEY not set. Run 'ironclaw setup' first or set it in .env")
anyhow::anyhow!(
"SECRETS_MASTER_KEY not set. Run 'ironclaw onboard' first or set it in .env"
)
})?;
let store = Store::new(&config.database).await?;
+2 -2
View File
@@ -138,7 +138,7 @@ impl DatabaseConfig {
.or(settings.database_url.clone())
.ok_or_else(|| ConfigError::MissingRequired {
key: "database_url".to_string(),
hint: "Run 'ironclaw setup' or set DATABASE_URL environment variable".to_string(),
hint: "Run 'ironclaw onboard' or set DATABASE_URL environment variable".to_string(),
})?;
// Priority: env var > settings > default
@@ -583,7 +583,7 @@ impl SecretsConfig {
// This might happen if keychain was cleared
tracing::warn!(
"Secrets configured for keychain but key not found. \
Run 'ironclaw setup' to reconfigure."
Run 'ironclaw onboard' to reconfigure."
);
(None, KeySource::None)
}
+11 -12
View File
@@ -128,14 +128,13 @@ async fn main() -> anyhow::Result<()> {
return run_status_command().await;
}
Some(Command::Setup {
Some(Command::Onboard {
skip_auth,
channels_only,
}) => {
// Load .env before running setup wizard
// Load .env before running onboarding wizard
let _ = dotenvy::dotenv();
// Run setup wizard
let config = SetupConfig {
skip_auth: *skip_auth,
channels_only: *channels_only,
@@ -153,9 +152,9 @@ async fn main() -> anyhow::Result<()> {
let _ = dotenvy::dotenv();
// Enhanced first-run detection
if !cli.no_setup {
if let Some(reason) = check_setup_needed() {
println!("Setup needed: {}", reason);
if !cli.no_onboard {
if let Some(reason) = check_onboard_needed() {
println!("Onboarding needed: {}", reason);
println!();
let mut wizard = SetupWizard::new();
wizard.run().await?;
@@ -170,7 +169,7 @@ async fn main() -> anyhow::Result<()> {
eprintln!(" {}", hint);
eprintln!();
eprintln!(
"Run 'ironclaw setup' to configure, or set the required environment variables."
"Run 'ironclaw onboard' to configure, or set the required environment variables."
);
std::process::exit(1);
}
@@ -781,10 +780,10 @@ async fn main() -> anyhow::Result<()> {
Ok(())
}
/// Check if setup is needed and return the reason.
/// Check if onboarding is needed and return the reason.
///
/// Returns `Some(reason)` if setup should be triggered, `None` otherwise.
fn check_setup_needed() -> Option<&'static str> {
/// Returns `Some(reason)` if onboarding should be triggered, `None` otherwise.
fn check_onboard_needed() -> Option<&'static str> {
let settings = Settings::load();
// Database not configured (and not in env)
@@ -801,9 +800,9 @@ fn check_setup_needed() -> Option<&'static str> {
// For now, we don't require it for first run
}
// First run (setup never completed and no session)
// First run (onboarding never completed and no session)
let session_path = ironclaw::llm::session::default_session_path();
if !settings.setup_completed && !session_path.exists() {
if !settings.onboard_completed && !session_path.exists() {
return Some("First run");
}
+4 -4
View File
@@ -10,9 +10,9 @@ use serde::{Deserialize, Serialize};
/// User settings persisted to disk.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Settings {
/// Whether setup wizard has been completed.
#[serde(default)]
pub setup_completed: bool,
/// Whether onboarding wizard has been completed.
#[serde(default, alias = "setup_completed")]
pub onboard_completed: bool,
// === Step 1: Database ===
/// Database connection URL (postgres://...).
@@ -775,7 +775,7 @@ mod tests {
// Check some expected entries
assert!(list.iter().any(|(k, _)| k == "agent.name"));
assert!(list.iter().any(|(k, _)| k == "heartbeat.enabled"));
assert!(list.iter().any(|(k, _)| k == "setup_completed"));
assert!(list.iter().any(|(k, _)| k == "onboard_completed"));
}
#[test]
+2 -2
View File
@@ -731,7 +731,7 @@ impl SetupWizard {
/// Save settings and print summary.
fn save_and_summarize(&mut self) -> Result<(), SetupError> {
self.settings.setup_completed = true;
self.settings.onboard_completed = true;
self.settings.save().map_err(|e| {
SetupError::Io(std::io::Error::new(
@@ -815,7 +815,7 @@ impl SetupWizard {
println!();
println!("To change settings later:");
println!(" ironclaw config set <setting> <value>");
println!(" ironclaw setup");
println!(" ironclaw onboard");
println!();
Ok(())