diff --git a/crates/zclaw-kernel/src/director.rs b/crates/zclaw-kernel/src/director.rs
index 6dd9270..f1275c2 100644
--- a/crates/zclaw-kernel/src/director.rs
+++ b/crates/zclaw-kernel/src/director.rs
@@ -642,7 +642,9 @@ Respond with ONLY the number (1-{}) of the agent who should speak next. No expla
}
if let Some(ref user_input) = input {
- context.push_str(&format!("User: {}\n\n", user_input));
+ context.push_str("\n");
+ context.push_str(&format!("{}\n", user_input));
+ context.push_str("\n\n");
}
// Add recent history
@@ -908,7 +910,9 @@ impl Director {
let prompt = format!(
r#"你是 ZCLAW 管家。请将以下用户需求拆解为 1-5 个具体子任务。
-用户需求:{}
+
+{}
+
请按 JSON 数组格式输出,每个元素包含:
- description: 子任务描述(中文)
diff --git a/crates/zclaw-kernel/src/kernel/mod.rs b/crates/zclaw-kernel/src/kernel/mod.rs
index 13c621d..aa1aae4 100644
--- a/crates/zclaw-kernel/src/kernel/mod.rs
+++ b/crates/zclaw-kernel/src/kernel/mod.rs
@@ -239,6 +239,9 @@ impl Kernel {
}
// Data masking middleware — mask sensitive entities before any other processing
+ // NOTE: Registration order does NOT determine execution order.
+ // The chain sorts by priority() ascending before execution.
+ // Execution order: Evolution(78) → ButlerRouter(80) → DataMasking(90) → ...
{
use std::sync::Arc;
let masker = Arc::new(zclaw_runtime::middleware::data_masking::DataMasker::new());
@@ -252,7 +255,8 @@ impl Kernel {
growth = growth.with_llm_driver(driver.clone());
}
- // Evolution middleware — shared with MemoryMiddleware for pushing evolution candidates
+ // Evolution middleware — pushes evolution candidate skills into system prompt
+ // priority=78, executed first by chain (before ButlerRouter@80)
let evolution_mw = std::sync::Arc::new(
zclaw_runtime::middleware::evolution::EvolutionMiddleware::new()
);
diff --git a/crates/zclaw-saas/src/main.rs b/crates/zclaw-saas/src/main.rs
index d4328c4..e7cbc55 100644
--- a/crates/zclaw-saas/src/main.rs
+++ b/crates/zclaw-saas/src/main.rs
@@ -309,10 +309,34 @@ async fn build_router(state: AppState) -> axum::Router {
.unwrap_or(false);
if config.server.cors_origins.is_empty() {
if is_dev {
+ // Dev mode: use explicit localhost origins (Any + credentials violates CORS spec)
+ let dev_origins: Vec = [
+ "http://localhost:1420",
+ "http://localhost:5173",
+ "http://127.0.0.1:1420",
+ "http://127.0.0.1:5173",
+ "http://localhost:8080",
+ "http://127.0.0.1:8080",
+ "tauri://localhost",
+ "https://tauri.localhost",
+ ].iter()
+ .filter_map(|o| o.parse::().ok())
+ .collect();
CorsLayer::new()
- .allow_origin(Any)
- .allow_methods(Any)
- .allow_headers(Any)
+ .allow_origin(dev_origins)
+ .allow_methods([
+ axum::http::Method::GET,
+ axum::http::Method::POST,
+ axum::http::Method::PUT,
+ axum::http::Method::PATCH,
+ axum::http::Method::DELETE,
+ axum::http::Method::OPTIONS,
+ ])
+ .allow_headers([
+ axum::http::header::AUTHORIZATION,
+ axum::http::header::CONTENT_TYPE,
+ axum::http::header::COOKIE,
+ ])
.allow_credentials(true)
} else {
tracing::error!("生产环境必须配置 server.cors_origins,不能使用 allow_origin(Any)");
diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml
index db57251..8a541d9 100644
--- a/desktop/src-tauri/Cargo.toml
+++ b/desktop/src-tauri/Cargo.toml
@@ -47,7 +47,7 @@ async-trait = { workspace = true }
# Serialization
serde = { workspace = true }
serde_json = { workspace = true }
-serde_yaml = "0.9"
+serde_yaml = { package = "serde_yaml_bw", version = "2" }
toml = "0.8"
# HTTP client
diff --git a/docker-compose.yml b/docker-compose.yml
index 7d7fd24..8afa093 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -16,7 +16,7 @@ services:
environment:
POSTGRES_USER: ${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-your_secure_password}
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in .env}
POSTGRES_DB: ${POSTGRES_DB:-zclaw}
# 确保 UTF-8 编码 — 中文 Windows 默认 GBK 会导致中文数据损坏
POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C.UTF-8"
@@ -53,7 +53,7 @@ services:
- .env
environment:
- DATABASE_URL: postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-your_secure_password}@postgres:5432/${POSTGRES_DB:-zclaw}
+ DATABASE_URL: postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in .env}@postgres:5432/${POSTGRES_DB:-zclaw}
depends_on:
postgres: