chore: update release notes and bump version to v0.0.18

This commit is contained in:
OpenClaw Manager
2026-03-07 00:33:43 +01:00
parent 032e90d632
commit dbd4df04f8
16 changed files with 175 additions and 99 deletions
+4 -4
View File
@@ -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
BIN
View File
Binary file not shown.
+23
View File
@@ -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 <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
+21
View File
@@ -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
+1 -1
View File
@@ -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",
+5
View File
@@ -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
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
View File
+1 -1
View File
@@ -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"
+68 -56
View File
@@ -303,18 +303,18 @@ pub async fn get_official_providers() -> Result<Vec<OfficialProvider>, 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<Vec<OfficialProvider>, 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<Vec<OfficialProvider>, 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<Vec<OfficialProvider>, 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<Vec<OfficialProvider>, 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<Vec<OfficialProvider>, 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<Vec<OfficialProvider>, 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,
+13 -10
View File
@@ -55,24 +55,27 @@ pub async fn check_environment() -> Result<EnvironmentStatus, String> {
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<EnvironmentStatus, String> {
// 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 {
+1 -1
View File
@@ -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",
+21 -26
View File
@@ -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<PageType>('dashboard');
const [isReady, setIsReady] = useState<boolean | null>(null);
const [envStatus, setEnvStatus] = useState<EnvironmentStatus | null>(null);
const [serviceStatus, setServiceStatus] = useState<ServiceStatus | null>(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<EnvironmentStatus>('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 (
<div className="flex h-screen bg-dark-900 items-center justify-center">
<div className="fixed inset-0 bg-gradient-radial pointer-events-none" />
<div className="relative z-10 text-center">
<div className="inline-flex items-center justify-center w-16 h-16 rounded-xl bg-gradient-to-br from-brand-500 to-purple-600 mb-4 animate-pulse">
<span className="text-3xl">🦞</span>
</div>
<p className="text-dark-400">Starting...</p>
const LoadingSpinner = () => (
<div className="flex h-full items-center justify-center">
<div className="relative z-10 text-center">
<div className="inline-flex items-center justify-center w-16 h-16 rounded-xl bg-gradient-to-br from-brand-500 to-purple-600 mb-4 animate-pulse shadow-lg shadow-purple-900/20">
<span className="text-3xl">🦞</span>
</div>
<p className="text-dark-400 font-medium">Loading component...</p>
</div>
);
}
</div>
);
// Main interface
return (
@@ -557,9 +550,11 @@ function App() {
<Header currentPage={currentPage} />
{/* Page content */}
<main className="flex-1 overflow-hidden p-6">
<main className="flex-1 overflow-hidden p-6 relative">
<ErrorBoundary>
{renderPage()}
<React.Suspense fallback={<LoadingSpinner />}>
{renderPage()}
</React.Suspense>
</ErrorBoundary>
</main>
</div>
+17
View File
@@ -0,0 +1,17 @@
{
"tools": {
"profile": "messaging",
"pdf": {
"provider": "anthropic",
"maxPages": 10
}
},
"memorySearch": {
"provider": "ollama"
},
"sessions_spawn": {
"inlineFileAttachments": {
"enabled": true
}
}
}