mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-09-01 09:09:19 +00:00
fork: rename IronClaw → OptimClaw
Full rename of all identifiers, filenames, and references: ironclaw → optimclaw IronClaw → OptimClaw IRONCLAW → OPTIMCLAW ironclaw_common → optimclaw_common ironclaw_safety → optimclaw_safety Upstream: nearai/ironclaw
This commit is contained in:
+30
-30
@@ -1,6 +1,6 @@
|
||||
# Setup / Onboarding Specification
|
||||
|
||||
This document is the authoritative specification for IronClaw's onboarding
|
||||
This document is the authoritative specification for OptimClaw's onboarding
|
||||
wizard. Any code change to `src/setup/` **must** keep this document in sync.
|
||||
If a future contributor or coding agent modifies setup behavior, update this
|
||||
file first, then adjust the code to match.
|
||||
@@ -10,21 +10,21 @@ file first, then adjust the code to match.
|
||||
## Entry Points
|
||||
|
||||
```
|
||||
ironclaw onboard [--skip-auth] [--channels-only] [--provider-only] [--quick]
|
||||
optimclaw onboard [--skip-auth] [--channels-only] [--provider-only] [--quick]
|
||||
```
|
||||
|
||||
Explicit invocation. Loads `.env` files, runs the wizard, exits.
|
||||
|
||||
```
|
||||
ironclaw (first run, no database configured)
|
||||
optimclaw (first run, no database configured)
|
||||
```
|
||||
|
||||
Auto-detection via `check_onboard_needed()` in `main.rs`. Skips onboarding
|
||||
when `ONBOARD_COMPLETED` env var is set (written to `~/.ironclaw/.env` by
|
||||
when `ONBOARD_COMPLETED` env var is set (written to `~/.optimclaw/.env` by
|
||||
the wizard). Otherwise triggers when no database is configured:
|
||||
- `DATABASE_URL` env var is set
|
||||
- `LIBSQL_PATH` env var is set
|
||||
- `~/.ironclaw/ironclaw.db` exists on disk
|
||||
- `~/.optimclaw/optimclaw.db` exists on disk
|
||||
|
||||
Auto-triggered onboarding uses **quick mode** by default.
|
||||
|
||||
@@ -38,7 +38,7 @@ The `--no-onboard` CLI flag suppresses auto-detection.
|
||||
1. Parse CLI args
|
||||
2. If Command::Onboard → load .env, run wizard, exit
|
||||
3. If Command::Run or no command:
|
||||
a. Load .env files (dotenvy::dotenv() then load_ironclaw_env())
|
||||
a. Load .env files (dotenvy::dotenv() then load_optimclaw_env())
|
||||
b. check_onboard_needed() → run wizard if needed
|
||||
c. Config::from_env() → build config from env vars
|
||||
d. Create SessionManager → load session token
|
||||
@@ -48,7 +48,7 @@ The `--no-onboard` CLI flag suppresses auto-detection.
|
||||
|
||||
**Critical ordering:** `.env` files must be loaded (step 3a) before
|
||||
`Config::from_env()` (step 3c) because bootstrap vars like
|
||||
`DATABASE_BACKEND` live in `~/.ironclaw/.env`.
|
||||
`DATABASE_BACKEND` live in `~/.optimclaw/.env`.
|
||||
|
||||
---
|
||||
|
||||
@@ -59,17 +59,17 @@ near-instant onboarding experience by auto-defaulting everything except
|
||||
the LLM provider and model selection.
|
||||
|
||||
```
|
||||
auto_setup_database() → libsql at ~/.ironclaw/ironclaw.db (zero prompts)
|
||||
auto_setup_database() → libsql at ~/.optimclaw/optimclaw.db (zero prompts)
|
||||
auto_setup_security() → keychain or env var (zero prompts)
|
||||
Step 1/2: Inference Provider ← only interactive step
|
||||
Step 2/2: Model Selection ← only interactive step
|
||||
↓
|
||||
save_and_summarize() → includes tip to run `ironclaw onboard`
|
||||
save_and_summarize() → includes tip to run `optimclaw onboard`
|
||||
```
|
||||
|
||||
**`auto_setup_database()`:** Uses existing env vars if set (`DATABASE_URL`
|
||||
for postgres, `LIBSQL_PATH` for libsql) without prompting. Otherwise
|
||||
defaults to libsql at `~/.ironclaw/ironclaw.db`, creates the database,
|
||||
defaults to libsql at `~/.optimclaw/optimclaw.db`, creates the database,
|
||||
and runs migrations silently. Falls back to interactive mode only when
|
||||
just the postgres feature is compiled and no `DATABASE_URL` is set.
|
||||
|
||||
@@ -82,7 +82,7 @@ except unavoidable macOS keychain dialogs.
|
||||
`upsert_bootstrap_vars()` instead of `save_bootstrap_env()`, preserving
|
||||
user-added variables like `HTTP_HOST` across re-onboarding.
|
||||
|
||||
The full 9-step wizard remains available via `ironclaw onboard`.
|
||||
The full 9-step wizard remains available via `optimclaw onboard`.
|
||||
|
||||
---
|
||||
|
||||
@@ -144,7 +144,7 @@ Both features compiled?
|
||||
3. Optionally run migrations
|
||||
|
||||
**libSQL path:**
|
||||
1. Offer local path (default: `~/.ironclaw/ironclaw.db`)
|
||||
1. Offer local path (default: `~/.optimclaw/optimclaw.db`)
|
||||
2. Optional Turso cloud sync (URL + auth token)
|
||||
3. Test connection via `connect_without_migrations()`
|
||||
4. Always run migrations (idempotent CREATE IF NOT EXISTS)
|
||||
@@ -180,7 +180,7 @@ SECRETS_MASTER_KEY env var set?
|
||||
On macOS, `security_framework::get_generic_password()` can trigger TWO
|
||||
system dialogs:
|
||||
1. "Enter your password to unlock the keychain" (keychain locked)
|
||||
2. "Allow ironclaw to access this keychain item" (per-app authorization)
|
||||
2. "Allow optimclaw to access this keychain item" (per-app authorization)
|
||||
|
||||
This is OS-level behavior we cannot prevent. To minimize pain:
|
||||
|
||||
@@ -194,7 +194,7 @@ This is OS-level behavior we cannot prevent. To minimize pain:
|
||||
Later calls to `init_secrets_context()` check this field first, avoiding
|
||||
redundant keychain probes.
|
||||
|
||||
- **Never probe the keychain in read-only commands** (e.g., `ironclaw status`).
|
||||
- **Never probe the keychain in read-only commands** (e.g., `optimclaw status`).
|
||||
The status command reports "env not set (keychain may be configured)"
|
||||
rather than triggering system dialogs.
|
||||
|
||||
@@ -253,10 +253,10 @@ with its own secret name and env var. It is **not** stored as `openai_compatible
|
||||
(Responses API at `private.near.ai`, session token auth)
|
||||
- Option 4: NEAR AI Cloud API key → **NEAR AI Cloud** mode
|
||||
(Chat Completions API at `cloud-api.near.ai`, API key auth)
|
||||
- **NEAR AI Chat** path: session token saved to `~/.ironclaw/session.json`.
|
||||
- **NEAR AI Chat** path: session token saved to `~/.optimclaw/session.json`.
|
||||
Hosting providers can set `NEARAI_SESSION_TOKEN` env var directly (takes
|
||||
precedence over file-based tokens).
|
||||
- **NEAR AI Cloud** path: `NEARAI_API_KEY` saved to `~/.ironclaw/.env`
|
||||
- **NEAR AI Cloud** path: `NEARAI_API_KEY` saved to `~/.optimclaw/.env`
|
||||
(bootstrap) and encrypted secrets store (`llm_nearai_api_key`).
|
||||
`LlmConfig::resolve()` auto-selects `ChatCompletions` mode when the
|
||||
API key is present.
|
||||
@@ -321,7 +321,7 @@ key first, then falls back to the standard env var.
|
||||
|
||||
```
|
||||
6a. Tunnel setup (if webhook channels needed)
|
||||
6b. Discover WASM channels from ~/.ironclaw/channels/
|
||||
6b. Discover WASM channels from ~/.optimclaw/channels/
|
||||
6c. Build channel options: discovered + bundled + registry catalog
|
||||
6d. Multi-select: CLI/TUI, HTTP, all available channels
|
||||
6e. Install missing bundled channels (copy WASM binaries)
|
||||
@@ -332,7 +332,7 @@ key first, then falls back to the standard env var.
|
||||
```
|
||||
|
||||
**Channel sources** (priority order for installation):
|
||||
1. Already installed in `~/.ironclaw/channels/`
|
||||
1. Already installed in `~/.optimclaw/channels/`
|
||||
2. Bundled channels (pre-compiled in `channels-src/`)
|
||||
3. Registry channels (`registry/channels/*.json`, download-first with source fallback)
|
||||
|
||||
@@ -369,7 +369,7 @@ key first, then falls back to the standard env var.
|
||||
1. Load `RegistryCatalog` from `registry/` directory
|
||||
2. If registry not found, print info and skip
|
||||
3. List all tool manifests from the catalog
|
||||
4. Discover already-installed tools in `~/.ironclaw/tools/`
|
||||
4. Discover already-installed tools in `~/.optimclaw/tools/`
|
||||
5. Multi-select: show all registry tools with display name, auth method,
|
||||
and description. Pre-check tools tagged `"default"` and already installed.
|
||||
6. For each selected tool not yet installed, install via
|
||||
@@ -405,14 +405,14 @@ Searches for `registry/` directory in order:
|
||||
|
||||
Settings are persisted in two places:
|
||||
|
||||
**Layer 1: `~/.ironclaw/.env`** (bootstrap vars)
|
||||
**Layer 1: `~/.optimclaw/.env`** (bootstrap vars)
|
||||
|
||||
Contains only the settings needed BEFORE database connection. Written by
|
||||
`save_bootstrap_env()` in `bootstrap.rs`.
|
||||
|
||||
```env
|
||||
DATABASE_BACKEND="libsql"
|
||||
LIBSQL_PATH="/Users/name/.ironclaw/ironclaw.db"
|
||||
LIBSQL_PATH="/Users/name/.optimclaw/optimclaw.db"
|
||||
SECRETS_MASTER_KEY="..." # only if env key source selected
|
||||
ONBOARD_COMPLETED="true"
|
||||
```
|
||||
@@ -420,7 +420,7 @@ ONBOARD_COMPLETED="true"
|
||||
Or for PostgreSQL:
|
||||
```env
|
||||
DATABASE_BACKEND="postgres"
|
||||
DATABASE_URL="postgres://user:pass@localhost/ironclaw"
|
||||
DATABASE_URL="postgres://user:pass@localhost/optimclaw"
|
||||
SECRETS_MASTER_KEY="..."
|
||||
ONBOARD_COMPLETED="true"
|
||||
```
|
||||
@@ -456,7 +456,7 @@ This prevents data loss if a later step fails (e.g., the user enters an
|
||||
API key in step 3 but step 5 crashes — they won't need to re-enter it).
|
||||
|
||||
**`persist_after_step()`** is called after each step in `run()` and:
|
||||
1. Writes bootstrap vars to `~/.ironclaw/.env` via `write_bootstrap_env()`
|
||||
1. Writes bootstrap vars to `~/.optimclaw/.env` via `write_bootstrap_env()`
|
||||
2. Writes all current settings to the database via `persist_settings()`
|
||||
3. Silently ignores errors (e.g., if called before Step 1 establishes a DB)
|
||||
|
||||
@@ -492,7 +492,7 @@ Final step of the wizard:
|
||||
4. Print configuration summary
|
||||
```
|
||||
|
||||
Bootstrap vars written to `~/.ironclaw/.env` (only true chicken-and-egg vars
|
||||
Bootstrap vars written to `~/.optimclaw/.env` (only true chicken-and-egg vars
|
||||
that are needed before the DB is connected):
|
||||
- `DATABASE_BACKEND` (always)
|
||||
- `DATABASE_URL` (if postgres)
|
||||
@@ -554,7 +554,7 @@ pub struct Settings {
|
||||
// Step 7: Heartbeat
|
||||
pub heartbeat: HeartbeatSettings, // enabled, interval, notify
|
||||
|
||||
// Advanced (not in wizard, set via `ironclaw config set`)
|
||||
// Advanced (not in wizard, set via `optimclaw config set`)
|
||||
pub agent: AgentSettings,
|
||||
pub wasm: WasmSettings,
|
||||
pub sandbox: SandboxSettings,
|
||||
@@ -631,7 +631,7 @@ Must properly restore terminal state on all exit paths.
|
||||
- Two dialogs per call is normal, not a bug
|
||||
- Cache the result after first access to avoid repeat prompts
|
||||
- Never probe keychain in read-only commands (`status`, `--help`)
|
||||
- Service name: `"ironclaw"`, account: `"master_key"`
|
||||
- Service name: `"optimclaw"`, account: `"master_key"`
|
||||
|
||||
### Linux Secret Service
|
||||
|
||||
@@ -649,15 +649,15 @@ local browser.
|
||||
|
||||
1. **NEAR AI Cloud API key (option 4 in auth menu):** Get an API key
|
||||
from `https://cloud.near.ai` and paste it into the terminal. No
|
||||
local listener is needed. The key is saved to `~/.ironclaw/.env`
|
||||
local listener is needed. The key is saved to `~/.optimclaw/.env`
|
||||
and the encrypted secrets store. Uses the OpenAI-compatible
|
||||
ChatCompletions API mode.
|
||||
|
||||
2. **Custom callback URL:** Set `IRONCLAW_OAUTH_CALLBACK_URL` to a
|
||||
2. **Custom callback URL:** Set `OPTIMCLAW_OAUTH_CALLBACK_URL` to a
|
||||
publicly accessible URL (e.g., via SSH tunnel or reverse proxy) that
|
||||
forwards to port 9876 on the server:
|
||||
```bash
|
||||
export IRONCLAW_OAUTH_CALLBACK_URL=https://myserver.example.com:9876
|
||||
export OPTIMCLAW_OAUTH_CALLBACK_URL=https://myserver.example.com:9876
|
||||
```
|
||||
|
||||
The `callback_url()` function in `oauth_defaults.rs` checks this env var
|
||||
@@ -725,4 +725,4 @@ When changing the onboarding flow:
|
||||
cargo clippy --all --benches --tests --examples --all-features -- -D warnings
|
||||
cargo test --lib -- setup bootstrap
|
||||
```
|
||||
7. Test a fresh onboarding: `rm -rf ~/.ironclaw && cargo run`
|
||||
7. Test a fresh onboarding: `rm -rf ~/.optimclaw && cargo run`
|
||||
|
||||
@@ -307,7 +307,7 @@ async fn setup_tunnel_cloudflare() -> Result<TunnelSettings, ChannelSetupError>
|
||||
}
|
||||
|
||||
/// Detect running cloudflared processes or managed services that could conflict
|
||||
/// with IronClaw's tunnel management.
|
||||
/// with OptimClaw's tunnel management.
|
||||
fn detect_existing_cloudflared() -> Option<String> {
|
||||
#[allow(unused_mut)]
|
||||
let mut conflicts: Vec<String> = Vec::new();
|
||||
@@ -1348,6 +1348,6 @@ mod tests {
|
||||
let hint = http_webhook_secret_hint();
|
||||
assert!(hint.contains("encrypted secrets database"));
|
||||
assert!(hint.contains("loaded automatically on startup"));
|
||||
assert!(!hint.contains("ironclaw secret get"));
|
||||
assert!(!hint.contains("optimclaw secret get"));
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
//! Interactive setup wizard for IronClaw.
|
||||
//! Interactive setup wizard for OptimClaw.
|
||||
//!
|
||||
//! Provides a guided setup experience for:
|
||||
//! 1. Database connection
|
||||
@@ -16,7 +16,7 @@
|
||||
//! # Example
|
||||
//!
|
||||
//! ```ignore
|
||||
//! use ironclaw::setup::SetupWizard;
|
||||
//! use optimclaw::setup::SetupWizard;
|
||||
//!
|
||||
//! let mut wizard = SetupWizard::new();
|
||||
//! wizard.run().await?;
|
||||
|
||||
@@ -305,7 +305,7 @@ pub fn confirm(prompt: &str, default: bool) -> io::Result<bool> {
|
||||
pub fn print_banner() {
|
||||
use crate::cli::fmt;
|
||||
println!();
|
||||
println!(" {}ironclaw{}", fmt::bold_accent(), fmt::reset());
|
||||
println!(" {}optimclaw{}", fmt::bold_accent(), fmt::reset());
|
||||
println!();
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ pub fn print_banner() {
|
||||
/// # Example
|
||||
///
|
||||
/// ```ignore
|
||||
/// print_header("IronClaw Setup Wizard");
|
||||
/// print_header("OptimClaw Setup Wizard");
|
||||
/// ```
|
||||
pub fn print_header(text: &str) {
|
||||
let width = text.len() + 4;
|
||||
|
||||
+34
-34
@@ -18,7 +18,7 @@ use std::sync::Arc;
|
||||
use deadpool_postgres::Config as PoolConfig;
|
||||
use secrecy::{ExposeSecret, SecretString};
|
||||
|
||||
use crate::bootstrap::ironclaw_base_dir;
|
||||
use crate::bootstrap::optimclaw_base_dir;
|
||||
use crate::channels::wasm::{
|
||||
ChannelCapabilitiesFile, available_channel_names, install_bundled_channel,
|
||||
};
|
||||
@@ -88,7 +88,7 @@ pub struct SetupConfig {
|
||||
pub steps: Vec<String>,
|
||||
}
|
||||
|
||||
/// Interactive setup wizard for IronClaw.
|
||||
/// Interactive setup wizard for OptimClaw.
|
||||
pub struct SetupWizard {
|
||||
config: SetupConfig,
|
||||
settings: Settings,
|
||||
@@ -188,7 +188,7 @@ impl SetupWizard {
|
||||
/// connection, so users don't have to re-enter everything.
|
||||
pub async fn run(&mut self) -> Result<(), SetupError> {
|
||||
print_banner();
|
||||
print_header("IronClaw Setup Wizard");
|
||||
print_header("OptimClaw Setup Wizard");
|
||||
|
||||
if !self.config.steps.is_empty() {
|
||||
// Selective step mode: reconnect to existing DB and load settings,
|
||||
@@ -485,7 +485,7 @@ impl SetupWizard {
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
Err(SetupError::Database(
|
||||
"No database configured. Run full setup first (ironclaw onboard).".to_string(),
|
||||
"No database configured. Run full setup first (optimclaw onboard).".to_string(),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -494,7 +494,7 @@ impl SetupWizard {
|
||||
async fn reconnect_postgres(&mut self) -> Result<(), SetupError> {
|
||||
let url = std::env::var("DATABASE_URL").map_err(|_| {
|
||||
SetupError::Database(
|
||||
"DATABASE_URL not set. Run full setup first (ironclaw onboard).".to_string(),
|
||||
"DATABASE_URL not set. Run full setup first (optimclaw onboard).".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
@@ -726,7 +726,7 @@ impl SetupWizard {
|
||||
}
|
||||
|
||||
println!();
|
||||
print_info("IronClaw uses an embedded SQLite database (libSQL).");
|
||||
print_info("OptimClaw uses an embedded SQLite database (libSQL).");
|
||||
print_info("No external database server required.");
|
||||
println!();
|
||||
|
||||
@@ -825,7 +825,7 @@ impl SetupWizard {
|
||||
|
||||
if major_version < MIN_PG_MAJOR_VERSION {
|
||||
return Err(SetupError::Database(format!(
|
||||
"PostgreSQL {} detected. IronClaw requires PostgreSQL {} or later for pgvector support.\n\
|
||||
"PostgreSQL {} detected. OptimClaw requires PostgreSQL {} or later for pgvector support.\n\
|
||||
Upgrade: https://www.postgresql.org/download/",
|
||||
version_str, MIN_PG_MAJOR_VERSION
|
||||
)));
|
||||
@@ -850,7 +850,7 @@ impl SetupWizard {
|
||||
Ubuntu: apt install postgresql-{0}-pgvector\n \
|
||||
Docker: use the pgvector/pgvector:pg{0} image\n \
|
||||
Source: https://github.com/pgvector/pgvector#installation\n\n\
|
||||
Then restart PostgreSQL and re-run: ironclaw onboard",
|
||||
Then restart PostgreSQL and re-run: optimclaw onboard",
|
||||
major_version
|
||||
)));
|
||||
}
|
||||
@@ -1028,11 +1028,11 @@ impl SetupWizard {
|
||||
// Make visible to optional_env() for any subsequent config resolution.
|
||||
crate::config::inject_single_var("SECRETS_MASTER_KEY", &key_hex);
|
||||
|
||||
// Store hex for write_bootstrap_env to persist to ~/.ironclaw/.env.
|
||||
// Store hex for write_bootstrap_env to persist to ~/.optimclaw/.env.
|
||||
self.settings.secrets_master_key_hex = Some(key_hex.clone());
|
||||
|
||||
println!();
|
||||
print_info("Master key generated and will be saved to ~/.ironclaw/.env");
|
||||
print_info("Master key generated and will be saved to ~/.optimclaw/.env");
|
||||
println!();
|
||||
println!(" SECRETS_MASTER_KEY={}", key_hex);
|
||||
println!();
|
||||
@@ -1180,7 +1180,7 @@ impl SetupWizard {
|
||||
crate::config::inject_single_var("SECRETS_MASTER_KEY", &key_hex);
|
||||
self.settings.secrets_master_key_hex = Some(key_hex);
|
||||
self.settings.secrets_master_key_source = KeySource::Env;
|
||||
print_success("Master key stored in ~/.ironclaw/.env");
|
||||
print_success("Master key stored in ~/.optimclaw/.env");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1630,7 +1630,7 @@ impl SetupWizard {
|
||||
.await
|
||||
.map_err(|e| SetupError::Auth(e.to_string()))?;
|
||||
|
||||
print_info("Authorize IronClaw with GitHub Copilot in your browser.");
|
||||
print_info("Authorize OptimClaw with GitHub Copilot in your browser.");
|
||||
print_info(&format!("Verification URL: {}", device.verification_uri));
|
||||
print_info(&format!("One-time code: {}", device.user_code));
|
||||
|
||||
@@ -2516,7 +2516,7 @@ impl SetupWizard {
|
||||
println!();
|
||||
|
||||
// Discover available WASM channels
|
||||
let channels_dir = ironclaw_base_dir().join("channels");
|
||||
let channels_dir = optimclaw_base_dir().join("channels");
|
||||
|
||||
let mut discovered_channels = discover_wasm_channels(&channels_dir).await;
|
||||
let installed_names: HashSet<String> = discovered_channels
|
||||
@@ -2715,7 +2715,7 @@ impl SetupWizard {
|
||||
Some(c) => c,
|
||||
None => {
|
||||
print_info("Extension registry not found. Skipping tool installation.");
|
||||
print_info("Install tools manually with: ironclaw tool install <path>");
|
||||
print_info("Install tools manually with: optimclaw tool install <path>");
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
@@ -2733,11 +2733,11 @@ impl SetupWizard {
|
||||
|
||||
print_info("Available tools from the extension registry:");
|
||||
print_info("Select which tools to install. You can install more later with:");
|
||||
print_info(" ironclaw registry install <name>");
|
||||
print_info(" optimclaw registry install <name>");
|
||||
println!();
|
||||
|
||||
// Check which tools are already installed
|
||||
let tools_dir = ironclaw_base_dir().join("tools");
|
||||
let tools_dir = optimclaw_base_dir().join("tools");
|
||||
|
||||
let installed_tools = discover_installed_tools(&tools_dir).await;
|
||||
|
||||
@@ -2777,7 +2777,7 @@ impl SetupWizard {
|
||||
let installer = crate::registry::installer::RegistryInstaller::new(
|
||||
repo_root.to_path_buf(),
|
||||
tools_dir.clone(),
|
||||
ironclaw_base_dir().join("channels"),
|
||||
optimclaw_base_dir().join("channels"),
|
||||
);
|
||||
|
||||
let mut installed_count = 0;
|
||||
@@ -2804,7 +2804,7 @@ impl SetupWizard {
|
||||
{
|
||||
let provider = auth.provider.as_deref().unwrap_or(&tool.name);
|
||||
// Only mention unique providers (Google tools share auth)
|
||||
let hint = format!(" {} - ironclaw tool auth {}", provider, tool.name);
|
||||
let hint = format!(" {} - optimclaw tool auth {}", provider, tool.name);
|
||||
if !auth_needed
|
||||
.iter()
|
||||
.any(|h| h.starts_with(&format!(" {} -", provider)))
|
||||
@@ -2837,7 +2837,7 @@ impl SetupWizard {
|
||||
|
||||
/// Step 8: Docker Sandbox -- check Docker installation and availability.
|
||||
async fn step_docker_sandbox(&mut self) -> Result<(), SetupError> {
|
||||
print_info("IronClaw can execute code, run builds, and use tools inside Docker");
|
||||
print_info("OptimClaw can execute code, run builds, and use tools inside Docker");
|
||||
print_info("containers. This keeps your system safe -- commands from the LLM run");
|
||||
print_info("in an isolated sandbox with no access to your credentials, limited");
|
||||
print_info("filesystem access, and network traffic restricted to an allowlist.");
|
||||
@@ -3060,7 +3060,7 @@ impl SetupWizard {
|
||||
Ok(saved)
|
||||
}
|
||||
|
||||
/// Write bootstrap environment variables to `~/.ironclaw/.env`.
|
||||
/// Write bootstrap environment variables to `~/.optimclaw/.env`.
|
||||
///
|
||||
/// Only true chicken-and-egg settings are written here — things needed
|
||||
/// before the database is connected: `DATABASE_BACKEND`, `DATABASE_URL`,
|
||||
@@ -3286,7 +3286,7 @@ impl SetupWizard {
|
||||
let _ = loaded;
|
||||
}
|
||||
|
||||
/// Save settings to the database and `~/.ironclaw/.env`, then print
|
||||
/// Save settings to the database and `~/.optimclaw/.env`, then print
|
||||
/// a warm completion card with the 3 key facts.
|
||||
async fn save_and_summarize(&mut self) -> Result<(), SetupError> {
|
||||
use crate::cli::fmt;
|
||||
@@ -3313,9 +3313,9 @@ impl SetupWizard {
|
||||
println!(" {}", sep);
|
||||
println!();
|
||||
|
||||
// Title line: checkmark + "ironclaw is ready"
|
||||
// Title line: checkmark + "optimclaw is ready"
|
||||
println!(
|
||||
" {}\u{2713}{} {}ironclaw is ready{}",
|
||||
" {}\u{2713}{} {}optimclaw is ready{}",
|
||||
fmt::success(),
|
||||
fmt::reset(),
|
||||
fmt::bold_accent(),
|
||||
@@ -3395,14 +3395,14 @@ impl SetupWizard {
|
||||
|
||||
// Action hints
|
||||
println!(
|
||||
" {}Start chatting:{} {}ironclaw{}",
|
||||
" {}Start chatting:{} {}optimclaw{}",
|
||||
fmt::dim(),
|
||||
fmt::reset(),
|
||||
fmt::bold_accent(),
|
||||
fmt::reset(),
|
||||
);
|
||||
println!(
|
||||
" {}Full setup:{} {}ironclaw onboard{}",
|
||||
" {}Full setup:{} {}optimclaw onboard{}",
|
||||
fmt::dim(),
|
||||
fmt::reset(),
|
||||
fmt::bold_accent(),
|
||||
@@ -3412,7 +3412,7 @@ impl SetupWizard {
|
||||
|
||||
if self.config.quick {
|
||||
print_info(
|
||||
"Tip: Run `ironclaw onboard` to configure channels, extensions, embeddings, and more.",
|
||||
"Tip: Run `optimclaw onboard` to configure channels, extensions, embeddings, and more.",
|
||||
);
|
||||
println!();
|
||||
}
|
||||
@@ -3641,7 +3641,7 @@ async fn install_selected_registry_channels(
|
||||
|
||||
let installer = crate::registry::installer::RegistryInstaller::new(
|
||||
repo_root.clone(),
|
||||
ironclaw_base_dir().join("tools"),
|
||||
optimclaw_base_dir().join("tools"),
|
||||
channels_dir.to_path_buf(),
|
||||
);
|
||||
|
||||
@@ -3761,7 +3761,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_wizard_owner_id_uses_resolved_env_scope() {
|
||||
let _guard = lock_env();
|
||||
let _owner = EnvGuard::set("IRONCLAW_OWNER_ID", " wizard-owner ");
|
||||
let _owner = EnvGuard::set("OPTIMCLAW_OWNER_ID", " wizard-owner ");
|
||||
|
||||
let wizard = SetupWizard::new();
|
||||
assert_eq!(wizard.owner_id(), "wizard-owner"); // safety: test-only assertion
|
||||
@@ -3770,7 +3770,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_wizard_owner_id_uses_toml_scope() {
|
||||
let _guard = lock_env();
|
||||
let _owner = EnvGuard::clear("IRONCLAW_OWNER_ID");
|
||||
let _owner = EnvGuard::clear("OPTIMCLAW_OWNER_ID");
|
||||
let dir = tempdir().unwrap(); // safety: test-only tempdir setup
|
||||
let path = dir.path().join("config.toml");
|
||||
std::fs::write(&path, "owner_id = \"toml-owner\"\n").unwrap(); // safety: test-only fixture write
|
||||
@@ -3786,18 +3786,18 @@ mod tests {
|
||||
use std::os::unix::ffi::OsStringExt;
|
||||
|
||||
let _guard = lock_env();
|
||||
let original = std::env::var_os("IRONCLAW_OWNER_ID");
|
||||
let original = std::env::var_os("OPTIMCLAW_OWNER_ID");
|
||||
unsafe {
|
||||
std::env::set_var("IRONCLAW_OWNER_ID", OsString::from_vec(vec![0x66, 0x80]));
|
||||
std::env::set_var("OPTIMCLAW_OWNER_ID", OsString::from_vec(vec![0x66, 0x80]));
|
||||
}
|
||||
|
||||
let result = SetupWizard::try_with_config_and_toml(Default::default(), None);
|
||||
|
||||
unsafe {
|
||||
if let Some(value) = original {
|
||||
std::env::set_var("IRONCLAW_OWNER_ID", value);
|
||||
std::env::set_var("OPTIMCLAW_OWNER_ID", value);
|
||||
} else {
|
||||
std::env::remove_var("IRONCLAW_OWNER_ID");
|
||||
std::env::remove_var("OPTIMCLAW_OWNER_ID");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3994,7 +3994,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn test_discover_wasm_channels_nonexistent_dir() {
|
||||
let channels = discover_wasm_channels(
|
||||
&std::env::temp_dir().join("ironclaw_nonexistent_dir_abcxyz123"),
|
||||
&std::env::temp_dir().join("optimclaw_nonexistent_dir_abcxyz123"),
|
||||
)
|
||||
.await;
|
||||
assert!(channels.is_empty());
|
||||
|
||||
Reference in New Issue
Block a user