Skip to content

Commit 75fdf60

Browse files
feat(Mountain): implement Cocoon gRPC file system operations and command registry
This commit implements the remaining stubbed operations in the CocoonService gRPC server, replacing Status::unimplemented returns with working implementations: - **File System Operations**: read_file, write_file, stat, readdir now delegate to tokio::fs with proper URI-to-path parsing. delete_file, rename_file, copy_file, create_directory implemented with atomic parent directory creation. - **find_files**: Implements glob pattern matching using globset crate, walking workspace folders from ApplicationState. - **git_exec**: Spawns native git process with provided args, captures stdout/stderr, returns exit code and output lines. - **open_terminal**: Wires to MountainEnvironment::CreateTerminal using TerminalProvider. - **Command Registration**: Wires RegisterCommand/UnregisterCommand to CommandExecutor instead of stub logging. - **Language Feature Providers**: All 15+ provider registration methods now call RegisterProvider to store metadata in ApplicationState.Extension.ProviderRegistration. - **Workspace Folders**: Initialize handler now parses workspace_folders from init payload and stores in ApplicationState.Workspace. - **Extension Queries**: get_extension and get_all_extensions now query ApplicationState via ExtensionManagementService. This removes the TODO placeholders for these operations and enables the full gRPC service contract between Mountain and Cocoon.
1 parent 499dbf4 commit 75fdf60

2 files changed

Lines changed: 541 additions & 287 deletions

File tree

Source/IPC/WindServiceHandlers.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,11 @@ type ConfigurationOverridesDTO = ConfigurationOverridesDTOModule::ConfigurationO
183183
type ConfigurationTarget = ConfigurationTargetModule::ConfigurationTarget;
184184

185185
use CommonLibrary::{
186+
Command::CommandExecutor::CommandExecutor,
186187
Configuration::ConfigurationProvider::ConfigurationProvider,
187188
Environment::Requires::Requires,
188189
Error::CommonError::CommonError,
190+
ExtensionManagement::ExtensionManagementService::ExtensionManagementService,
189191
FileSystem::{FileSystemReader::FileSystemReader, FileSystemWriter::FileSystemWriter},
190192
Storage::StorageProvider::StorageProvider,
191193
};
@@ -234,6 +236,15 @@ pub async fn mountain_ipc_invoke(app_handle:AppHandle, command:String, args:Vec<
234236
// Workbench commands
235237
"workbench:getConfiguration" => handle_workbench_configuration(runtime.inner().clone(), args).await,
236238

239+
// Command registry commands
240+
"commands:execute" => handle_commands_execute(runtime.inner().clone(), args).await,
241+
"commands:getAll" => handle_commands_get_all(runtime.inner().clone()).await,
242+
243+
// Extension host commands
244+
"extensions:getAll" => handle_extensions_get_all(runtime.inner().clone()).await,
245+
"extensions:get" => handle_extensions_get(runtime.inner().clone(), args).await,
246+
"extensions:isActive" => handle_extensions_is_active(runtime.inner().clone(), args).await,
247+
237248
// IPC status commands
238249
"mountain_get_status" => {
239250
let status = json!({
@@ -818,3 +829,86 @@ pub fn register_wind_ipc_handlers(app_handle:&tauri::AppHandle) -> Result<(), St
818829

819830
Ok(())
820831
}
832+
833+
// ============================================================================
834+
// Command Registry Handlers
835+
// ============================================================================
836+
837+
/// Execute a command by ID, dispatching to Mountain's CommandExecutor.
838+
async fn handle_commands_execute(runtime:Arc<ApplicationRunTime>, args:Vec<Value>) -> Result<Value, String> {
839+
let CommandId = args
840+
.first()
841+
.and_then(|V| V.as_str())
842+
.ok_or_else(|| "commands:execute requires string command_id as first argument".to_string())?
843+
.to_string();
844+
845+
let Argument = args.get(1).cloned().unwrap_or(Value::Null);
846+
847+
debug!("[WindServiceHandlers] commands:execute id={}", CommandId);
848+
849+
runtime
850+
.Environment
851+
.ExecuteCommand(CommandId, Argument)
852+
.await
853+
.map_err(|Error| format!("commands:execute failed: {}", Error))
854+
}
855+
856+
/// Return all registered command IDs from Mountain's CommandRegistry.
857+
async fn handle_commands_get_all(runtime:Arc<ApplicationRunTime>) -> Result<Value, String> {
858+
let Commands = runtime
859+
.Environment
860+
.GetAllCommands()
861+
.await
862+
.map_err(|Error| format!("commands:getAll failed: {}", Error))?;
863+
864+
Ok(json!(Commands))
865+
}
866+
867+
// ============================================================================
868+
// Extension Host Handlers
869+
// ============================================================================
870+
871+
/// Return metadata for all scanned extensions.
872+
async fn handle_extensions_get_all(runtime:Arc<ApplicationRunTime>) -> Result<Value, String> {
873+
let Extensions = runtime
874+
.Environment
875+
.GetExtensions()
876+
.await
877+
.map_err(|Error| format!("extensions:getAll failed: {}", Error))?;
878+
879+
Ok(json!(Extensions))
880+
}
881+
882+
/// Return metadata for a single extension by ID.
883+
async fn handle_extensions_get(runtime:Arc<ApplicationRunTime>, args:Vec<Value>) -> Result<Value, String> {
884+
let Id = args
885+
.first()
886+
.and_then(|V| V.as_str())
887+
.ok_or_else(|| "extensions:get requires string id as first argument".to_string())?
888+
.to_string();
889+
890+
let Extension = runtime
891+
.Environment
892+
.GetExtension(Id)
893+
.await
894+
.map_err(|Error| format!("extensions:get failed: {}", Error))?;
895+
896+
Ok(Extension.unwrap_or(Value::Null))
897+
}
898+
899+
/// Check whether an extension is currently active (scanned and present).
900+
async fn handle_extensions_is_active(runtime:Arc<ApplicationRunTime>, args:Vec<Value>) -> Result<Value, String> {
901+
let Id = args
902+
.first()
903+
.and_then(|V| V.as_str())
904+
.ok_or_else(|| "extensions:isActive requires string id as first argument".to_string())?
905+
.to_string();
906+
907+
let Extension = runtime
908+
.Environment
909+
.GetExtension(Id)
910+
.await
911+
.map_err(|Error| format!("extensions:isActive failed: {}", Error))?;
912+
913+
Ok(json!(Extension.is_some()))
914+
}

0 commit comments

Comments
 (0)