mirror of
https://github.com/MrFadiAi/openclaw-manager.git
synced 2026-08-14 00:57:59 +00:00
chore: update release notes and bump version to v0.0.18
This commit is contained in:
@@ -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
|
||||
|
||||
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -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
@@ -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",
|
||||
|
||||
@@ -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
|
||||
Binary file not shown.
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,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
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user