polish: wizard secure defaults, full summary, architecture SVG update
Wizard: - Default autonomy now Supervised + workspace_only=true (was Full + false) - print_summary shows Tunnel, Composio, Secrets, Gateway status - run_quick_setup shows Gateway, Tunnel, Composio in summary - Quick setup next steps include gateway command - Removed unused AutonomyLevel import Architecture SVG: - Sandbox section: 'Default: Supervised + workspace-only' - Wizard section: 'Live connection testing | Secure defaults' - Step 3: '7 channels + live test', Step 7: '8 workspace MD files' - Wizard output summary line listing all 9 config areas - Footer: 8 traits, 17,800+ lines, 0 clippy warnings README: - Config example clarifies supervised + workspace_only are defaults 1,017 tests, 0 clippy warnings, cargo fmt clean.
This commit is contained in:
parent
1fd51f1984
commit
a74a774ad5
3 changed files with 88 additions and 32 deletions
|
|
@ -141,8 +141,8 @@ require_pairing = true # require pairing code on first connect
|
||||||
allow_public_bind = false # refuse 0.0.0.0 without tunnel
|
allow_public_bind = false # refuse 0.0.0.0 without tunnel
|
||||||
|
|
||||||
[autonomy]
|
[autonomy]
|
||||||
level = "supervised" # "readonly", "supervised", "full"
|
level = "supervised" # "readonly", "supervised", "full" (default: supervised)
|
||||||
workspace_only = true
|
workspace_only = true # default: true — scoped to workspace
|
||||||
allowed_commands = ["git", "npm", "cargo", "ls", "cat", "grep"]
|
allowed_commands = ["git", "npm", "cargo", "ls", "cat", "grep"]
|
||||||
forbidden_paths = ["/etc", "/root", "/proc", "/sys", "~/.ssh", "~/.gnupg", "~/.aws"]
|
forbidden_paths = ["/etc", "/root", "/proc", "/sys", "~/.ssh", "~/.gnupg", "~/.aws"]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1100 920" font-family="'Segoe UI', system-ui, -apple-system, sans-serif">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1100 950" font-family="'Segoe UI', system-ui, -apple-system, sans-serif">
|
||||||
<defs>
|
<defs>
|
||||||
<filter id="shadow" x="-4%" y="-4%" width="108%" height="108%">
|
<filter id="shadow" x="-4%" y="-4%" width="108%" height="108%">
|
||||||
<feDropShadow dx="0" dy="2" stdDeviation="3" flood-opacity="0.15"/>
|
<feDropShadow dx="0" dy="2" stdDeviation="3" flood-opacity="0.15"/>
|
||||||
|
|
@ -24,11 +24,11 @@
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
<!-- Background -->
|
<!-- Background -->
|
||||||
<rect width="1100" height="920" rx="12" fill="url(#bgGrad)"/>
|
<rect width="1100" height="950" rx="12" fill="url(#bgGrad)"/>
|
||||||
|
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<text x="550" y="38" text-anchor="middle" fill="#e6edf3" font-size="22" font-weight="700">ZeroClaw Architecture</text>
|
<text x="550" y="38" text-anchor="middle" fill="#e6edf3" font-size="22" font-weight="700">ZeroClaw Architecture</text>
|
||||||
<text x="550" y="58" text-anchor="middle" fill="#7d8590" font-size="12">Zero overhead. Zero compromise. 100% Rust. 100% Agnostic.</text>
|
<text x="550" y="58" text-anchor="middle" fill="#7d8590" font-size="12">Zero overhead. Zero compromise. 100% Rust. 100% Agnostic. 8 pluggable traits.</text>
|
||||||
|
|
||||||
<!-- ═══════════ LEFT: Chat Apps ═══════════ -->
|
<!-- ═══════════ LEFT: Chat Apps ═══════════ -->
|
||||||
<rect x="20" y="80" width="150" height="310" rx="10" fill="#1c2333" stroke="#3b82f6" stroke-width="1.5" filter="url(#shadow)"/>
|
<rect x="20" y="80" width="150" height="310" rx="10" fill="#1c2333" stroke="#3b82f6" stroke-width="1.5" filter="url(#shadow)"/>
|
||||||
|
|
@ -240,8 +240,8 @@
|
||||||
<text x="695" y="652" text-anchor="middle" fill="#ef4444" font-size="9">Null byte injection blocked</text>
|
<text x="695" y="652" text-anchor="middle" fill="#ef4444" font-size="9">Null byte injection blocked</text>
|
||||||
<text x="695" y="669" text-anchor="middle" fill="#ef4444" font-size="9">Symlink escape detection</text>
|
<text x="695" y="669" text-anchor="middle" fill="#ef4444" font-size="9">Symlink escape detection</text>
|
||||||
<text x="695" y="686" text-anchor="middle" fill="#ef4444" font-size="9">14 system dirs + 4 dotfiles blocked</text>
|
<text x="695" y="686" text-anchor="middle" fill="#ef4444" font-size="9">14 system dirs + 4 dotfiles blocked</text>
|
||||||
<text x="695" y="706" text-anchor="middle" fill="#ef4444" font-size="9">Autonomy: ReadOnly / Supervised / Full</text>
|
<text x="695" y="706" text-anchor="middle" fill="#ef4444" font-size="9">Default: Supervised + workspace-only</text>
|
||||||
<text x="695" y="726" text-anchor="middle" fill="#ef4444" font-size="9">Workspace-only mode (default)</text>
|
<text x="695" y="726" text-anchor="middle" fill="#ef4444" font-size="9">Levels: ReadOnly / Supervised / Full</text>
|
||||||
|
|
||||||
<!-- Arrow: Agent → Sandbox -->
|
<!-- Arrow: Agent → Sandbox -->
|
||||||
<line x1="695" y1="550" x2="695" y2="570" stroke="#ef4444" stroke-width="2"/>
|
<line x1="695" y1="550" x2="695" y2="570" stroke="#ef4444" stroke-width="2"/>
|
||||||
|
|
@ -259,9 +259,9 @@
|
||||||
<line x1="960" y1="550" x2="960" y2="570" stroke="#06b6d4" stroke-width="2"/>
|
<line x1="960" y1="550" x2="960" y2="570" stroke="#06b6d4" stroke-width="2"/>
|
||||||
|
|
||||||
<!-- ═══════════ BOTTOM: Setup Wizard ═══════════ -->
|
<!-- ═══════════ BOTTOM: Setup Wizard ═══════════ -->
|
||||||
<rect x="20" y="760" width="1060" height="140" rx="10" fill="#1c2333" stroke="#f472b6" stroke-width="1.5" filter="url(#shadow)"/>
|
<rect x="20" y="760" width="1060" height="170" rx="10" fill="#1c2333" stroke="#f472b6" stroke-width="1.5" filter="url(#shadow)"/>
|
||||||
<text x="550" y="785" text-anchor="middle" fill="#f9a8d4" font-size="14" font-weight="700">Setup Wizard -- zeroclaw onboard (--quick for instant setup)</text>
|
<text x="550" y="785" text-anchor="middle" fill="#f9a8d4" font-size="14" font-weight="700">Setup Wizard -- zeroclaw onboard (--quick for instant setup)</text>
|
||||||
<text x="550" y="802" text-anchor="middle" fill="#7d8590" font-size="10">7 steps, under 60 seconds</text>
|
<text x="550" y="802" text-anchor="middle" fill="#7d8590" font-size="10">7 steps, under 60 seconds | Live connection testing | Secure defaults</text>
|
||||||
|
|
||||||
<!-- Wizard steps: 7 -->
|
<!-- Wizard steps: 7 -->
|
||||||
<rect x="30" y="815" width="130" height="38" rx="8" fill="#2d1f3d" stroke="#c084fc" stroke-width="1"/>
|
<rect x="30" y="815" width="130" height="38" rx="8" fill="#2d1f3d" stroke="#c084fc" stroke-width="1"/>
|
||||||
|
|
@ -274,7 +274,7 @@
|
||||||
|
|
||||||
<rect x="310" y="815" width="130" height="38" rx="8" fill="#2d1f3d" stroke="#c084fc" stroke-width="1"/>
|
<rect x="310" y="815" width="130" height="38" rx="8" fill="#2d1f3d" stroke="#c084fc" stroke-width="1"/>
|
||||||
<text x="375" y="831" text-anchor="middle" fill="#e9d5ff" font-size="8" font-weight="600">3. Channels</text>
|
<text x="375" y="831" text-anchor="middle" fill="#e9d5ff" font-size="8" font-weight="600">3. Channels</text>
|
||||||
<text x="375" y="845" text-anchor="middle" fill="#a78bfa" font-size="7">7 channels + test</text>
|
<text x="375" y="845" text-anchor="middle" fill="#a78bfa" font-size="7">7 channels + live test</text>
|
||||||
|
|
||||||
<rect x="450" y="815" width="130" height="38" rx="8" fill="#2d1f3d" stroke="#c084fc" stroke-width="1"/>
|
<rect x="450" y="815" width="130" height="38" rx="8" fill="#2d1f3d" stroke="#c084fc" stroke-width="1"/>
|
||||||
<text x="515" y="831" text-anchor="middle" fill="#e9d5ff" font-size="8" font-weight="600">4. Tunnel</text>
|
<text x="515" y="831" text-anchor="middle" fill="#e9d5ff" font-size="8" font-weight="600">4. Tunnel</text>
|
||||||
|
|
@ -290,7 +290,7 @@
|
||||||
|
|
||||||
<rect x="870" y="815" width="130" height="38" rx="8" fill="#2d1f3d" stroke="#c084fc" stroke-width="1"/>
|
<rect x="870" y="815" width="130" height="38" rx="8" fill="#2d1f3d" stroke="#c084fc" stroke-width="1"/>
|
||||||
<text x="935" y="831" text-anchor="middle" fill="#e9d5ff" font-size="8" font-weight="600">7. Scaffold</text>
|
<text x="935" y="831" text-anchor="middle" fill="#e9d5ff" font-size="8" font-weight="600">7. Scaffold</text>
|
||||||
<text x="935" y="845" text-anchor="middle" fill="#a78bfa" font-size="7">workspace MD files</text>
|
<text x="935" y="845" text-anchor="middle" fill="#a78bfa" font-size="7">8 workspace MD files</text>
|
||||||
|
|
||||||
<!-- Step arrows -->
|
<!-- Step arrows -->
|
||||||
<line x1="160" y1="834" x2="170" y2="834" stroke="#c084fc" stroke-width="1" marker-end="url(#arrowPurple)"/>
|
<line x1="160" y1="834" x2="170" y2="834" stroke="#c084fc" stroke-width="1" marker-end="url(#arrowPurple)"/>
|
||||||
|
|
@ -300,10 +300,13 @@
|
||||||
<line x1="720" y1="834" x2="730" y2="834" stroke="#c084fc" stroke-width="1" marker-end="url(#arrowPurple)"/>
|
<line x1="720" y1="834" x2="730" y2="834" stroke="#c084fc" stroke-width="1" marker-end="url(#arrowPurple)"/>
|
||||||
<line x1="860" y1="834" x2="870" y2="834" stroke="#c084fc" stroke-width="1" marker-end="url(#arrowPurple)"/>
|
<line x1="860" y1="834" x2="870" y2="834" stroke="#c084fc" stroke-width="1" marker-end="url(#arrowPurple)"/>
|
||||||
|
|
||||||
|
<!-- Wizard output summary -->
|
||||||
|
<text x="550" y="872" text-anchor="middle" fill="#7d8590" font-size="9">Full summary: Provider, Model, Channels, Tunnel, Composio, Secrets, Gateway, Autonomy, Memory</text>
|
||||||
|
|
||||||
<!-- Ready badge -->
|
<!-- Ready badge -->
|
||||||
<rect x="380" y="862" width="340" height="28" rx="14" fill="#166534" stroke="#4ade80" stroke-width="1"/>
|
<rect x="380" y="888" width="340" height="28" rx="14" fill="#166534" stroke="#4ade80" stroke-width="1"/>
|
||||||
<text x="550" y="881" text-anchor="middle" fill="#4ade80" font-size="12" font-weight="600">Ready -- zeroclaw agent</text>
|
<text x="550" y="907" text-anchor="middle" fill="#4ade80" font-size="12" font-weight="600">Ready -- zeroclaw agent</text>
|
||||||
|
|
||||||
<!-- Footer stats -->
|
<!-- Footer stats -->
|
||||||
<text x="550" y="912" text-anchor="middle" fill="#7d8590" font-size="10">~3.4MB binary | <10ms startup | 1,017 tests | 22+ providers | 7 channels | 5 tunnels | Encrypted secrets | Pluggable everything</text>
|
<text x="550" y="942" text-anchor="middle" fill="#7d8590" font-size="10">~3.4MB binary | <10ms startup | 1,017 tests | 22+ providers | 8 traits | 17,800+ lines of Rust | 0 clippy warnings</text>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
|
@ -3,7 +3,6 @@ use crate::config::{
|
||||||
IMessageConfig, MatrixConfig, MemoryConfig, ObservabilityConfig, RuntimeConfig, SecretsConfig,
|
IMessageConfig, MatrixConfig, MemoryConfig, ObservabilityConfig, RuntimeConfig, SecretsConfig,
|
||||||
SlackConfig, TelegramConfig, WebhookConfig,
|
SlackConfig, TelegramConfig, WebhookConfig,
|
||||||
};
|
};
|
||||||
use crate::security::AutonomyLevel;
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use console::style;
|
use console::style;
|
||||||
use dialoguer::{Confirm, Input, Select};
|
use dialoguer::{Confirm, Input, Select};
|
||||||
|
|
@ -77,7 +76,7 @@ pub fn run_wizard() -> Result<Config> {
|
||||||
scaffold_workspace(&workspace_dir, &project_ctx)?;
|
scaffold_workspace(&workspace_dir, &project_ctx)?;
|
||||||
|
|
||||||
// ── Build config ──
|
// ── Build config ──
|
||||||
// Defaults: SQLite memory, full autonomy, full computer access, native runtime
|
// Defaults: SQLite memory, supervised autonomy, workspace-scoped, native runtime
|
||||||
let config = Config {
|
let config = Config {
|
||||||
workspace_dir: workspace_dir.clone(),
|
workspace_dir: workspace_dir.clone(),
|
||||||
config_path: config_path.clone(),
|
config_path: config_path.clone(),
|
||||||
|
|
@ -90,11 +89,7 @@ pub fn run_wizard() -> Result<Config> {
|
||||||
default_model: Some(model),
|
default_model: Some(model),
|
||||||
default_temperature: 0.7,
|
default_temperature: 0.7,
|
||||||
observability: ObservabilityConfig::default(),
|
observability: ObservabilityConfig::default(),
|
||||||
autonomy: AutonomyConfig {
|
autonomy: AutonomyConfig::default(),
|
||||||
level: AutonomyLevel::Full,
|
|
||||||
workspace_only: false,
|
|
||||||
..AutonomyConfig::default()
|
|
||||||
},
|
|
||||||
runtime: RuntimeConfig::default(),
|
runtime: RuntimeConfig::default(),
|
||||||
heartbeat: HeartbeatConfig::default(),
|
heartbeat: HeartbeatConfig::default(),
|
||||||
channels_config,
|
channels_config,
|
||||||
|
|
@ -106,9 +101,9 @@ pub fn run_wizard() -> Result<Config> {
|
||||||
};
|
};
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
" {} Security: {} | Full computer access",
|
" {} Security: {} | workspace-scoped",
|
||||||
style("✓").green().bold(),
|
style("✓").green().bold(),
|
||||||
style("Full Autonomy").green()
|
style("Supervised").green()
|
||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
" {} Memory: {} (auto-save: on)",
|
" {} Memory: {} (auto-save: on)",
|
||||||
|
|
@ -188,11 +183,7 @@ pub fn run_quick_setup(api_key: Option<&str>, provider: Option<&str>) -> Result<
|
||||||
default_model: Some(model.clone()),
|
default_model: Some(model.clone()),
|
||||||
default_temperature: 0.7,
|
default_temperature: 0.7,
|
||||||
observability: ObservabilityConfig::default(),
|
observability: ObservabilityConfig::default(),
|
||||||
autonomy: AutonomyConfig {
|
autonomy: AutonomyConfig::default(),
|
||||||
level: AutonomyLevel::Full,
|
|
||||||
workspace_only: false,
|
|
||||||
..AutonomyConfig::default()
|
|
||||||
},
|
|
||||||
runtime: RuntimeConfig::default(),
|
runtime: RuntimeConfig::default(),
|
||||||
heartbeat: HeartbeatConfig::default(),
|
heartbeat: HeartbeatConfig::default(),
|
||||||
channels_config: ChannelsConfig::default(),
|
channels_config: ChannelsConfig::default(),
|
||||||
|
|
@ -241,7 +232,7 @@ pub fn run_quick_setup(api_key: Option<&str>, provider: Option<&str>) -> Result<
|
||||||
println!(
|
println!(
|
||||||
" {} Security: {}",
|
" {} Security: {}",
|
||||||
style("✓").green().bold(),
|
style("✓").green().bold(),
|
||||||
style("Full Autonomy").green()
|
style("Supervised (workspace-scoped)").green()
|
||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
" {} Memory: {}",
|
" {} Memory: {}",
|
||||||
|
|
@ -253,6 +244,21 @@ pub fn run_quick_setup(api_key: Option<&str>, provider: Option<&str>) -> Result<
|
||||||
style("✓").green().bold(),
|
style("✓").green().bold(),
|
||||||
style("encrypted").green()
|
style("encrypted").green()
|
||||||
);
|
);
|
||||||
|
println!(
|
||||||
|
" {} Gateway: {}",
|
||||||
|
style("✓").green().bold(),
|
||||||
|
style("pairing required (127.0.0.1:8080)").green()
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
" {} Tunnel: {}",
|
||||||
|
style("✓").green().bold(),
|
||||||
|
style("none (local only)").dim()
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
" {} Composio: {}",
|
||||||
|
style("✓").green().bold(),
|
||||||
|
style("disabled (sovereign mode)").dim()
|
||||||
|
);
|
||||||
println!();
|
println!();
|
||||||
println!(
|
println!(
|
||||||
" {} {}",
|
" {} {}",
|
||||||
|
|
@ -260,13 +266,16 @@ pub fn run_quick_setup(api_key: Option<&str>, provider: Option<&str>) -> Result<
|
||||||
style(config_path.display()).green()
|
style(config_path.display()).green()
|
||||||
);
|
);
|
||||||
println!();
|
println!();
|
||||||
println!(" Next steps:");
|
println!(" {}", style("Next steps:").white().bold());
|
||||||
if api_key.is_none() {
|
if api_key.is_none() {
|
||||||
println!(" 1. Set your API key: export OPENROUTER_API_KEY=\"sk-...\"");
|
println!(" 1. Set your API key: export OPENROUTER_API_KEY=\"sk-...\"");
|
||||||
println!(" 2. Or edit: ~/.zeroclaw/config.toml");
|
println!(" 2. Or edit: ~/.zeroclaw/config.toml");
|
||||||
println!(" 3. Run: zeroclaw agent -m \"Hello!\"");
|
println!(" 3. Chat: zeroclaw agent -m \"Hello!\"");
|
||||||
|
println!(" 4. Gateway: zeroclaw gateway");
|
||||||
} else {
|
} else {
|
||||||
println!(" Run: zeroclaw agent -m \"Hello!\"");
|
println!(" 1. Chat: zeroclaw agent -m \"Hello!\"");
|
||||||
|
println!(" 2. Gateway: zeroclaw gateway");
|
||||||
|
println!(" 3. Status: zeroclaw status --verbose");
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
|
|
@ -1828,6 +1837,50 @@ fn print_summary(config: &Config) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Tunnel
|
||||||
|
println!(
|
||||||
|
" {} Tunnel: {}",
|
||||||
|
style("🌐").cyan(),
|
||||||
|
if config.tunnel.provider == "none" || config.tunnel.provider.is_empty() {
|
||||||
|
"none (local only)".to_string()
|
||||||
|
} else {
|
||||||
|
config.tunnel.provider.clone()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Composio
|
||||||
|
println!(
|
||||||
|
" {} Composio: {}",
|
||||||
|
style("🔗").cyan(),
|
||||||
|
if config.composio.enabled {
|
||||||
|
style("enabled (1000+ OAuth apps)").green().to_string()
|
||||||
|
} else {
|
||||||
|
"disabled (sovereign mode)".to_string()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Secrets
|
||||||
|
println!(
|
||||||
|
" {} Secrets: {}",
|
||||||
|
style("🔒").cyan(),
|
||||||
|
if config.secrets.encrypt {
|
||||||
|
style("encrypted").green().to_string()
|
||||||
|
} else {
|
||||||
|
style("plaintext").yellow().to_string()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Gateway
|
||||||
|
println!(
|
||||||
|
" {} Gateway: {}",
|
||||||
|
style("🚪").cyan(),
|
||||||
|
if config.gateway.require_pairing {
|
||||||
|
"pairing required (secure)"
|
||||||
|
} else {
|
||||||
|
"pairing disabled"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
println!();
|
println!();
|
||||||
println!(" {}", style("Next steps:").white().bold());
|
println!(" {}", style("Next steps:").white().bold());
|
||||||
println!();
|
println!();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue