DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/ProcessManagement/
InitializationData.rs1use std::{collections::HashMap, env, fs, path::PathBuf, sync::Arc};
136
137use CommonLibrary::{
138 Environment::Requires::Requires,
139 Error::CommonError::CommonError,
140 ExtensionManagement::ExtensionManagementService::ExtensionManagementService,
141 Workspace::WorkspaceProvider::WorkspaceProvider,
142};
143use serde_json::{Value, json};
144use tauri::{AppHandle, Manager, Wry};
145use uuid::Uuid;
146
147use crate::{
148 ApplicationState::State::ApplicationState::ApplicationState,
149 Environment::MountainEnvironment::MountainEnvironment,
150 dev_log,
151};
152
153fn get_or_generate_machine_id(app_data_dir:&PathBuf) -> String {
164 let machine_id_path = app_data_dir.join("machine-id.txt");
165
166 if let Ok(content) = fs::read_to_string(&machine_id_path) {
168 let trimmed = content.trim();
169
170 if !trimmed.is_empty() {
171 dev_log!("cocoon", "[InitializationData] Loaded existing machine ID from disk");
172
173 return trimmed.to_string();
174 }
175 }
176
177 let new_machine_id = Uuid::new_v4().to_string();
179
180 if let Some(parent) = machine_id_path.parent() {
182 if let Err(e) = fs::create_dir_all(parent) {
183 dev_log!(
184 "cocoon",
185 "warn: [InitializationData] Failed to create machine ID directory: {}",
186 e
187 );
188 }
189 }
190
191 if let Err(e) = fs::write(&machine_id_path, &new_machine_id) {
193 dev_log!(
194 "cocoon",
195 "warn: [InitializationData] Failed to persist machine ID to disk: {}",
196 e
197 );
198 } else {
199 dev_log!("cocoon", "[InitializationData] Generated and persisted new machine ID");
200 }
201
202 new_machine_id
203}
204
205pub async fn ConstructSandboxConfiguration(
207 ApplicationHandle:&AppHandle<Wry>,
208
209 ApplicationState:&Arc<ApplicationState>,
210) -> Result<Value, CommonError> {
211 dev_log!("cocoon", "[InitializationData] Constructing ISandboxConfiguration for Sky.");
212
213 let PathResolver = ApplicationHandle.path();
214
215 let AppRootUri = PathResolver.resource_dir().map_err(|Error| {
216 CommonError::ConfigurationLoad {
217 Description:format!("Failed to resolve resource directory (app root): {}", Error),
218 }
219 })?;
220
221 let AppDataDir = PathResolver.app_data_dir().map_err(|Error| {
222 CommonError::ConfigurationLoad { Description:format!("Failed to resolve app data directory: {}", Error) }
223 })?;
224
225 let HomeDir = PathResolver.home_dir().map_err(|Error| {
226 CommonError::ConfigurationLoad { Description:format!("Failed to resolve home directory: {}", Error) }
227 })?;
228
229 let TmpDir = env::temp_dir();
230
231 let BackupPath = AppDataDir.join("Backups").join(ApplicationState.GetWorkspaceIdentifier()?);
232
233 let LogsPath = AppDataDir.join("logs").join(crate::IPC::DevLog::SessionTimestamp::Fn());
238 let _ = std::fs::create_dir_all(&LogsPath);
239
240 let Platform = match env::consts::OS {
241 "windows" => "win32",
242
243 "macos" => "darwin",
244
245 "linux" => "linux",
246
247 _ => "unknown",
248 };
249
250 let Arch = match env::consts::ARCH {
251 "x86_64" => "x64",
252
253 "aarch64" => "arm64",
254
255 "x86" => "ia32",
256
257 _ => "unknown",
258 };
259
260 let Versions = json!({
261 "mountain": ApplicationHandle.package_info().version.to_string(),
262
263 "electron": "0.0.0-tauri",
265
266 "chrome": "120.0.0.0",
268
269 "node": "18.18.2"
271 });
272
273 let machine_id = get_or_generate_machine_id(&AppDataDir);
275
276 Ok(json!({
277 "windowId": ApplicationHandle.get_webview_window("main").unwrap().label(),
278
279 "machineId": machine_id,
284
285 "sessionId": Uuid::new_v4().to_string(),
286
287 "logLevel": log::max_level() as i32,
288
289 "userEnv": env::vars().collect::<HashMap<_,_>>(),
290
291 "appRoot": AppRootUri.to_string_lossy(),
298
299 "appName": ApplicationHandle.package_info().name.clone(),
300
301 "appUriScheme": "mountain",
302
303 "appLanguage": "en",
304
305 "appHost": "desktop",
306
307 "platform": Platform,
308
309 "arch": Arch,
310
311 "versions": Versions,
312
313 "execPath": env::current_exe().unwrap_or_default().to_string_lossy(),
314
315 "homeDir": HomeDir.to_string_lossy(),
319
320 "tmpDir": TmpDir.to_string_lossy(),
321
322 "userDataDir": AppDataDir.to_string_lossy(),
323
324 "backupPath": BackupPath.to_string_lossy(),
325
326 "logsPath": LogsPath.to_string_lossy(),
327
328 "perfMarks": [],
332
333 "colorScheme": { "dark": false, "highContrast": false },
334
335 "loggers": [],
336
337 "mainPid": std::process::id(),
338
339 "os": {
340 "release": "22.0.0",
341 "hostname": "land",
342 "arch": env::consts::ARCH,
343 },
344
345 "nls": { "messages": {}, "language": "en", "availableLanguages": { "en": "English" } },
346
347 "productConfiguration": {
348
349 "nameShort": std::env::var("ProductNameShort").unwrap_or_else(|_| "FIDDEE".into()),
353 "nameLong": std::env::var("ProductNameLong").unwrap_or_else(|_| "FIDDEE".into()),
354 "applicationName": std::env::var("ProductApplicationName").unwrap_or_else(|_| "fiddee".into()),
355 "embedderIdentifier": std::env::var("ProductEmbedderIdentifier").unwrap_or_else(|_| "fiddee-desktop".into()),
356
357 "dataFolderName": std::env::var("ProductDataFolderName").unwrap_or_else(|_| ".fiddee".into()),
362
363 "sharedDataFolderName": std::env::var("ProductDataFolderName").unwrap_or_else(|_| ".fiddee".into()),
366
367 "version": std::env::var("ProductVersion").unwrap_or_else(|_| "1.0.0".into()),
369 },
370
371 "resourcesPath": PathResolver.resource_dir().unwrap_or_default().to_string_lossy(),
372
373 "VSCODE_CWD": env::current_dir().unwrap_or_default().to_string_lossy(),
374 }))
375}
376
377pub async fn ConstructExtensionHostInitializationData(Environment:&MountainEnvironment) -> Result<Value, CommonError> {
379 dev_log!("cocoon", "[InitializationData] Constructing IExtensionHostInitData for Cocoon.");
380
381 let ApplicationState = &Environment.ApplicationState;
382
383 let ApplicationHandle = &Environment.ApplicationHandle;
384
385 let ExtensionManagementProvider:Arc<dyn ExtensionManagementService> = Environment.Require();
386
387 let ExtensionsDTO = ExtensionManagementProvider.GetExtensions().await?;
388
389 let WorkspaceProvider:Arc<dyn WorkspaceProvider> = Environment.Require();
390
391 let WorkspaceName = WorkspaceProvider
392 .GetWorkspaceName()
393 .await?
394 .unwrap_or_else(|| "Mountain Workspace".to_string());
395
396 let WorkspaceFoldersGuard = ApplicationState.Workspace.WorkspaceFolders.lock().unwrap();
397
398 let FoldersWire:Vec<Value> = WorkspaceFoldersGuard
409 .iter()
410 .map(|Folder| {
411 json!({
412 "uri": Folder.URI.to_string(),
413 "name": Folder.GetDisplayName(),
414 "index": Folder.Index,
415 })
416 })
417 .collect();
418
419 dev_log!(
425 "cocoon",
426 "[InitializationData] FoldersWire count={} sample0={}",
427 FoldersWire.len(),
428 FoldersWire.first().map(|F| F.to_string()).unwrap_or_else(|| "<none>".into())
429 );
430
431 let WorkspaceDTO = if WorkspaceFoldersGuard.is_empty() {
432 Value::Null
433 } else {
434 json!({
435
436 "id": ApplicationState.GetWorkspaceIdentifier()?,
437
438 "name": WorkspaceName,
439
440 "folders": FoldersWire,
441
442 "configuration": ApplicationState.Workspace.WorkspaceConfigurationPath.lock().unwrap().as_ref().map(|p| p.to_string_lossy()),
443
444 "isUntitled": ApplicationState.Workspace.WorkspaceConfigurationPath.lock().unwrap().is_none(),
445
446 "transient": false
447 })
448 };
449
450 let PathResolver = ApplicationHandle.path();
451
452 let AppRoot = PathResolver
453 .resource_dir()
454 .ok()
455 .filter(|P| !P.as_os_str().is_empty() && P.exists())
456 .or_else(|| {
457 let ExeDir = std::env::current_exe()
466 .ok()
467 .and_then(|P| P.parent().map(|D| D.to_path_buf()))
468 .unwrap_or_default();
469 let BundleResources = ExeDir.join("../Resources");
470 if BundleResources.exists() {
471 return Some(BundleResources.canonicalize().unwrap_or(BundleResources));
472 }
473 let SkyTarget = ExeDir.join("../../../Sky/Target");
474 if SkyTarget.exists() {
475 return Some(SkyTarget.canonicalize().unwrap_or(SkyTarget));
476 }
477 None
478 })
479 .ok_or_else(|| {
480 CommonError::ConfigurationLoad {
481 Description:"Could not resolve AppRoot from resource_dir, ../Resources, or ../../../Sky/Target"
482 .to_string(),
483 }
484 })?;
485
486 let AppData = PathResolver
487 .app_data_dir()
488 .map_err(|Error| CommonError::ConfigurationLoad { Description:Error.to_string() })?;
489
490 let LogsLocation = PathResolver
491 .app_log_dir()
492 .map_err(|Error| CommonError::ConfigurationLoad { Description:Error.to_string() })?;
493
494 let GlobalStorage = AppData.join("User/globalStorage");
495
496 let WorkspaceStorage = AppData.join("User/workspaceStorage");
497
498 Ok(json!({
499
500 "commit": std::env::var("ProductCommit").unwrap_or_else(|_| "dev".into()),
506
507 "version": std::env::var("ProductVersion").unwrap_or_else(|_| {
508 ApplicationHandle.package_info().version.to_string()
509 }),
510
511 "quality": std::env::var("ProductQuality").unwrap_or_else(|_| "development".into()),
512
513 "parentPid": std::process::id(),
514
515 "environment": {
516
517 "isExtensionDevelopmentDebug": false,
518
519 "appName": "Mountain",
520
521 "appHost": "desktop",
522
523 "appUriScheme": "mountain",
524
525 "appLanguage": "en",
526
527 "isExtensionTelemetryLoggingOnly": true,
528
529 "appRoot": url::Url::from_directory_path(AppRoot.clone()).unwrap(),
530
531 "globalStorageHome": url::Url::from_directory_path(GlobalStorage).unwrap(),
532
533 "workspaceStorageHome": url::Url::from_directory_path(WorkspaceStorage).unwrap(),
534
535 "extensionDevelopmentLocationURI": [],
536
537 "extensionTestsLocationURI": Value::Null,
538
539 "extensionLogLevel": [["info", "Default"]],
540
541 },
542
543 "workspace": WorkspaceDTO,
544
545 "remote": {
546
547 "isRemote": false,
548
549 "authority": Value::Null,
550
551 "connectionData": Value::Null,
552
553 },
554
555 "consoleForward": { "includeStack": true, "logNative": true },
556
557 "logLevel": log::max_level() as i32,
558
559 "logsLocation": url::Url::from_directory_path(LogsLocation).unwrap(),
560
561 "telemetryInfo": {
562
563 "sessionId": Uuid::new_v4().to_string(),
564
565 "machineId": get_or_generate_machine_id(&AppData),
566
567 "firstSessionDate": "2024-01-01T00:00:00.000Z",
568
569 "msftInternal": false
570 },
571
572 "extensions": ExtensionsDTO,
573
574 "autoStart": true,
575
576 "uiKind": 1,
578 }))
579}