From 129134d926660543c4d21c850f05e7978a5b2bb9 Mon Sep 17 00:00:00 2001 From: weishao Date: Thu, 27 Aug 2026 20:30:41 +0800 Subject: [PATCH 1/2] refactor(desktop): remove unused Tauri commands Remove 11 orphaned Desktop commands together with their registrations, remote-workspace policies, implementation-only capability entries, dead snapshot DTOs/helpers, and runtime contract references. Regenerate the Tauri command map for the resulting 640-command surface. --- .../technical/tauri-command-map.json | 162 +--------------- src/apps/desktop/src/api/commands.rs | 28 --- src/apps/desktop/src/api/config_api.rs | 14 -- src/apps/desktop/src/api/mod.rs | 1 - .../src/api/remote_workspace_policy.rs | 46 ----- src/apps/desktop/src/api/snapshot_service.rs | 162 +--------------- src/apps/desktop/src/api/storage_commands.rs | 177 ------------------ src/apps/desktop/src/lib.rs | 12 -- src/apps/desktop/src/runtime/mod.rs | 2 - .../interactive-capabilities/catalog.json | 20 +- 10 files changed, 7 insertions(+), 617 deletions(-) delete mode 100644 src/apps/desktop/src/api/storage_commands.rs diff --git a/docs/interactive-capabilities/technical/tauri-command-map.json b/docs/interactive-capabilities/technical/tauri-command-map.json index 55299214ee..0a6533e330 100644 --- a/docs/interactive-capabilities/technical/tauri-command-map.json +++ b/docs/interactive-capabilities/technical/tauri-command-map.json @@ -2,12 +2,12 @@ "schemaVersion": 2, "generatedFrom": "src/shared/interactive-capabilities/catalog.json", "catalogDigest": "b915ffcb329182de3e033d8e48186a1dbd5c683d975484567d9dfe9b9c595c13", - "commandCount": 653, + "commandCount": 642, "coverage": { - "commandCount": 653, + "commandCount": 642, "documentedCommandCount": 615, - "implementationCommandCount": 38, - "implementationDigest": "965d441b20c0092bc25c1dd48db3e31f72a977479fe9d1ff7c788d8e17d7395b" + "implementationCommandCount": 27, + "implementationDigest": "4d3b2e8145a6a97b622fdb78cf1c25275881328eb7ccbc3c92ae95bf798cb190" }, "commands": [ { @@ -1280,34 +1280,6 @@ "signature": "fn cleanup_invalid_workspaces( state: State<'_, AppState>, app: tauri::AppHandle, startup_trace: State<'_, DesktopStartupTrace>, ) -> Result", "remoteWorkspacePolicy": "LegacyUnaudited" }, - { - "id": "cleanup_storage", - "moduleId": "storage_commands", - "capabilityId": "feature.files-editor", - "capabilityIds": [ - "feature.files-editor" - ], - "documentedItemIds": [], - "visibility": "implementation", - "rustPath": "cleanup_storage", - "sourceFile": "src/apps/desktop/src/api/storage_commands.rs", - "signature": "fn cleanup_storage(state: State<'_, AppState>) -> Result", - "remoteWorkspacePolicy": "LegacyUnaudited" - }, - { - "id": "cleanup_storage_with_policy", - "moduleId": "storage_commands", - "capabilityId": "feature.files-editor", - "capabilityIds": [ - "feature.files-editor" - ], - "documentedItemIds": [], - "visibility": "implementation", - "rustPath": "cleanup_storage_with_policy", - "sourceFile": "src/apps/desktop/src/api/storage_commands.rs", - "signature": "fn cleanup_storage_with_policy( state: State<'_, AppState>, policy: CleanupPolicy, ) -> Result", - "remoteWorkspacePolicy": "LegacyUnaudited" - }, { "id": "clear_mcp_remote_auth", "moduleId": "mcp", @@ -3497,20 +3469,6 @@ "signature": "fn get_project_permission_rules( state: State<'_, AppState>, request: PermissionProjectRequest, ) -> Result", "remoteWorkspacePolicy": "RemoteRouted" }, - { - "id": "get_project_storage_paths", - "moduleId": "storage_commands", - "capabilityId": "feature.files-editor", - "capabilityIds": [ - "feature.files-editor" - ], - "documentedItemIds": [], - "visibility": "implementation", - "rustPath": "get_project_storage_paths", - "sourceFile": "src/apps/desktop/src/api/storage_commands.rs", - "signature": "fn get_project_storage_paths( state: State<'_, AppState>, workspace_path: String, ) -> Result", - "remoteWorkspacePolicy": "LegacyUnaudited" - }, { "id": "get_readonly_tools_info", "moduleId": "tool", @@ -3799,34 +3757,6 @@ "signature": "fn get_statistics( state: State<'_, AppState>, ) -> Result", "remoteWorkspacePolicy": "LegacyUnaudited" }, - { - "id": "get_storage_paths", - "moduleId": "storage_commands", - "capabilityId": "feature.files-editor", - "capabilityIds": [ - "feature.files-editor" - ], - "documentedItemIds": [], - "visibility": "implementation", - "rustPath": "get_storage_paths", - "sourceFile": "src/apps/desktop/src/api/storage_commands.rs", - "signature": "fn get_storage_paths(state: State<'_, AppState>) -> Result", - "remoteWorkspacePolicy": "LegacyUnaudited" - }, - { - "id": "get_storage_statistics", - "moduleId": "storage_commands", - "capabilityId": "feature.files-editor", - "capabilityIds": [ - "feature.files-editor" - ], - "documentedItemIds": [], - "visibility": "implementation", - "rustPath": "get_storage_statistics", - "sourceFile": "src/apps/desktop/src/api/storage_commands.rs", - "signature": "fn get_storage_statistics(state: State<'_, AppState>) -> Result", - "remoteWorkspacePolicy": "LegacyUnaudited" - }, { "id": "get_subagent_detail", "moduleId": "subagent", @@ -4673,34 +4603,6 @@ "signature": "fn initialize_mcp_servers_non_destructive( state: State<'_, AppState>, startup_trace: State<'_, DesktopStartupTrace>, ) -> Result<(), String>", "remoteWorkspacePolicy": "LegacyUnaudited" }, - { - "id": "initialize_project_storage", - "moduleId": "storage_commands", - "capabilityId": "feature.files-editor", - "capabilityIds": [ - "feature.files-editor" - ], - "documentedItemIds": [], - "visibility": "implementation", - "rustPath": "initialize_project_storage", - "sourceFile": "src/apps/desktop/src/api/storage_commands.rs", - "signature": "fn initialize_project_storage( state: State<'_, AppState>, workspace_path: String, ) -> Result<(), String>", - "remoteWorkspacePolicy": "LegacyUnaudited" - }, - { - "id": "initialize_snapshot", - "moduleId": "snapshot_service", - "capabilityId": "feature.files-editor", - "capabilityIds": [ - "feature.files-editor" - ], - "documentedItemIds": [], - "visibility": "implementation", - "rustPath": "initialize_snapshot", - "sourceFile": "src/apps/desktop/src/api/snapshot_service.rs", - "signature": "fn initialize_snapshot( app_handle: AppHandle, runtime: State<'_, DesktopRuntimeContext>, request: SnapshotInitRequest, ) -> Result", - "remoteWorkspacePolicy": "LegacyUnaudited" - }, { "id": "initialize_tray_after_startup", "moduleId": "system", @@ -6680,20 +6582,6 @@ "signature": "fn read_mcp_resource( state: State<'_, AppState>, request: ReadMCPResourceRequest, ) -> Result", "remoteWorkspacePolicy": "LegacyUnaudited" }, - { - "id": "record_file_change", - "moduleId": "snapshot_service", - "capabilityId": "feature.files-editor", - "capabilityIds": [ - "feature.files-editor" - ], - "documentedItemIds": [], - "visibility": "implementation", - "rustPath": "record_file_change", - "sourceFile": "src/apps/desktop/src/api/snapshot_service.rs", - "signature": "fn record_file_change( app_handle: AppHandle, runtime: State<'_, DesktopRuntimeContext>, request: RecordFileChangeRequest, ) -> Result", - "remoteWorkspacePolicy": "LegacyUnaudited" - }, { "id": "recover_interrupted_dialog_turn", "moduleId": "agentic", @@ -6933,20 +6821,6 @@ "signature": "fn reload_custom_agents( state: State<'_, AppState>, request: ReloadCustomAgentsRequest, ) -> Result<(), String>", "remoteWorkspacePolicy": "LegacyUnaudited" }, - { - "id": "reload_global_config", - "moduleId": "commands", - "capabilityId": "feature.projects", - "capabilityIds": [ - "feature.projects" - ], - "documentedItemIds": [], - "visibility": "implementation", - "rustPath": "reload_global_config", - "sourceFile": "src/apps/desktop/src/api/commands.rs", - "signature": "fn reload_global_config() -> Result", - "remoteWorkspacePolicy": "LegacyUnaudited" - }, { "id": "reload_session_context", "moduleId": "agentic", @@ -9624,20 +9498,6 @@ "signature": "fn submit_user_answers( runtime: State<'_, DesktopRuntimeContext>, tool_id: String, answers: serde_json::Value, ) -> Result<(), String>", "remoteWorkspacePolicy": "LegacyUnaudited" }, - { - "id": "subscribe_config_updates", - "moduleId": "commands", - "capabilityId": "feature.projects", - "capabilityIds": [ - "feature.projects" - ], - "documentedItemIds": [], - "visibility": "implementation", - "rustPath": "subscribe_config_updates", - "sourceFile": "src/apps/desktop/src/api/commands.rs", - "signature": "fn subscribe_config_updates() -> Result<(), String>", - "remoteWorkspacePolicy": "LegacyUnaudited" - }, { "id": "subscribe_permission_requests", "moduleId": "agentic", @@ -9654,20 +9514,6 @@ "signature": "fn subscribe_permission_requests( app: AppHandle, runtime: State<'_, DesktopRuntimeContext>, ) -> Result<(), String>", "remoteWorkspacePolicy": "WorkspaceAgnostic" }, - { - "id": "sync_config_to_global", - "moduleId": "config", - "capabilityId": "setting.application.general", - "capabilityIds": [ - "setting.application.general" - ], - "documentedItemIds": [], - "visibility": "implementation", - "rustPath": "sync_config_to_global", - "sourceFile": "src/apps/desktop/src/api/config_api.rs", - "signature": "fn sync_config_to_global(_state: State<'_, AppState>) -> Result", - "remoteWorkspacePolicy": "LegacyUnaudited" - }, { "id": "terminal_ack", "moduleId": "terminal", diff --git a/src/apps/desktop/src/api/commands.rs b/src/apps/desktop/src/api/commands.rs index 087daab1d1..c1e2137c07 100644 --- a/src/apps/desktop/src/api/commands.rs +++ b/src/apps/desktop/src/api/commands.rs @@ -4974,39 +4974,11 @@ pub async fn cancel_search( Ok(()) } -#[tauri::command] -pub async fn reload_global_config() -> Result { - match bitfun_core::service::config::reload_global_config().await { - Ok(_) => { - info!("Global config reloaded"); - Ok("Configuration reloaded successfully".to_string()) - } - Err(e) => { - error!("Failed to reload global config: {}", e); - Err(format!("Failed to reload configuration: {}", e)) - } - } -} - #[tauri::command] pub async fn get_global_config_status() -> Result { Ok(bitfun_core::service::config::GlobalConfigManager::is_initialized()) } -#[tauri::command] -pub async fn subscribe_config_updates() -> Result<(), String> { - if let Some(mut receiver) = bitfun_core::service::config::subscribe_config_updates() { - tokio::spawn(async move { - while let Ok(event) = receiver.recv().await { - debug!("Config update event: {:?}", event); - } - }); - Ok(()) - } else { - Err("Config update subscription not available".to_string()) - } -} - #[tauri::command] pub async fn get_model_configs( state: State<'_, AppState>, diff --git a/src/apps/desktop/src/api/config_api.rs b/src/apps/desktop/src/api/config_api.rs index 30bc125042..b12c2f21cb 100644 --- a/src/apps/desktop/src/api/config_api.rs +++ b/src/apps/desktop/src/api/config_api.rs @@ -348,20 +348,6 @@ pub async fn reload_config(state: State<'_, AppState>) -> Result } } -#[tauri::command] -pub async fn sync_config_to_global(_state: State<'_, AppState>) -> Result { - match bitfun_core::service::config::reload_global_config().await { - Ok(_) => { - info!("Config synced to global service"); - Ok("Configuration synced to global service".to_string()) - } - Err(e) => { - error!("Failed to sync config to global service: {}", e); - Err(format!("Failed to sync config to global service: {}", e)) - } - } -} - #[tauri::command] pub async fn get_global_config_health() -> Result { Ok(bitfun_core::service::config::GlobalConfigManager::is_initialized()) diff --git a/src/apps/desktop/src/api/mod.rs b/src/apps/desktop/src/api/mod.rs index 85c9986458..b0a3e7343f 100644 --- a/src/apps/desktop/src/api/mod.rs +++ b/src/apps/desktop/src/api/mod.rs @@ -49,7 +49,6 @@ pub mod skill_api; pub mod snapshot_service; pub mod speech_api; pub mod ssh_api; -pub mod storage_commands; pub mod subagent_api; pub mod system_api; pub mod terminal_api; diff --git a/src/apps/desktop/src/api/remote_workspace_policy.rs b/src/apps/desktop/src/api/remote_workspace_policy.rs index 32398ec5a2..dc18ce8432 100644 --- a/src/apps/desktop/src/api/remote_workspace_policy.rs +++ b/src/apps/desktop/src/api/remote_workspace_policy.rs @@ -303,11 +303,6 @@ pub const REMOTE_WORKSPACE_COMMAND_POLICIES: &[(&str, RemoteWorkspacePolicy)] = "cleanup_invalid_workspaces", RemoteWorkspacePolicy::LegacyUnaudited, ), - ("cleanup_storage", RemoteWorkspacePolicy::LegacyUnaudited), - ( - "cleanup_storage_with_policy", - RemoteWorkspacePolicy::LegacyUnaudited, - ), ( "clear_mcp_remote_auth", RemoteWorkspacePolicy::LegacyUnaudited, @@ -703,10 +698,6 @@ pub const REMOTE_WORKSPACE_COMMAND_POLICIES: &[(&str, RemoteWorkspacePolicy)] = "get_pending_announcements", RemoteWorkspacePolicy::WorkspaceAgnostic, ), - ( - "get_project_storage_paths", - RemoteWorkspacePolicy::LegacyUnaudited, - ), ( "get_readonly_tools_info", RemoteWorkspacePolicy::LegacyUnaudited, @@ -761,11 +752,6 @@ pub const REMOTE_WORKSPACE_COMMAND_POLICIES: &[(&str, RemoteWorkspacePolicy)] = RemoteWorkspacePolicy::WorkspaceAgnostic, ), ("get_statistics", RemoteWorkspacePolicy::LegacyUnaudited), - ("get_storage_paths", RemoteWorkspacePolicy::LegacyUnaudited), - ( - "get_storage_statistics", - RemoteWorkspacePolicy::LegacyUnaudited, - ), ( "get_subagent_detail", RemoteWorkspacePolicy::LegacyUnaudited, @@ -875,14 +861,6 @@ pub const REMOTE_WORKSPACE_COMMAND_POLICIES: &[(&str, RemoteWorkspacePolicy)] = "initialize_mcp_servers_non_destructive", RemoteWorkspacePolicy::LegacyUnaudited, ), - ( - "initialize_project_storage", - RemoteWorkspacePolicy::LegacyUnaudited, - ), - ( - "initialize_snapshot", - RemoteWorkspacePolicy::LegacyUnaudited, - ), ( "initialize_tray_after_startup", RemoteWorkspacePolicy::LocalOnly, @@ -1260,7 +1238,6 @@ pub const REMOTE_WORKSPACE_COMMAND_POLICIES: &[(&str, RemoteWorkspacePolicy)] = ), ("read_file_content", RemoteWorkspacePolicy::LegacyUnaudited), ("read_mcp_resource", RemoteWorkspacePolicy::LegacyUnaudited), - ("record_file_change", RemoteWorkspacePolicy::LegacyUnaudited), ( "refresh_model_client", RemoteWorkspacePolicy::LegacyUnaudited, @@ -1304,10 +1281,6 @@ pub const REMOTE_WORKSPACE_COMMAND_POLICIES: &[(&str, RemoteWorkspacePolicy)] = "reload_custom_agents", RemoteWorkspacePolicy::LegacyUnaudited, ), - ( - "reload_global_config", - RemoteWorkspacePolicy::LegacyUnaudited, - ), ( "reload_session_context", RemoteWorkspacePolicy::RemoteRouted, @@ -1848,14 +1821,6 @@ pub const REMOTE_WORKSPACE_COMMAND_POLICIES: &[(&str, RemoteWorkspacePolicy)] = "submit_user_answers", RemoteWorkspacePolicy::LegacyUnaudited, ), - ( - "subscribe_config_updates", - RemoteWorkspacePolicy::LegacyUnaudited, - ), - ( - "sync_config_to_global", - RemoteWorkspacePolicy::LegacyUnaudited, - ), ("terminal_ack", RemoteWorkspacePolicy::RemoteRouted), ("terminal_close", RemoteWorkspacePolicy::RemoteRouted), ("terminal_create", RemoteWorkspacePolicy::RemoteRouted), @@ -2200,8 +2165,6 @@ mod tests { "check_git_isolation", "check_path_exists", "cleanup_invalid_workspaces", - "cleanup_storage", - "cleanup_storage_with_policy", "clear_mcp_remote_auth", "clear_session_thread_goal", "close_workspace", @@ -2283,7 +2246,6 @@ mod tests { "get_opened_workspaces", "get_operation_diff", "get_operation_summary", - "get_project_storage_paths", "get_readonly_tools_info", "get_recent_workspaces", "get_runtime_capabilities", @@ -2299,8 +2261,6 @@ mod tests { "get_snapshot_sessions", "get_snapshot_system_stats", "get_statistics", - "get_storage_paths", - "get_storage_statistics", "get_subagent_detail", "get_tool_info", "get_turn_files", @@ -2313,8 +2273,6 @@ mod tests { "initialize_ai", "initialize_mcp_servers", "initialize_mcp_servers_non_destructive", - "initialize_project_storage", - "initialize_snapshot", "initialize_workspace_startup_state", "install_acp_client_cli", "list_agent_companion_pets", @@ -2379,13 +2337,11 @@ mod tests { "read_background_command_output", "read_file_content", "read_mcp_resource", - "record_file_change", "refresh_model_client", "reject_file", "reject_operation", "reload_config", "reload_custom_agents", - "reload_global_config", "reload_subagents", "remove_recent_workspace", "rename_file", @@ -2442,8 +2398,6 @@ mod tests { "submit_acp_permission_response", "submit_mcp_interaction_response", "submit_user_answers", - "subscribe_config_updates", - "sync_config_to_global", "terminal_get", "terminal_get_shells", "terminal_list", diff --git a/src/apps/desktop/src/api/snapshot_service.rs b/src/apps/desktop/src/api/snapshot_service.rs index 681dc4caea..dfda97eda3 100644 --- a/src/apps/desktop/src/api/snapshot_service.rs +++ b/src/apps/desktop/src/api/snapshot_service.rs @@ -7,7 +7,7 @@ use bitfun_core::service::remote_ssh::workspace_state::is_remote_path; use bitfun_core::service::snapshot::{ ensure_snapshot_manager_for_workspace, get_snapshot_manager_for_workspace, initialize_snapshot_manager_for_workspace, open_snapshot_manager_for_view, FileChangeEntry, - OperationType, SnapshotConfig, SnapshotManager, + OperationType, SnapshotManager, }; use bitfun_runtime_ports::{AgentSessionWorkspaceLocation, SessionStoragePathRequest}; use log::{info, warn}; @@ -53,33 +53,6 @@ async fn ensure_local_runtime_ownership( .map_err(|error| error.to_string()) } -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SnapshotInitRequest { - #[serde(alias = "workspacePath")] - pub workspace_path: String, - pub config: Option, - #[serde(flatten)] - pub remote_scope: SnapshotRemoteScope, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct RecordFileChangeRequest { - #[serde(alias = "sessionId")] - pub session_id: String, - #[serde(alias = "turnIndex")] - pub turn_index: usize, - #[serde(alias = "filePath")] - pub file_path: String, - #[serde(alias = "operationType")] - pub operation_type: String, // "Create", "Modify", "Delete", "Rename" - #[serde(alias = "toolName")] - pub tool_name: String, - #[serde(alias = "workspacePath")] - pub workspace_path: String, - #[serde(flatten)] - pub remote_scope: SnapshotRemoteScope, -} - #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RollbackSessionRequest { #[serde(alias = "sessionId")] @@ -240,48 +213,6 @@ pub struct SnapshotWorkspaceRequest { pub remote_scope: SnapshotRemoteScope, } -#[tauri::command] -pub async fn initialize_snapshot( - app_handle: AppHandle, - runtime: State<'_, DesktopRuntimeContext>, - request: SnapshotInitRequest, -) -> Result { - // Remote workspaces don't support snapshot system - if request.remote_scope.declares_remote() || is_remote_path(&request.workspace_path).await { - return Ok(serde_json::json!({ - "success": true, - "message": "Snapshot system skipped for remote workspace" - })); - } - ensure_local_runtime_ownership(runtime.inner(), &request.workspace_path).await?; - - let workspace_dir = PathBuf::from(&request.workspace_path); - - if !workspace_dir.exists() { - return Err(format!( - "Workspace directory does not exist: {}", - request.workspace_path - )); - } - - initialize_snapshot_manager_for_workspace(workspace_dir, request.config) - .await - .map_err(|e| format!("Failed to initialize snapshot system: {}", e))?; - - let _ = app_handle.emit( - "snapshot_initialized", - serde_json::json!({ - "workspace_path": request.workspace_path, - "timestamp": chrono::Utc::now().to_rfc3339() - }), - ); - - Ok(serde_json::json!({ - "success": true, - "message": "Snapshot system initialized" - })) -} - async fn resolve_workspace_dir(workspace_path: &str) -> Result { if workspace_path.trim().is_empty() { return Err("workspacePath is required".to_string()); @@ -479,88 +410,6 @@ async fn begin_snapshot_history_mutation( }) } -async fn begin_snapshot_record_mutation( - runtime: &DesktopRuntimeContext, - workspace_path: &str, - session_id: &str, -) -> Result { - let compatibility = runtime.session_application().compatibility(); - let storage_path = compatibility - .resolve_persisted_session_storage_path(SessionStoragePathRequest { - workspace_path: PathBuf::from(workspace_path), - remote_connection_id: None, - remote_ssh_host: None, - }) - .await - .map_err(|error| { - format!("Failed to resolve session storage before snapshot recording: {error}") - })?; - let mutation = compatibility - .begin_persisted_session_mutation(&storage_path, session_id) - .await - .map_err(|error| format!("Failed to lock snapshot recording: {error}"))?; - compatibility - .ensure_snapshot_record_allowed(&mutation) - .await - .map_err(|error| format!("Failed to admit snapshot recording: {error}"))?; - Ok(mutation) -} - -#[tauri::command] -pub async fn record_file_change( - app_handle: AppHandle, - runtime: State<'_, DesktopRuntimeContext>, - request: RecordFileChangeRequest, -) -> Result { - ensure_local_snapshot_mutation_path(&request.workspace_path, &request.remote_scope).await?; - ensure_local_runtime_ownership(runtime.inner(), &request.workspace_path).await?; - let manager = - ensure_snapshot_manager_ready_for(&request.workspace_path, "record_file_change").await?; - - let operation_type = match request.operation_type.as_str() { - "Create" => OperationType::Create, - "Modify" => OperationType::Modify, - "Delete" => OperationType::Delete, - "Rename" => OperationType::Rename, - _ => { - return Err(format!( - "Unknown operation type: {}", - request.operation_type - )); - } - }; - - let _record_mutation = begin_snapshot_record_mutation( - runtime.inner(), - &request.workspace_path, - &request.session_id, - ) - .await?; - - let snapshot_id = manager - .record_file_change( - &request.session_id, - request.turn_index, - PathBuf::from(&request.file_path), - operation_type, - request.tool_name.clone(), - ) - .await - .map_err(|e| format!("Failed to record file change: {}", e))?; - - let _ = app_handle.emit( - "file_change_recorded", - serde_json::json!({ - "session_id": request.session_id, - "turn_index": request.turn_index, - "file_path": request.file_path, - "snapshot_id": snapshot_id, - }), - ); - - Ok(snapshot_id) -} - #[tauri::command] pub async fn rollback_session( app_handle: AppHandle, @@ -1484,15 +1333,6 @@ mod tests { !targeted_rollback.contains("begin_snapshot_history_mutation"), "targeted rollback must not reacquire the Session mutation owned by the Agent Session transaction" ); - - let record = source - .split_once("pub async fn record_file_change") - .expect("record_file_change remains present") - .1 - .split_once("pub async fn rollback_session") - .expect("rollback_session remains present") - .0; - assert!(record.contains("begin_snapshot_record_mutation")); } #[tokio::test] diff --git a/src/apps/desktop/src/api/storage_commands.rs b/src/apps/desktop/src/api/storage_commands.rs deleted file mode 100644 index cfbdf77fa3..0000000000 --- a/src/apps/desktop/src/api/storage_commands.rs +++ /dev/null @@ -1,177 +0,0 @@ -//! Storage Management API - -use crate::api::AppState; -use bitfun_core::infrastructure::storage::{CleanupPolicy, CleanupResult, CleanupService}; -use serde::{Deserialize, Serialize}; -use std::path::PathBuf; -use tauri::State; - -#[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct StoragePathsInfo { - pub user_config_dir: PathBuf, - pub user_data_dir: PathBuf, - pub cache_root: PathBuf, - pub logs_dir: PathBuf, - pub temp_dir: PathBuf, -} - -#[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct StorageStats { - pub total_size_mb: f64, - pub config_size_mb: f64, - pub cache_size_mb: f64, - pub logs_size_mb: f64, - pub temp_size_mb: f64, -} - -#[tauri::command] -pub async fn get_storage_paths(state: State<'_, AppState>) -> Result { - let workspace_service = &state.workspace_service; - let path_manager = workspace_service.path_manager(); - - Ok(StoragePathsInfo { - user_config_dir: path_manager.user_config_dir(), - user_data_dir: path_manager.user_data_dir(), - cache_root: path_manager.cache_root(), - logs_dir: path_manager.logs_dir(), - temp_dir: path_manager.temp_dir(), - }) -} - -#[tauri::command] -pub async fn get_project_storage_paths( - state: State<'_, AppState>, - workspace_path: String, -) -> Result { - let workspace_service = &state.workspace_service; - let path_manager = workspace_service.path_manager(); - - let workspace_path = PathBuf::from(workspace_path); - - Ok(ProjectStoragePathsInfo { - project_root: path_manager.project_root(&workspace_path), - runtime_root: path_manager.project_runtime_root(&workspace_path), - agents_dir: path_manager.project_agents_dir(&workspace_path), - sessions_dir: path_manager.project_sessions_dir(&workspace_path), - plans_dir: path_manager.project_plans_dir(&workspace_path), - }) -} - -#[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ProjectStoragePathsInfo { - pub project_root: PathBuf, - pub runtime_root: PathBuf, - pub agents_dir: PathBuf, - pub sessions_dir: PathBuf, - pub plans_dir: PathBuf, -} - -#[tauri::command] -pub async fn cleanup_storage(state: State<'_, AppState>) -> Result { - let workspace_service = &state.workspace_service; - let path_manager = workspace_service.path_manager(); - - let policy = CleanupPolicy::default(); - let cleanup_service = CleanupService::new((**path_manager).clone(), policy); - - cleanup_service - .cleanup_all() - .await - .map_err(|e| format!("Cleanup failed: {}", e)) -} - -#[tauri::command] -pub async fn cleanup_storage_with_policy( - state: State<'_, AppState>, - policy: CleanupPolicy, -) -> Result { - let workspace_service = &state.workspace_service; - let path_manager = workspace_service.path_manager(); - - let cleanup_service = CleanupService::new((**path_manager).clone(), policy); - - cleanup_service - .cleanup_all() - .await - .map_err(|e| format!("Cleanup failed: {}", e)) -} - -#[tauri::command] -pub async fn get_storage_statistics(state: State<'_, AppState>) -> Result { - let workspace_service = &state.workspace_service; - let path_manager = workspace_service.path_manager(); - - let config_size = calculate_dir_size(&path_manager.user_config_dir()).await?; - let cache_size = calculate_dir_size(&path_manager.cache_root()).await?; - let logs_size = calculate_dir_size(&path_manager.logs_dir()).await?; - let temp_size = calculate_dir_size(&path_manager.temp_dir()).await?; - - let total_size = config_size + cache_size + logs_size + temp_size; - - Ok(StorageStats { - total_size_mb: bytes_to_mb(total_size), - config_size_mb: bytes_to_mb(config_size), - cache_size_mb: bytes_to_mb(cache_size), - logs_size_mb: bytes_to_mb(logs_size), - temp_size_mb: bytes_to_mb(temp_size), - }) -} - -#[tauri::command] -pub async fn initialize_project_storage( - state: State<'_, AppState>, - workspace_path: String, -) -> Result<(), String> { - let workspace_service = &state.workspace_service; - let runtime_service = workspace_service.runtime_service(); - - let workspace_path = PathBuf::from(workspace_path); - - runtime_service - .ensure_local_workspace_runtime(&workspace_path) - .await - .map(|_| ()) - .map_err(|e| format!("Failed to initialize project runtime: {}", e)) -} - -fn calculate_dir_size( - dir: &std::path::Path, -) -> std::pin::Pin> + Send + '_>> { - Box::pin(async move { - let mut total = 0u64; - - if !dir.exists() { - return Ok(0); - } - - let mut read_dir = tokio::fs::read_dir(dir) - .await - .map_err(|e| format!("Failed to read directory: {}", e))?; - - while let Some(entry) = read_dir - .next_entry() - .await - .map_err(|e| format!("Failed to read directory entry: {}", e))? - { - let metadata = entry - .metadata() - .await - .map_err(|e| format!("Failed to get metadata: {}", e))?; - - if metadata.is_dir() { - total += calculate_dir_size(&entry.path()).await?; - } else { - total += metadata.len(); - } - } - - Ok(total) - }) -} - -fn bytes_to_mb(bytes: u64) -> f64 { - bytes as f64 / 1_048_576.0 -} diff --git a/src/apps/desktop/src/lib.rs b/src/apps/desktop/src/lib.rs index da8082f1cc..8be1547450 100644 --- a/src/apps/desktop/src/lib.rs +++ b/src/apps/desktop/src/lib.rs @@ -87,7 +87,6 @@ use api::session_api::*; use api::skill_api::*; use api::snapshot_service::*; use api::speech_api::*; -use api::storage_commands::*; use api::subagent_api::*; use api::system_api::*; use api::tool_api::*; @@ -1570,7 +1569,6 @@ pub async fn run() { import_config, validate_config, reload_config, - sync_config_to_global, get_global_config_health, get_runtime_logging_info, export_diagnostics_bundle, @@ -1672,8 +1670,6 @@ pub async fn run() { compute_diff, apply_patch, save_merged_diff_content, - initialize_snapshot, - record_file_change, rollback_session, rollback_session_to_turn, accept_session, @@ -1696,12 +1692,6 @@ pub async fn run() { get_file_change_history, get_all_modified_files, get_baseline_snapshot_diff, - get_storage_paths, - get_project_storage_paths, - cleanup_storage, - cleanup_storage_with_policy, - get_storage_statistics, - initialize_project_storage, // Session persistence API list_persisted_sessions, search_session_content, @@ -1761,9 +1751,7 @@ pub async fn run() { get_acp_session_commands, set_acp_session_model, set_acp_session_config_option, - reload_global_config, get_global_config_status, - subscribe_config_updates, get_model_configs, get_ai_model_catalog, project_ai_model_reasoning_catalog, diff --git a/src/apps/desktop/src/runtime/mod.rs b/src/apps/desktop/src/runtime/mod.rs index edc899f395..d83296fb3c 100644 --- a/src/apps/desktop/src/runtime/mod.rs +++ b/src/apps/desktop/src/runtime/mod.rs @@ -308,8 +308,6 @@ mod tests { } for mutation in [ - "pub async fn initialize_snapshot", - "pub async fn record_file_change", "pub async fn rollback_session", "pub async fn rollback_session_to_turn", "pub async fn accept_session", diff --git a/src/shared/interactive-capabilities/catalog.json b/src/shared/interactive-capabilities/catalog.json index 5ead54c5b8..912bd19ba8 100644 --- a/src/shared/interactive-capabilities/catalog.json +++ b/src/shared/interactive-capabilities/catalog.json @@ -186,35 +186,22 @@ "check_command_exists", "check_commands_exist" ], - "storageMaintenance": [ - "cleanup_storage", - "cleanup_storage_with_policy", - "get_project_storage_paths", - "get_storage_paths", - "get_storage_statistics" - ], "runtimeLifecycle": [ "ensure_assistant_bootstrap", "ensure_coordinator_session", "initialize_ai", "initialize_mcp_servers", "initialize_mcp_servers_non_destructive", - "initialize_project_storage", - "initialize_snapshot", "initialize_tray_after_startup", "initialize_workspace_startup_state", - "reload_config", - "reload_global_config", - "subscribe_config_updates" + "reload_config" ], "genericConfigPrimitives": [ "get_config", "get_configs", - "set_config", - "sync_config_to_global" + "set_config" ], "persistencePrimitives": [ - "record_file_change", "save_session_metadata", "save_session_turn", "touch_session_activity" @@ -8960,9 +8947,6 @@ "browser": { "capabilityId": "feature.browser" }, - "storage_commands": { - "capabilityId": "feature.files-editor" - }, "announcement": { "capabilityId": "setting.application.general" }, From 39299b43e0079d88c7f0e853a12225a265a2c357 Mon Sep 17 00:00:00 2001 From: weishao Date: Thu, 27 Aug 2026 20:31:57 +0800 Subject: [PATCH 2/2] docs(capabilities): refresh interaction inventory Regenerate the interaction inventory after rebasing onto the latest target branch. The merged source now audits 640 Tauri commands and 4,393 interaction candidates across 364 UI source files. --- docs/interactive-capabilities/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/interactive-capabilities/README.md b/docs/interactive-capabilities/README.md index 5bcfc9a2f7..9f92a6129e 100644 --- a/docs/interactive-capabilities/README.md +++ b/docs/interactive-capabilities/README.md @@ -27,9 +27,9 @@ BitFun Playbook currently contains **22 features**, **16 settings pages**, and * - Generated per-item interaction audit: `docs/interactive-capabilities/technical/product-control-open-audit.json` - Generated low-level audit map: `docs/interactive-capabilities/technical/tauri-command-map.json` -说明书、网站、搜索和 Agent 只看“功能 + 设置 + 子能力”。每项子能力都必须引用已注册 Tauri Command 或可解析的源码标记;这些证据不会进入公开目录。当前 **653** 个 Tauri 命令只用于实现覆盖审计。产品 UI 交互源码会在生成和检查时扫描并校验,但不会保存成随普通 UI 改动频繁变化的版本化快照。 +说明书、网站、搜索和 Agent 只看“功能 + 设置 + 子能力”。每项子能力都必须引用已注册 Tauri Command 或可解析的源码标记;这些证据不会进入公开目录。当前 **642** 个 Tauri 命令只用于实现覆盖审计。产品 UI 交互源码会在生成和检查时扫描并校验,但不会保存成随普通 UI 改动频繁变化的版本化快照。 -Docs, website, search, and agents see only features, settings, and documented sub-capabilities. Every sub-capability must reference a registered Tauri command or a resolvable source marker; evidence is stripped from public projections. The **653** Tauri commands remain implementation-audit evidence only. Product UI interaction sources are scanned and validated during generation and checks, but are not stored as a versioned snapshot that churns with ordinary UI changes. +Docs, website, search, and agents see only features, settings, and documented sub-capabilities. Every sub-capability must reference a registered Tauri command or a resolvable source marker; evidence is stripped from public projections. The **642** Tauri commands remain implementation-audit evidence only. Product UI interaction sources are scanned and validated during generation and checks, but are not stored as a versioned snapshot that churns with ordinary UI changes. ## 控制边界 / Control boundary