The tauri-plugin-mcp was registered in Rust but the frontend never called
setupPluginListeners(), causing all DOM-related MCP operations (execute_js,
query_page, type_text) to timeout. This fix enables proper dev debugging
via tauri-mcp tools.
Register 15 structured tools via navigator.modelContext (Chrome 146+)
for direct state queries without DOM scraping. Reduces token consumption
~67% vs DevTools MCP snapshot-based debugging. Dev mode only.
Tools: get_zclaw_state, check_connection, send_message, cancel_stream,
get_streaming_state, list_conversations, get_current_conversation,
switch_conversation, get_token_usage, get_offline_queue,
get_saas_account, get_available_models, get_current_agent,
list_agents, get_console_errors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add IF NOT EXISTS to accounts_template_assignment ALTER COLUMN
- Add IF NOT EXISTS to webhooks CREATE INDEX statements
- Add created_at/updated_at columns + ON CONFLICT DO NOTHING to industry templates
- Bump SCHEMA_VERSION 13→14 to force migration re-run on existing DB
- 16 down SQL files in migrations/down/ for each incremental migration
- db::run_down_migrations() executes rollback files in reverse order
- migrate_down CLI task: task=migrate_down timestamp=20260402
- Initial schema and seed data excluded (would be destructive)
- Unify ConnectionState: kernel-types.ts now canonical source
with 'handshaking', gateway-types.ts re-exports
- PromptTemplateInfo source/status → union literals
- PromptVariable.type → union literal
- CreateRoleRequest id/permissions → optional
- PropertyPanel: replace 13 as any with typed accessor pattern
- chatStore: window cast via as unknown as Record
- index.ts: add _storesInitialized guard to prevent triple initialization
- offlineStore.ts: add isRetrying mutex for retryAllMessages concurrency
- PropertyPanel.tsx: replace 13x (data as any) with typed d accessor
- chatStore.ts: replace window as any with Record<string, unknown>
- kernel-*.ts: replace prototype as any with Record<string, unknown>
- gateway-heartbeat.ts: delete dead code (9 as any, zero imports)
- DEAD-05: 10 dead saas-client methods removed (PARTIALLY_FIXED)
- V11-P2-05: 9 stale @reserved annotations corrected to @connected
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
M1-01: Move Gemini API key from URL query param to x-goog-api-key header,
preventing key leakage in logs/proxy/telemetry (matches Anthropic/OpenAI pattern)
M1-03/M1-04: Replace Mutex .unwrap() with .unwrap_or_else(|e| e.into_inner())
in MemoryMiddleware and LoopGuardMiddleware — recovers from poison
instead of panicking async runtime
M2-08: Add input validation to agent_create — reject empty names,
out-of-range temperature (0-2), and zero max_tokens
M11-06: Replace Date.now() message ID with crypto.randomUUID()
to prevent collisions in classroom chat
The ChatArea.tsx toolSteps/subtasks rendering uses helper functions to avoid TypeScript strict mode && chain producing unknown type in JSX children. Add SubscriptionPanel component for subscription status display in SaaS billing section.
- cache: insert-then-retain pattern avoids empty-window race during refresh
- relay: manage_task_status flag for proper failover state transitions
- relay: retry_task re-resolves model groups instead of blind provider reuse
- relay: filter empty-member groups from available models list
- relay: quota cache stale entry cleanup (TTL 5x expiry)
- error: from_sqlx_unique helper for 409 vs 500 distinction
- model_config: unique constraint handling, duplicate member check
- model_config: failover_strategy whitelist, model_id vs group name conflict check
- model_config: group-scoped member removal with group_id validation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sprint 2: 产品体验打磨 + 行业模板
- Create PipelineResultPreview component with tab-based output switching
- Connect workflow/hand messages to PresentationContainer in ChatArea
- Add auto-trigger first Hand after onboarding (industry-specific queries)
- Seed 3 industry agent templates (education, healthcare, design-shantou)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Model Groups provide logical model names that map to multiple physical
models across providers, with automatic failover when one provider's
key pool is exhausted.
Backend:
- New model_groups + model_group_members tables with FK constraints
- Full CRUD API (7 endpoints) with admin-only write permissions
- Cache layer: DashMap-backed CachedModelGroup with load_from_db
- Relay integration: ModelResolution enum for Direct/Group routing
- Cross-provider failover: sort_candidates_by_quota + OnceLock cache
- Relay failure path: record failure usage + relay_dequeue (fixes
queue counter leak that caused connection pool exhaustion)
- add_group_member: validate model_id exists before insert
Frontend:
- saas-relay-client: accept getModel() callback for dynamic model selection
- connectionStore: prefer conversationStore.currentModel over first available
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Kernel orchestration bridge: execute_orchestration, auto_compose_skills,
validate_orchestration methods on Kernel struct
- True parallel execution: replace sequential for-loop with tokio::JoinSet
for concurrent node execution within parallel groups
- Tauri commands: orchestration_execute (auto-compose or pre-defined graph),
orchestration_validate (dry-run validation)
- Full type conversions: OrchestrationRequest/Response with camelCase serde
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- SemanticSkillRouter: add RuntimeLlmIntent trait and with_llm_fallback() builder
- route(): call LLM fallback when TF-IDF/embedding confidence < threshold
- CJK tokenization: generate bigrams for Chinese/Japanese/Korean text
- Fix: previous tokenizer treated entire CJK string as one huge token
- SemanticSkillRouter: add RuntimeLlmIntent trait and with_llm_fallback() builder
- route(): call LLM fallback when TF-IDF/embedding confidence < threshold
- CJK tokenization: generate bigrams for Chinese/Japanese/Korean text
- Fix: previous tokenizer treated entire CJK string as one huge token
- LlmSkillFallback: concrete RuntimeLlmIntent using LlmDriver
- Asks LLM to pick best skill from ambiguous candidates list
- Parses structured JSON response from LLM output
- Includes tests for LLM fallback and CJK tokenization
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- MCPServices.tsx now calls real Tauri commands (start/stop/list)
instead of only toggling config flags
- Show running service count, discovered tools per service
- Expand/collapse tool list for each running MCP service
- Extended QuickConfig mcpServices type with command/args/env/cwd
- Config change persists enabled state, MCP start/stop happens live
- get_messages_paginated(session_id, limit, offset) for batch loading
- count_messages(session_id) for total count queries
- Enables frontend to load messages progressively instead of all-at-once
- Schema: migrations now execute ALTER TABLE ADD COLUMN for state/message_count
- MemoryStore: add update_agent_runtime() and list_agents_with_runtime()
- Registry: add register_with_runtime() to accept persisted state/message_count
- Kernel boot: restore agents with their persisted state (not always Running)
- Kernel shutdown: persist all agent states/message_counts before terminating
Agents that were suspended stay suspended after restart. Message counts
survive restarts instead of resetting to 0.
- Add effective_importance() with exponential time decay (30-day half-life)
and access count boost for fair scoring of stale vs fresh memories
- Add SqliteStorage::decay_memories() for periodic maintenance:
reduces stored importance per interval, archives (deletes) below threshold
- Update find() scoring to use time-decayed importance in sort
- Add DecayResult type and effective_importance re-export in lib.rs
- Remove dead frontend active-learning.ts (370 lines, zero imports)
- saas test harness: align WorkerDispatcher::new and AppState::new
signatures with SpawnLimiter addition and init_db(&DatabaseConfig)
- growth sqlite: add CJK fallback (LIKE-based) when FTS5 unicode61
tokenizer fails on Chinese queries (unicode61 doesn't index CJK)
Full E2E test suite for agent chat functionality including:
- Message send/receive flow
- Streaming response verification
- Model switching behavior
- Error handling scenarios
- Multi-turn conversation context
Includes test report documenting coverage and known gaps.
S6 MCP Protocol:
- Fix McpTransport::initialize() — store actual server capabilities instead
of discarding them and storing empty ServerCapabilities::default()
- Add send_notification() method to McpTransport for JSON-RPC notifications
- Send notifications/initialized after MCP handshake (spec requirement)
- Add McpToolAdapter: bridges MCP server tools into the tool execution path
- Add McpServiceManager: lifecycle management for MCP server connections
- Add 4 Tauri commands: mcp_start_service, mcp_stop_service,
mcp_list_services, mcp_call_tool
- Register zclaw-protocols dependency in desktop Cargo.toml
New files:
- crates/zclaw-protocols/src/mcp_tool_adapter.rs (153 lines)
- desktop/src-tauri/src/kernel_commands/mcp.rs (145 lines)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>