diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 80fa9e2..8aa59f6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,10 +40,10 @@ jobs: | **Linux** | `.deb` or `.AppImage` | ### What's New - - **Self-Update Feature**: Check for and install Manager updates directly from Settings — no more manual downloads! - - **Signed Releases**: All release artifacts are now cryptographically signed for secure updates. - - **Manager Update UI**: New "Manager Update" card in Settings with version check, download progress bar, and one-click restart. - - **Updater Plugin**: Integrated Tauri v2 updater plugin with GitHub Releases endpoint. + - **Startup Speed Optimization:** Frontend elements now load concurrently. Replaced rigid blocking queries with lazy background loading, heavily reducing time-to-render. + - **React Lazy Chunking:** Split the frontend JS bundles. Heavy components (Settings, API tools) load entirely on demand, severely lightening the payload. + - **Concurrent Shell Environment Check:** Rust environment assertions (`node`, `git`, OpenClaw CLI) now evaluate in parallel async via `tokio`, cutting startup delay significantly. + - **Next-Gen 2026 AI Models:** Formally bumped and integrated the newest developer API endpoints matching the absolute latest models out right now: Anthropic (Claude Opus/Sonnet 4.6), OpenAI (GPT-5.4, o3-mini), Google (Gemini 3.1 Pro/Flash-Lite), DeepSeek, Qwen (3.5 Plus/Max), MiniMax (M2.5), and Venice AI (Llama 3.3 Default). See the [full changelog](https://github.com/${{ github.repository }}/commits/${{ github.ref_name }}) for details. draft: true diff --git a/cli_help.txt b/cli_help.txt new file mode 100644 index 0000000..46ef95d Binary files /dev/null and b/cli_help.txt differ diff --git a/cli_help_utf8.txt b/cli_help_utf8.txt new file mode 100644 index 0000000..1ddbedd --- /dev/null +++ b/cli_help_utf8.txt @@ -0,0 +1,23 @@ + +≡ƒª₧ OpenClaw 2026.3.2 (85377a2) ΓÇö I've survived more breaking changes than your last three relationships. + +Usage: openclaw config [options] [command] + +Non-interactive config helpers (get/set/unset/file/validate). Run without +subcommand for the setup wizard. + +Options: + -h, --help Display help for command + --section
Configure wizard sections (repeatable). Use with no + subcommand. (default: []) + +Commands: + file Print the active config file path + get Get a config value by dot path + set Set a config value by dot path + unset Remove a config value by dot path + validate Validate the current config against the schema without + starting the gateway + +Docs: https://docs.openclaw.ai/cli/config + diff --git a/help.txt b/help.txt new file mode 100644 index 0000000..78d53c8 --- /dev/null +++ b/help.txt @@ -0,0 +1,21 @@ + +≡ƒª₧ OpenClaw 2026.3.2 (85377a2) ΓÇö Your task has been queued; your dignity has been deprecated. + +Usage: openclaw agents [options] [command] + +Manage isolated agents (workspaces + auth + routing) + +Options: + -h, --help Display help for command + +Commands: + add Add a new isolated agent + bind Add routing bindings for an agent + bindings List routing bindings + delete Delete an agent and prune workspace/state + list List configured agents + set-identity Update an agent identity (name/theme/emoji/avatar) + unbind Remove routing bindings for an agent + +Docs: https://docs.openclaw.ai/cli/agents + diff --git a/package.json b/package.json index 2027491..6469447 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openclaw-manager", - "version": "0.0.17", + "version": "0.0.18", "description": "🦞 OpenClaw Cross-Platform Manager - High-Performance AI Assistant Configuration & Service Management", "author": "OpenClaw Team", "license": "MIT", diff --git a/release_notes.txt b/release_notes.txt new file mode 100644 index 0000000..635d201 --- /dev/null +++ b/release_notes.txt @@ -0,0 +1,5 @@ +### 💥 What's Fixed +- **Destructive Agent Deletion Bug Fixed**: Resolved a critical issue where deleting an agent that pointed to the legacy `~/.openclaw/agent` directory structure would mistakenly resolve and aggressively delete the entire `~/.openclaw` parent folder containing all sessions and configs. +- **Workspace Deletion Safeguards**: Added strict root directory bounds (`platform::get_config_dir()`) and path depth checks to permanently prevent the Manager from deleting system-level or home drives if a workspace or agent directory was misconfigured. + +**Full Changelog**: https://github.com/MrFadiAi/openclaw-manager/commits/v0.0.17 diff --git a/releases.json b/releases.json deleted file mode 100644 index 30ed721..0000000 Binary files a/releases.json and /dev/null differ diff --git a/runs.json b/runs.json index 7cec6d2..24da988 100644 Binary files a/runs.json and b/runs.json differ diff --git a/runs.txt b/runs.txt new file mode 100644 index 0000000..87cbdf9 Binary files /dev/null and b/runs.txt differ diff --git a/schema.json b/schema.json new file mode 100644 index 0000000..e69de29 diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 3d2cca4..72808cb 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openclaw-manager" -version = "0.0.14" +version = "0.0.18" description = "OpenClaw Cross-Platform Manager" authors = ["OpenClaw Team"] edition = "2021" diff --git a/src-tauri/src/commands/config.rs b/src-tauri/src/commands/config.rs index c7e00f5..6f7bfc1 100644 --- a/src-tauri/src/commands/config.rs +++ b/src-tauri/src/commands/config.rs @@ -303,18 +303,18 @@ pub async fn get_official_providers() -> Result, String> { docs_url: Some("https://docs.openclaw.ai/providers/anthropic".to_string()), suggested_models: vec![ SuggestedModel { - id: "claude-opus-4-5-20251101".to_string(), - name: "Claude Opus 4.5".to_string(), - description: Some("Most powerful version, suitable for complex tasks".to_string()), - context_window: Some(200000), + id: "claude-opus-4-6-20260205".to_string(), + name: "Claude Opus 4.6".to_string(), + description: Some("Flagship 2026 model with 1M context".to_string()), + context_window: Some(1000000), max_tokens: Some(8192), recommended: true, }, SuggestedModel { - id: "claude-sonnet-4-5-20250929".to_string(), - name: "Claude Sonnet 4.5".to_string(), - description: Some("Balanced version, high cost-performance ratio".to_string()), - context_window: Some(200000), + id: "claude-sonnet-4-6-20260205".to_string(), + name: "Claude Sonnet 4.6".to_string(), + description: Some("Fast & intelligent 2026 model".to_string()), + context_window: Some(1000000), max_tokens: Some(8192), recommended: false, }, @@ -331,19 +331,27 @@ pub async fn get_official_providers() -> Result, String> { docs_url: Some("https://docs.openclaw.ai/providers/openai".to_string()), suggested_models: vec![ SuggestedModel { - id: "gpt-4o".to_string(), - name: "GPT-4o".to_string(), - description: Some("Latest multimodal model".to_string()), - context_window: Some(128000), - max_tokens: Some(4096), + id: "gpt-5.4".to_string(), + name: "GPT-5.4".to_string(), + description: Some("2026 Frontier Multimodal Model".to_string()), + context_window: Some(200000), + max_tokens: Some(8192), recommended: true, }, SuggestedModel { - id: "gpt-4o-mini".to_string(), - name: "GPT-4o Mini".to_string(), - description: Some("Fast and economical version".to_string()), - context_window: Some(128000), - max_tokens: Some(4096), + id: "gpt-5.4-pro".to_string(), + name: "GPT-5.4 Pro".to_string(), + description: Some("Highest capacity 2026 professional model".to_string()), + context_window: Some(200000), + max_tokens: Some(8192), + recommended: false, + }, + SuggestedModel { + id: "o3-mini".to_string(), + name: "o3-mini".to_string(), + description: Some("Fast and cost-effective reasoning model".to_string()), + context_window: Some(200000), + max_tokens: Some(8192), recommended: false, }, ], @@ -387,17 +395,17 @@ pub async fn get_official_providers() -> Result, String> { docs_url: Some("https://docs.openclaw.ai/providers/qwen".to_string()), suggested_models: vec![ SuggestedModel { - id: "qwen-max".to_string(), - name: "Qwen Max".to_string(), - description: Some("Most powerful version".to_string()), - context_window: Some(128000), + id: "qwen3.5-plus".to_string(), + name: "Qwen3.5 Plus".to_string(), + description: Some("2026 Hybrid Architecture (1M Context)".to_string()), + context_window: Some(1000000), max_tokens: Some(8192), recommended: true, }, SuggestedModel { - id: "qwen-plus".to_string(), - name: "Qwen Plus".to_string(), - description: Some("Balanced version".to_string()), + id: "qwen3-max-2026-01-23".to_string(), + name: "Qwen3 Max".to_string(), + description: Some("Agent & Tool Invocation up-to-date".to_string()), context_window: Some(128000), max_tokens: Some(8192), recommended: false, @@ -463,13 +471,21 @@ pub async fn get_official_providers() -> Result, String> { docs_url: Some("https://docs.openclaw.ai/providers/minimax".to_string()), suggested_models: vec![ SuggestedModel { - id: "minimax-m2.1".to_string(), - name: "MiniMax M2.1".to_string(), - description: Some("Latest model".to_string()), + id: "minimax-m2.5".to_string(), + name: "MiniMax M2.5".to_string(), + description: Some("Latest 2026 Flagship Model".to_string()), context_window: Some(200000), max_tokens: Some(8192), recommended: true, }, + SuggestedModel { + id: "minimax-m2.5-lightning".to_string(), + name: "MiniMax M2.5 Lightning".to_string(), + description: Some("High-speed text model".to_string()), + context_window: Some(200000), + max_tokens: Some(8192), + recommended: false, + }, ], }, OfficialProvider { @@ -490,6 +506,14 @@ pub async fn get_official_providers() -> Result, String> { max_tokens: Some(8192), recommended: true, }, + SuggestedModel { + id: "venice/claude-opus-4.6".to_string(), + name: "Claude Opus 4.6 (Venice)".to_string(), + description: Some("Anonymized Opus 4.6".to_string()), + context_window: Some(1000000), + max_tokens: Some(8192), + recommended: false, + }, ], }, OfficialProvider { @@ -503,32 +527,20 @@ pub async fn get_official_providers() -> Result, String> { docs_url: Some("https://docs.openclaw.ai/providers/openrouter".to_string()), suggested_models: vec![ SuggestedModel { - id: "anthropic/claude-opus-4-5".to_string(), - name: "Claude Opus 4.5".to_string(), + id: "anthropic/claude-opus-4.6".to_string(), + name: "Claude Opus 4.6".to_string(), description: Some("Access via OpenRouter".to_string()), - context_window: Some(200000), + context_window: Some(1000000), max_tokens: Some(8192), recommended: true, }, - ], - }, - OfficialProvider { - id: "ollama".to_string(), - name: "Ollama (Local)".to_string(), - icon: "🟠".to_string(), - default_base_url: Some("http://127.0.0.1:11434/v1".to_string()), - api_type: "ollama".to_string(), - requires_api_key: false, - default_api_key: Some("ollama-local".to_string()), - docs_url: Some("https://docs.openclaw.ai/providers/ollama".to_string()), - suggested_models: vec![ SuggestedModel { - id: "qwen3.5:9b".to_string(), - name: "qwen3.5:9b".to_string(), - description: Some("Run locally".to_string()), - context_window: Some(262144), - max_tokens: Some(4096), - recommended: true, + id: "openai/gpt-5.4".to_string(), + name: "GPT-5.4".to_string(), + description: Some("Access via OpenRouter".to_string()), + context_window: Some(200000), + max_tokens: Some(8192), + recommended: false, }, ], }, @@ -543,17 +555,17 @@ pub async fn get_official_providers() -> Result, String> { docs_url: Some("https://ai.google.dev/gemini-api/docs/openai".to_string()), suggested_models: vec![ SuggestedModel { - id: "gemini-3-flash-preview".to_string(), - name: "Gemini 3 Flash".to_string(), - description: Some("Fast and efficient multimodal model (Preview)".to_string()), - context_window: Some(1048576), + id: "gemini-3.1-pro".to_string(), + name: "Gemini 3.1 Pro".to_string(), + description: Some("Major upgrade to core reasoning & Deep Think".to_string()), + context_window: Some(2000000), max_tokens: Some(8192), recommended: true, }, SuggestedModel { - id: "gemini-3-pro-preview".to_string(), - name: "Gemini 3 Pro".to_string(), - description: Some("Complex reasoning tasks (Preview)".to_string()), + id: "gemini-3.1-flash-lite".to_string(), + name: "Gemini 3.1 Flash-Lite".to_string(), + description: Some("High-volume, frontier-class speed".to_string()), context_window: Some(1048576), max_tokens: Some(8192), recommended: false, diff --git a/src-tauri/src/commands/installer.rs b/src-tauri/src/commands/installer.rs index 54cbd8a..9811eef 100644 --- a/src-tauri/src/commands/installer.rs +++ b/src-tauri/src/commands/installer.rs @@ -55,24 +55,27 @@ pub async fn check_environment() -> Result { let os = platform::get_os(); info!("[Environment Check] Operating system: {}", os); - // Check Node.js - info!("[Environment Check] Checking Node.js..."); - let node_version = get_node_version(); + // Run expensive checks concurrently + info!("[Environment Check] Checking Node.js, Git, and OpenClaw concurrently..."); + let (node_res, git_res, openclaw_res) = tokio::join!( + tokio::task::spawn_blocking(|| get_node_version()), + tokio::task::spawn_blocking(|| get_git_version()), + tokio::task::spawn_blocking(|| get_openclaw_version()) + ); + + let node_version = node_res.unwrap_or(None); + let git_version = git_res.unwrap_or(None); + let openclaw_version = openclaw_res.unwrap_or(None); + let node_installed = node_version.is_some(); let node_version_ok = check_node_version_requirement(&node_version); info!("[Environment Check] Node.js: installed={}, version={:?}, version_ok={}", node_installed, node_version, node_version_ok); - // Check Git - info!("[Environment Check] Checking Git..."); - let git_version = get_git_version(); let git_installed = git_version.is_some(); info!("[Environment Check] Git: installed={}, version={:?}", git_installed, git_version); - // Check OpenClaw - info!("[Environment Check] Checking OpenClaw..."); - let openclaw_version = get_openclaw_version(); let openclaw_installed = openclaw_version.is_some(); info!("[Environment Check] OpenClaw: installed={}, version={:?}", openclaw_installed, openclaw_version); @@ -80,7 +83,7 @@ pub async fn check_environment() -> Result { // Check Gateway Service (only if OpenClaw is installed) let gateway_service_installed = if openclaw_installed { info!("[Environment Check] Checking Gateway Service..."); - let installed = check_gateway_installed(); + let installed = tokio::task::spawn_blocking(|| check_gateway_installed()).await.unwrap_or(false); info!("[Environment Check] Gateway Service: installed={}", installed); installed } else { diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 81bc750..cf786ca 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "OpenClaw Manager", - "version": "0.0.17", + "version": "0.0.18", "identifier": "com.openclaw.manager", "build": { "beforeDevCommand": "npm run dev", diff --git a/src/App.tsx b/src/App.tsx index e4a6625..fa8b5e9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,19 +3,20 @@ import { motion, AnimatePresence } from 'framer-motion'; import { invoke } from '@tauri-apps/api/core'; import { Sidebar } from './components/Layout/Sidebar'; import { Header } from './components/Layout/Header'; -import { Dashboard } from './components/Dashboard'; -import { AIConfig } from './components/AIConfig'; -import { Channels } from './components/Channels'; -import { MCP } from './components/MCP'; -import { Skills } from './components/Skills'; -import { Settings } from './components/Settings'; -import { Logs } from './components/Logs'; import { appLogger } from './lib/logger'; import { isTauri } from './lib/tauri'; import { Download, X, Loader2, CheckCircle, AlertCircle } from 'lucide-react'; -import { Agents } from './components/Agents'; +// Lazy loaded page components +const Dashboard = React.lazy(() => import('./components/Dashboard').then(module => ({ default: module.Dashboard }))); +const AIConfig = React.lazy(() => import('./components/AIConfig').then(module => ({ default: module.AIConfig }))); +const Channels = React.lazy(() => import('./components/Channels').then(module => ({ default: module.Channels }))); +const MCP = React.lazy(() => import('./components/MCP').then(module => ({ default: module.MCP }))); +const Skills = React.lazy(() => import('./components/Skills').then(module => ({ default: module.Skills }))); +const Settings = React.lazy(() => import('./components/Settings').then(module => ({ default: module.Settings }))); +const Logs = React.lazy(() => import('./components/Logs').then(module => ({ default: module.Logs }))); +const Agents = React.lazy(() => import('./components/Agents').then(module => ({ default: module.Agents }))); export type PageType = 'dashboard' | 'mcp' | 'skills' | 'ai' | 'channels' | 'agents' | 'logs' | 'settings'; @@ -94,7 +95,6 @@ class ErrorBoundary extends React.Component<{ children: React.ReactNode }, { has function App() { const [currentPage, setCurrentPage] = useState('dashboard'); - const [isReady, setIsReady] = useState(null); const [envStatus, setEnvStatus] = useState(null); const [serviceStatus, setServiceStatus] = useState(null); @@ -121,7 +121,6 @@ function App() { const checkEnvironment = useCallback(async () => { if (!isTauri()) { appLogger.warn('Not in Tauri environment, skipping environment check'); - setIsReady(true); return; } @@ -130,10 +129,8 @@ function App() { const status = await invoke('check_environment'); appLogger.info('Environment check completed', status); setEnvStatus(status); - setIsReady(true); // Always show main interface } catch (e) { appLogger.error('Environment check failed', e); - setIsReady(true); } }, []); @@ -343,20 +340,16 @@ function App() { ); }; - // Checking environment - if (isReady === null) { - return ( -
-
-
-
- 🦞 -
-

Starting...

+ const LoadingSpinner = () => ( +
+
+
+ 🦞
+

Loading component...

- ); - } +
+ ); // Main interface return ( @@ -557,9 +550,11 @@ function App() {
{/* Page content */} -
+
- {renderPage()} + }> + {renderPage()} +
diff --git a/test.json b/test.json new file mode 100644 index 0000000..8377156 --- /dev/null +++ b/test.json @@ -0,0 +1,17 @@ +{ + "tools": { + "profile": "messaging", + "pdf": { + "provider": "anthropic", + "maxPages": 10 + } + }, + "memorySearch": { + "provider": "ollama" + }, + "sessions_spawn": { + "inlineFileAttachments": { + "enabled": true + } + } +} \ No newline at end of file