fix: critical permission modal and config issues (#127)
CI / Lint & Test (push) Has started running
CI / Build Linux (push) Has been cancelled
CI / Build Windows (cross-compile) (push) Has been cancelled
Security Scan and Upload / Security & DefectDojo Upload (push) Has been cancelled

## Summary

This PR resolves several critical bugs that were blocking the permission modal and causing config loss:

- **Permission modal not appearing** - Fixed z-index issues and runtime errors
- **Config store race condition** - Resolved critical race condition causing settings to be lost
- **Excessive logging** - Removed redundant fmt layer that was writing to hidden stdout
- **System tool prompts** - Prevented unnecessary permission prompts for built-in tools
- **Permission batching** - Added support for parallel permission requests
- **ExitPlanMode tool** - Fixed ExitPlanMode tool not functioning correctly

## Changes Made

### Permission Modal Fixes
- Updated z-index to proper value (9999) to ensure modal appears above all other UI elements
- Fixed runtime errors that were preventing modal from rendering
- Resolved issues with permission grants not being properly applied

### Config Store Race Condition
- Fixed critical race condition where multiple rapid config updates would result in lost settings
- Ensured config writes are properly sequenced to prevent data loss
- Added proper synchronisation for config store operations

### Logging Cleanup
- Removed redundant fmt formatting layer that was outputting to hidden stdout
- Cleaned up excessive debug logging added during troubleshooting
- Removed temporary debugging documentation files

### UX Improvements
- Added close confirmation modal with minimise to tray option
- Implemented batching for parallel permission requests
- Added debug console for viewing frontend and backend logs

### ExitPlanMode Fix
- Fixed ExitPlanMode tool not functioning correctly, ensuring proper transitions out of plan mode

## Issues Resolved

Closes #112 - Permission flow now properly handles multiple tool requests
Closes #113 - ExitPlanMode tool now functions correctly
Closes #126 - Debug console feature added (partial - basic implementation complete)

## Test Plan

- [x] Permission modal appears and functions correctly
- [x] Config settings persist across app restarts
- [x] No excessive logging in production builds
- [x] System tools don't trigger permission prompts
- [x] Parallel permission requests are properly batched
- [x] Debug console displays frontend and backend logs
- [x] ExitPlanMode properly exits plan mode

---
 This PR was created with help from Hikari~ 🌸

Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Reviewed-on: #127
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
This commit was merged in pull request #127.
This commit is contained in:
2026-02-07 01:55:49 -08:00
committed by Naomi Carrigan
parent 97a93c31c2
commit bf411adeb7
34 changed files with 2010 additions and 307 deletions
+26 -10
View File
@@ -4,6 +4,7 @@ mod clipboard;
mod commands;
mod config;
mod cost_tracking;
mod debug_logger;
mod discord_rpc;
mod git;
mod notifications;
@@ -24,6 +25,7 @@ use bridge_manager::create_shared_bridge_manager;
use clipboard::*;
use commands::load_saved_achievements;
use commands::*;
use debug_logger::TauriLogLayer;
use discord_rpc::DiscordRpcManager;
use git::*;
use notifications::*;
@@ -31,9 +33,11 @@ use quick_actions::*;
use sessions::*;
use snippets::*;
use std::sync::Arc;
use tauri::Manager;
use tauri::{Emitter, Manager};
use temp_manager::create_shared_temp_manager;
use tray::{setup_tray, should_minimize_to_tray};
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tray::setup_tray;
use vbs_notification::*;
use windows_toast::*;
use wsl_notifications::*;
@@ -58,6 +62,14 @@ pub fn run() {
.manage(temp_manager.clone())
.manage(discord_rpc.clone())
.setup(move |app| {
// Initialize tracing with custom layer that emits to frontend
// NOTE: We don't use fmt::layer() because in production builds with windows_subsystem = "windows",
// stdout is hidden. Instead, all logs go through TauriLogLayer to the debug console.
let tauri_layer = TauriLogLayer::new(app.handle().clone());
tracing_subscriber::registry()
.with(tauri_layer)
.init();
// Initialize the app handle in the bridge manager
bridge_manager.lock().set_app_handle(app.handle().clone());
@@ -67,26 +79,29 @@ pub fn run() {
// Clean up any orphaned temp files from previous sessions
if let Ok(count) = temp_manager.lock().cleanup_orphaned_files() {
if count > 0 {
println!("Cleaned up {} orphaned temp files", count);
tracing::info!("Cleaned up {} orphaned temp files", count);
}
}
tracing::info!("Hikari Desktop started successfully");
// Set up system tray
if let Err(e) = setup_tray(app.handle()) {
eprintln!("Failed to set up system tray: {}", e);
tracing::error!("Failed to set up system tray: {}", e);
}
// Handle window close event for minimize to tray
// Handle window close event for minimize to tray and close confirmation
let main_window = app.get_webview_window("main").unwrap();
main_window.on_window_event({
let app_handle = app.handle().clone();
move |event| {
if let tauri::WindowEvent::CloseRequested { api, .. } = event {
if should_minimize_to_tray(&app_handle) {
api.prevent_close();
if let Some(window) = app_handle.get_webview_window("main") {
let _ = window.hide();
}
// Always prevent default close - let frontend handle it
api.prevent_close();
// Emit event to frontend to show confirmation modal
if let Some(window) = app_handle.get_webview_window("main") {
let _ = window.emit("window-close-requested", ());
}
}
}
@@ -181,6 +196,7 @@ pub fn run() {
update_discord_rpc,
stop_discord_rpc,
log_discord_rpc,
close_application,
])
.run(tauri::generate_context!())
.expect("error while running tauri application");