mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(desktop): resolve CI fmt and file-size failures
Three fixes for PR CI: - fmt: apply rustfmt to the rebased command_env helper in managed_agents/runtime/tests.rs (Rust Lint failure). - lib.rs over the 1000-line limit: move the window/haptic tauri commands (perform_sidebar_default_haptic, title_bar_double_click, fill_window, toggle_maximize) into commands/window_actions.rs where they belong with the other frontend-forwarded commands (1012 -> 901 lines, back under the default limit). - app_state.rs over its ratchet: drop the AppState field for the experiment entirely. The experiment flag now lives in commands/experiments.rs as a process-local atomic, lazily hydrated from the Rust-owned store on first read. The hydrate-before-restore ordering invariant now holds by construction (the spawn boundary is the first reader) instead of by an app-setup ordering requirement, and app_state.rs is byte-identical to main — one less shared surface the experiment touches. desktop src-tauri: cargo test 1483 passed, clippy and fmt clean, and node scripts/check-file-sizes.mjs passes. Co-authored-by: npub1zurdm6fx3kksz8f8d8y4js3mvjyu3rshlpqejr8wa8hta5tsqqeshmes7w <1706dde9268dad011d2769c959423b6489c88e17f841990ceee9eebed1700033@sprout-oss.stage.blox.sqprod.co> Signed-off-by: npub1zurdm6fx3kksz8f8d8y4js3mvjyu3rshlpqejr8wa8hta5tsqqeshmes7w <1706dde9268dad011d2769c959423b6489c88e17f841990ceee9eebed1700033@sprout-oss.stage.blox.sqprod.co>
This commit is contained in:
parent
f442707444
commit
ae1bbc8d64
@@ -38,8 +38,6 @@ pub struct AppState {
|
||||
/// records. Disabled by the agent-managed profiles experiment so an agent's
|
||||
/// own profile updates are not overwritten on start or restore.
|
||||
pub managed_agent_profile_reconcile_enabled: AtomicBool,
|
||||
/// Process-local in-app experiment forwarded to newly spawned ACP harnesses.
|
||||
pub acp_top_level_sessions_experiment: AtomicBool,
|
||||
/// Shared shutdown signal checked by launch-time agent restoration.
|
||||
pub shutdown_started: AtomicBool,
|
||||
/// Serializes the restore spawn/register transition with shutdown cleanup,
|
||||
@@ -203,7 +201,6 @@ pub fn build_app_state() -> AppState {
|
||||
relay_url_override: Mutex::new(None),
|
||||
managed_agent_restore_pending: AtomicBool::new(false),
|
||||
managed_agent_profile_reconcile_enabled: AtomicBool::new(true),
|
||||
acp_top_level_sessions_experiment: AtomicBool::new(false),
|
||||
shutdown_started: AtomicBool::new(false),
|
||||
managed_agent_restore_transition: Mutex::new(()),
|
||||
identity_mutation: Mutex::new(()),
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
sync::atomic::Ordering,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
sync::Once,
|
||||
};
|
||||
|
||||
use atomic_write_file::AtomicWriteFile;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tauri::{AppHandle, Manager, State};
|
||||
|
||||
use crate::app_state::AppState;
|
||||
use tauri::{AppHandle, Manager};
|
||||
|
||||
const EXPERIMENTS_FILE: &str = "desktop-experiments.json";
|
||||
|
||||
/// Process-local experiment state, lazily hydrated from the Rust-owned store on
|
||||
/// first read so every reader (spawn boundary, frontend) sees persisted state
|
||||
/// without an app-setup ordering requirement. A corrupt store fails closed:
|
||||
/// the error is logged and the disabled default stays.
|
||||
static ACP_TOP_LEVEL_SESSIONS: AtomicBool = AtomicBool::new(false);
|
||||
static HYDRATE: Once = Once::new();
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
#[serde(default)]
|
||||
struct DesktopExperiments {
|
||||
@@ -52,36 +58,36 @@ fn save_experiments(path: &Path, experiments: &DesktopExperiments) -> Result<(),
|
||||
.map_err(|error| format!("commit {}: {error}", path.display()))
|
||||
}
|
||||
|
||||
/// Hydrate process state from the Rust-owned store before managed-agent restore.
|
||||
pub(crate) fn hydrate_desktop_experiments(app: &AppHandle, state: &AppState) -> Result<(), String> {
|
||||
let experiments = load_experiments(&experiments_path(app)?)?;
|
||||
state
|
||||
.acp_top_level_sessions_experiment
|
||||
.store(experiments.acp_top_level_sessions, Ordering::Release);
|
||||
Ok(())
|
||||
/// Read the experiment, hydrating from the store on first access.
|
||||
pub(crate) fn acp_top_level_sessions_enabled(app: &AppHandle) -> bool {
|
||||
HYDRATE.call_once(
|
||||
|| match experiments_path(app).and_then(|path| load_experiments(&path)) {
|
||||
Ok(experiments) => {
|
||||
ACP_TOP_LEVEL_SESSIONS.store(experiments.acp_top_level_sessions, Ordering::Release);
|
||||
}
|
||||
Err(error) => {
|
||||
eprintln!("buzz-desktop: failed to hydrate desktop experiments: {error}");
|
||||
}
|
||||
},
|
||||
);
|
||||
ACP_TOP_LEVEL_SESSIONS.load(Ordering::Acquire)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_acp_top_level_sessions_experiment(state: State<'_, AppState>) -> bool {
|
||||
state
|
||||
.acp_top_level_sessions_experiment
|
||||
.load(Ordering::Acquire)
|
||||
pub fn get_acp_top_level_sessions_experiment(app: AppHandle) -> bool {
|
||||
acp_top_level_sessions_enabled(&app)
|
||||
}
|
||||
|
||||
/// Durably apply the experiment before exposing it to subsequently spawned agents.
|
||||
#[tauri::command]
|
||||
pub fn set_acp_top_level_sessions_experiment(
|
||||
enabled: bool,
|
||||
app: AppHandle,
|
||||
state: State<'_, AppState>,
|
||||
) -> Result<(), String> {
|
||||
pub fn set_acp_top_level_sessions_experiment(enabled: bool, app: AppHandle) -> Result<(), String> {
|
||||
let path = experiments_path(&app)?;
|
||||
let mut experiments = load_experiments(&path)?;
|
||||
experiments.acp_top_level_sessions = enabled;
|
||||
save_experiments(&path, &experiments)?;
|
||||
state
|
||||
.acp_top_level_sessions_experiment
|
||||
.store(enabled, Ordering::Release);
|
||||
// Persisted first: even if first-read hydration races this store, it
|
||||
// re-reads the same on-disk value.
|
||||
ACP_TOP_LEVEL_SESSIONS.store(enabled, Ordering::Release);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ mod social;
|
||||
mod team_snapshot;
|
||||
mod teams;
|
||||
mod updater;
|
||||
mod window_actions;
|
||||
mod window_vibrancy;
|
||||
mod workflows;
|
||||
mod workspace;
|
||||
@@ -93,6 +94,7 @@ pub use social::*;
|
||||
pub use team_snapshot::*;
|
||||
pub use teams::*;
|
||||
pub use updater::*;
|
||||
pub use window_actions::*;
|
||||
pub use window_vibrancy::*;
|
||||
pub use workflows::*;
|
||||
pub use workspace::*;
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
//! Native window and haptic commands forwarded from the web frontend.
|
||||
|
||||
#[tauri::command]
|
||||
pub fn perform_sidebar_default_haptic() {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
use objc2_app_kit::{
|
||||
NSHapticFeedbackManager, NSHapticFeedbackPattern, NSHapticFeedbackPerformanceTime,
|
||||
NSHapticFeedbackPerformer,
|
||||
};
|
||||
|
||||
NSHapticFeedbackManager::defaultPerformer().performFeedbackPattern_performanceTime(
|
||||
NSHapticFeedbackPattern::Alignment,
|
||||
NSHapticFeedbackPerformanceTime::Now,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs the window action matching the macOS "double-click a window's
|
||||
/// title bar to" preference (`AppleActionOnDoubleClick`).
|
||||
///
|
||||
/// macOS values are `Minimize`, `Maximize` (default when unset), `Fill`, or
|
||||
/// `None`.
|
||||
/// The desktop app uses a web-based title-bar drag region, so the frontend
|
||||
/// forwards double-clicks here and suppresses Tauri's injected drag-region
|
||||
/// handler, whose default macOS path hardcodes maximize.
|
||||
///
|
||||
/// For `Fill`, resize to the current monitor work area instead of using
|
||||
/// Tauri's maximize path, which maps to macOS zoom for titled, resizable
|
||||
/// windows.
|
||||
///
|
||||
/// On non-macOS platforms this always toggles maximize (the historical
|
||||
/// behavior).
|
||||
#[tauri::command]
|
||||
pub fn title_bar_double_click(window: tauri::Window) {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let action = {
|
||||
let output = std::process::Command::new("defaults")
|
||||
.args(["read", "-g", "AppleActionOnDoubleClick"])
|
||||
.output();
|
||||
match output {
|
||||
Ok(output) if output.status.success() => {
|
||||
String::from_utf8_lossy(&output.stdout).trim().to_string()
|
||||
}
|
||||
_ => "Maximize".to_string(),
|
||||
}
|
||||
};
|
||||
|
||||
match action.as_str() {
|
||||
"None" => {}
|
||||
"Minimize" => {
|
||||
let _ = window.minimize();
|
||||
}
|
||||
"Fill" => {
|
||||
fill_window(&window);
|
||||
}
|
||||
// "Maximize" or any unexpected value.
|
||||
_ => {
|
||||
toggle_maximize(&window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
toggle_maximize(&window);
|
||||
}
|
||||
}
|
||||
|
||||
/// Fills the current display work area, excluding system UI like the menu bar
|
||||
/// and Dock.
|
||||
#[cfg(target_os = "macos")]
|
||||
fn fill_window(window: &tauri::Window) {
|
||||
match window.current_monitor() {
|
||||
Ok(Some(monitor)) => {
|
||||
if window.is_maximized().unwrap_or(false) {
|
||||
let _ = window.unmaximize();
|
||||
}
|
||||
|
||||
let work_area = monitor.work_area();
|
||||
let _ = window.set_position(work_area.position);
|
||||
let _ = window.set_size(work_area.size);
|
||||
}
|
||||
_ => {
|
||||
let _ = window.maximize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Toggles the window between maximized and its previous size, matching the
|
||||
/// historical double-click behavior.
|
||||
fn toggle_maximize(window: &tauri::Window) {
|
||||
match window.is_maximized() {
|
||||
Ok(true) => {
|
||||
let _ = window.unmaximize();
|
||||
}
|
||||
_ => {
|
||||
let _ = window.maximize();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,106 +63,6 @@ use tauri_plugin_window_state::StateFlags;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
const INITIAL_RENDER_READY_EVENT: &str = "initial-render-ready";
|
||||
#[tauri::command]
|
||||
fn perform_sidebar_default_haptic() {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
use objc2_app_kit::{
|
||||
NSHapticFeedbackManager, NSHapticFeedbackPattern, NSHapticFeedbackPerformanceTime,
|
||||
NSHapticFeedbackPerformer,
|
||||
};
|
||||
|
||||
NSHapticFeedbackManager::defaultPerformer().performFeedbackPattern_performanceTime(
|
||||
NSHapticFeedbackPattern::Alignment,
|
||||
NSHapticFeedbackPerformanceTime::Now,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs the window action matching the macOS "double-click a window's
|
||||
/// title bar to" preference (`AppleActionOnDoubleClick`).
|
||||
///
|
||||
/// macOS values are `Minimize`, `Maximize` (default when unset), `Fill`, or
|
||||
/// `None`.
|
||||
/// The desktop app uses a web-based title-bar drag region, so the frontend
|
||||
/// forwards double-clicks here and suppresses Tauri's injected drag-region
|
||||
/// handler, whose default macOS path hardcodes maximize.
|
||||
///
|
||||
/// For `Fill`, resize to the current monitor work area instead of using
|
||||
/// Tauri's maximize path, which maps to macOS zoom for titled, resizable
|
||||
/// windows.
|
||||
///
|
||||
/// On non-macOS platforms this always toggles maximize (the historical
|
||||
/// behavior).
|
||||
#[tauri::command]
|
||||
fn title_bar_double_click(window: tauri::Window) {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let action = {
|
||||
let output = std::process::Command::new("defaults")
|
||||
.args(["read", "-g", "AppleActionOnDoubleClick"])
|
||||
.output();
|
||||
match output {
|
||||
Ok(output) if output.status.success() => {
|
||||
String::from_utf8_lossy(&output.stdout).trim().to_string()
|
||||
}
|
||||
_ => "Maximize".to_string(),
|
||||
}
|
||||
};
|
||||
|
||||
match action.as_str() {
|
||||
"None" => {}
|
||||
"Minimize" => {
|
||||
let _ = window.minimize();
|
||||
}
|
||||
"Fill" => {
|
||||
fill_window(&window);
|
||||
}
|
||||
// "Maximize" or any unexpected value.
|
||||
_ => {
|
||||
toggle_maximize(&window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
toggle_maximize(&window);
|
||||
}
|
||||
}
|
||||
|
||||
/// Fills the current display work area, excluding system UI like the menu bar
|
||||
/// and Dock.
|
||||
#[cfg(target_os = "macos")]
|
||||
fn fill_window(window: &tauri::Window) {
|
||||
match window.current_monitor() {
|
||||
Ok(Some(monitor)) => {
|
||||
if window.is_maximized().unwrap_or(false) {
|
||||
let _ = window.unmaximize();
|
||||
}
|
||||
|
||||
let work_area = monitor.work_area();
|
||||
let _ = window.set_position(work_area.position);
|
||||
let _ = window.set_size(work_area.size);
|
||||
}
|
||||
_ => {
|
||||
let _ = window.maximize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Toggles the window between maximized and its previous size, matching the
|
||||
/// historical double-click behavior.
|
||||
fn toggle_maximize(window: &tauri::Window) {
|
||||
match window.is_maximized() {
|
||||
Ok(true) => {
|
||||
let _ = window.unmaximize();
|
||||
}
|
||||
_ => {
|
||||
let _ = window.maximize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn reveal_initial_window<R: tauri::Runtime>(window: &tauri::Window<R>) {
|
||||
if let Err(error) = window.show() {
|
||||
@@ -490,16 +390,6 @@ pub fn run() {
|
||||
migration::run_boot_migrations(&app_handle);
|
||||
}
|
||||
|
||||
// Hydrate Rust-owned experiments before any launch-time managed-agent
|
||||
// restore can spawn a process. A corrupt store fails closed and leaves
|
||||
// the disabled default in place.
|
||||
let state = app_handle.state::<AppState>();
|
||||
if let Err(error) =
|
||||
commands::experiments::hydrate_desktop_experiments(&app_handle, &state)
|
||||
{
|
||||
eprintln!("buzz-desktop: failed to hydrate desktop experiments: {error}");
|
||||
}
|
||||
|
||||
// Resolve persisted identity key (env var → file → generate+save).
|
||||
// This is fatal — the app should not start with an ephemeral identity
|
||||
// that will be lost on restart, as that silently breaks channel
|
||||
|
||||
@@ -1714,13 +1714,7 @@ pub fn spawn_agent_child(
|
||||
// Legacy default. User env may override this while the experiment is off;
|
||||
// enabled experiment state is authoritatively finalized at the spawn boundary.
|
||||
command.env("BUZZ_ACP_MULTIPLE_EVENT_HANDLING", "steer");
|
||||
let top_level_sessions = {
|
||||
use std::sync::atomic::Ordering;
|
||||
use tauri::Manager;
|
||||
app.state::<crate::app_state::AppState>()
|
||||
.acp_top_level_sessions_experiment
|
||||
.load(Ordering::Acquire)
|
||||
};
|
||||
let top_level_sessions = crate::commands::experiments::acp_top_level_sessions_enabled(app);
|
||||
command.env("BUZZ_ACP_DEDUP", "queue");
|
||||
if let Some(meta) = runtime_meta {
|
||||
for (key, value) in meta.default_env {
|
||||
|
||||
@@ -761,10 +761,9 @@ fn own_group_grandchild_detected_by_ancestor_walk() {
|
||||
let _ = intermediate.wait();
|
||||
}
|
||||
|
||||
fn command_env(command: &std::process::Command) -> std::collections::HashMap<
|
||||
std::ffi::OsString,
|
||||
std::ffi::OsString,
|
||||
> {
|
||||
fn command_env(
|
||||
command: &std::process::Command,
|
||||
) -> std::collections::HashMap<std::ffi::OsString, std::ffi::OsString> {
|
||||
command
|
||||
.get_envs()
|
||||
.filter_map(|(key, value)| value.map(|value| (key.to_owned(), value.to_owned())))
|
||||
|
||||
Reference in New Issue
Block a user