From a117fe91e20898b0b7a2b1d047fae3f58386d8a6 Mon Sep 17 00:00:00 2001 From: Kang Date: Tue, 28 Jul 2026 18:45:06 +0800 Subject: [PATCH] refactor(desktop): isolate presentation imports --- .../src/features/formatting/labels.rs | 15 ++++++- .../src/features/formatting/markdown.rs | 5 ++- .../src/features/formatting/mod.rs | 35 +++++++-------- .../src/features/icons/aliases.rs | 2 +- .../src/features/icons/connection.rs | 5 ++- .../src/features/icons/file_kind.rs | 2 +- .../nyaterm-desktop/src/features/icons/mod.rs | 2 +- .../src/features/icons/quick.rs | 2 +- .../src/features/icons/remote_system.rs | 2 +- .../src/features/icons/search.rs | 2 +- crates/nyaterm-desktop/src/features/mod.rs | 19 +++++++- .../src/features/view_widgets/chrome.rs | 9 +++- .../view_widgets/inspector_widgets.rs | 6 ++- .../src/features/view_widgets/markdown.rs | 10 ++++- .../src/features/view_widgets/mod.rs | 43 +++++++------------ .../src/features/view_widgets/rows.rs | 11 ++++- .../src/features/view_widgets/stats.rs | 6 ++- docs/architecture/gpui-migration-status.md | 14 +++++- scripts/check-architecture-boundaries.sh | 26 +++++++++++ 19 files changed, 154 insertions(+), 62 deletions(-) diff --git a/crates/nyaterm-desktop/src/features/formatting/labels.rs b/crates/nyaterm-desktop/src/features/formatting/labels.rs index e0c997509..3a5db6673 100644 --- a/crates/nyaterm-desktop/src/features/formatting/labels.rs +++ b/crates/nyaterm-desktop/src/features/formatting/labels.rs @@ -1,4 +1,17 @@ -use super::*; +use std::path::PathBuf; +use std::time::{SystemTime, UNIX_EPOCH}; + +use gpui::rgb; +use nyaterm_core::{ + AppSettingsSummary, CloudSyncError, CloudSyncHistoryEntry, CloudSyncSettings, RiskLevel, + TunnelConfig, +}; +use nyaterm_transport::{ + SessionKind, SshSessionConfig, SshTunnelMode, TelnetEnterMode, safe_recording_name, +}; + +use crate::features::AiAgentStepStatus; +use crate::theme::ThemePalette; pub(in crate::features) fn ai_agent_step_status_style( status: AiAgentStepStatus, diff --git a/crates/nyaterm-desktop/src/features/formatting/markdown.rs b/crates/nyaterm-desktop/src/features/formatting/markdown.rs index 34f5136d2..b47bba362 100644 --- a/crates/nyaterm-desktop/src/features/formatting/markdown.rs +++ b/crates/nyaterm-desktop/src/features/formatting/markdown.rs @@ -394,7 +394,10 @@ pub(in crate::features) fn parse_markdown_blocks(content: &str) -> Vec &'static str { diff --git a/crates/nyaterm-desktop/src/features/icons/aliases.rs b/crates/nyaterm-desktop/src/features/icons/aliases.rs index 4c8817529..732bb373a 100644 --- a/crates/nyaterm-desktop/src/features/icons/aliases.rs +++ b/crates/nyaterm-desktop/src/features/icons/aliases.rs @@ -72,7 +72,7 @@ pub(super) fn resolve_alias(normalized: &str) -> &str { #[cfg(test)] mod tests { - use super::*; + use super::{CONNECTION_ICON_ALIASES, normalize_connection_icon_key, resolve_alias}; #[test] fn normalization_strips_the_svg_suffix_case_insensitively() { diff --git a/crates/nyaterm-desktop/src/features/icons/connection.rs b/crates/nyaterm-desktop/src/features/icons/connection.rs index 946d3997b..a35062203 100644 --- a/crates/nyaterm-desktop/src/features/icons/connection.rs +++ b/crates/nyaterm-desktop/src/features/icons/connection.rs @@ -242,7 +242,10 @@ pub(in crate::features) fn default_connection_icon_for_kind(kind: &str) -> IconD mod tests { use super::super::IconPaint; use super::super::aliases::CONNECTION_ICON_ALIASES; - use super::*; + use super::{ + CONNECTION_ICON_OPTIONS, LINUX_ICONS, SERVER_ICONS, SYSTEM_ICONS, + default_connection_icon_for_kind, lookup, resolve_connection_icon, + }; /// Every key the GPUI picker has ever offered. Stored connections carry these /// verbatim, so none may stop resolving. diff --git a/crates/nyaterm-desktop/src/features/icons/file_kind.rs b/crates/nyaterm-desktop/src/features/icons/file_kind.rs index 553262402..f9dbb3295 100644 --- a/crates/nyaterm-desktop/src/features/icons/file_kind.rs +++ b/crates/nyaterm-desktop/src/features/icons/file_kind.rs @@ -117,7 +117,7 @@ pub(in crate::features) fn file_entry_icon( #[cfg(test)] mod tests { - use super::*; + use super::{IconDef, ThemePalette, file_entry_icon}; fn palette() -> ThemePalette { crate::theme::theme_palette("github-dark") diff --git a/crates/nyaterm-desktop/src/features/icons/mod.rs b/crates/nyaterm-desktop/src/features/icons/mod.rs index a81fae5c2..6e0fcf871 100644 --- a/crates/nyaterm-desktop/src/features/icons/mod.rs +++ b/crates/nyaterm-desktop/src/features/icons/mod.rs @@ -127,7 +127,7 @@ fn legible_on(color: u32, palette: ThemePalette) -> u32 { #[cfg(test)] mod tests { - use super::*; + use super::{IconDef, ThemePalette, legible_on, relative_luminance}; fn dark() -> ThemePalette { crate::theme::theme_palette("github-dark") diff --git a/crates/nyaterm-desktop/src/features/icons/quick.rs b/crates/nyaterm-desktop/src/features/icons/quick.rs index c6e27a46c..1d4ee8360 100644 --- a/crates/nyaterm-desktop/src/features/icons/quick.rs +++ b/crates/nyaterm-desktop/src/features/icons/quick.rs @@ -50,7 +50,7 @@ pub(in crate::features) fn quick_command_icon(icon_tag: &str) -> Option #[cfg(test)] mod tests { use super::super::IconPaint; - use super::*; + use super::{BRAND_ICONS, GENERIC_ICONS, QUICK_COMMAND_ICON_OPTIONS, quick_command_icon}; /// Tags the GPUI picker has offered since the migration. Saved commands carry /// them, so none may stop resolving. diff --git a/crates/nyaterm-desktop/src/features/icons/remote_system.rs b/crates/nyaterm-desktop/src/features/icons/remote_system.rs index 876af245d..b44654fac 100644 --- a/crates/nyaterm-desktop/src/features/icons/remote_system.rs +++ b/crates/nyaterm-desktop/src/features/icons/remote_system.rs @@ -124,7 +124,7 @@ pub(in crate::features) fn infer_connection_icon_key_from_remote_system( mod tests { use super::super::connection::resolve_connection_icon; use super::super::{IconPaint, connection::default_connection_icon_for_kind}; - use super::*; + use super::{DISTRO_MATCHES, infer_connection_icon_key_from_remote_system}; fn infer(os: &str) -> Option<&'static str> { infer_connection_icon_key_from_remote_system(os, "x86_64") diff --git a/crates/nyaterm-desktop/src/features/icons/search.rs b/crates/nyaterm-desktop/src/features/icons/search.rs index a1b7a1b74..41868e883 100644 --- a/crates/nyaterm-desktop/src/features/icons/search.rs +++ b/crates/nyaterm-desktop/src/features/icons/search.rs @@ -58,7 +58,7 @@ pub(in crate::features) fn search_engine_icon( #[cfg(test)] mod tests { - use super::*; + use super::{SEARCH_ENGINE_ICON_IDS, ThemePalette, search_engine_icon}; fn palette() -> ThemePalette { crate::theme::theme_palette("github-dark") diff --git a/crates/nyaterm-desktop/src/features/mod.rs b/crates/nyaterm-desktop/src/features/mod.rs index a3dba32a0..c25c32148 100644 --- a/crates/nyaterm-desktop/src/features/mod.rs +++ b/crates/nyaterm-desktop/src/features/mod.rs @@ -57,7 +57,16 @@ pub(in crate::features) use connections::{ ConnectionDragKind, ConnectionDragPayload, ConnectionDragPreview, ConnectionDropPosition, ConnectionDropTarget, ConnectionEditorToggle, ConnectionFeatureFocus, ConnectionFeatureState, }; -pub(in crate::features) use formatting::*; +pub(in crate::features) use formatting::{ + cloud_sync_history_status, cloud_sync_status_dot_color, cloud_sync_status_text_color, + compact_id, configured_cloud_sync_provider, docker_compose_project_key, docker_state_color, + docker_state_label, docker_state_rank, download_file_name_from_remote_path, + format_cloud_provider, format_duration_ms, format_history_timestamp_ms, format_last_used_ms, + format_permissions_octal, format_rate, format_terminal_line_timestamp_ms, format_uptime, + non_empty_string, none_if_blank, normalize_startup_command, recent_terminal_output, + session_kind_label, short_id, status_label, trim_terminal_output_to, tunnel_endpoint, + tunnel_mode, tunnel_name, +}; pub(in crate::features) use icons::{ CONNECTION_ICON_OPTIONS, DEFAULT_CONNECTION_ICON, IconDef, QUICK_COMMAND_ICON_OPTIONS, SEARCH_ENGINE_ICON_IDS, file_entry_icon, infer_connection_icon_key_from_remote_system, @@ -103,7 +112,13 @@ pub(in crate::features) use transfers::{ TransferFeatureFocus, TransferFeatureState, duplicate_decision_label, duplicate_policy_label, format_file_size, transfer_job_title, transfer_status_label, }; -pub(in crate::features) use view_widgets::*; +pub(in crate::features) use view_widgets::{ + activity_icon, child_window_header, child_window_titlebar, cloud_sync_history_row, color_icon, + connection_type_icon, dialog_action_button, empty_workspace_action, logo_mark, metric, + modal_close_icon_button, modal_dialog_footer_localized, modal_dialog_footer_localized_danger, + modal_dialog_shell, mono_icon, nyaterm_logo_mark, panel_header_with_actions, service_status, + stats_progress_bar, themed_icon, transfer_entry_icon, window_control_button, +}; const LEGACY_ROOT: &str = "./temp/nyaterm-tauri"; pub(crate) const INITIAL_TERMINAL_BANNER: &str = "$ nyaterm --native\nGPUI shell initialized.\nStart a local terminal or open a saved connection.\n"; diff --git a/crates/nyaterm-desktop/src/features/view_widgets/chrome.rs b/crates/nyaterm-desktop/src/features/view_widgets/chrome.rs index ebc182807..1a8fcd1e0 100644 --- a/crates/nyaterm-desktop/src/features/view_widgets/chrome.rs +++ b/crates/nyaterm-desktop/src/features/view_widgets/chrome.rs @@ -1,5 +1,10 @@ -use super::*; -use gpui::AnyElement; +use gpui::{ + AnyElement, App, ClickEvent, FontWeight, IntoElement, SharedString, TitlebarOptions, Window, + WindowControlArea, div, prelude::*, px, rgb, rgba, svg, +}; + +use crate::theme::ThemePalette; +use crate::widgets::small_button; pub(in crate::features) fn logo_mark(palette: ThemePalette) -> impl IntoElement { div() diff --git a/crates/nyaterm-desktop/src/features/view_widgets/inspector_widgets.rs b/crates/nyaterm-desktop/src/features/view_widgets/inspector_widgets.rs index aaaaad157..9cc1a2ace 100644 --- a/crates/nyaterm-desktop/src/features/view_widgets/inspector_widgets.rs +++ b/crates/nyaterm-desktop/src/features/view_widgets/inspector_widgets.rs @@ -1,4 +1,8 @@ -use super::*; +use gpui::{ + App, ClickEvent, FontWeight, IntoElement, SharedString, Window, div, prelude::*, px, rgb, svg, +}; + +use crate::theme::ThemePalette; /// Tauri EmptyWorkspaceState row: action label (primary) + shortcut key chips. pub(in crate::features) fn empty_workspace_action( diff --git a/crates/nyaterm-desktop/src/features/view_widgets/markdown.rs b/crates/nyaterm-desktop/src/features/view_widgets/markdown.rs index ab7c56daa..4fef21963 100644 --- a/crates/nyaterm-desktop/src/features/view_widgets/markdown.rs +++ b/crates/nyaterm-desktop/src/features/view_widgets/markdown.rs @@ -1,4 +1,12 @@ -use super::*; +use gpui::{ + FontStyle, FontWeight, HighlightStyle, IntoElement, SharedString, StrikethroughStyle, + StyledText, UnderlineStyle, div, prelude::*, px, rgb, +}; + +use crate::features::formatting::{ + InlineMdStyle, MarkdownBlock, parse_inline_markdown, parse_markdown_blocks, +}; +use crate::theme::ThemePalette; /// Lightweight GFM markdown renderer for AI transcript (Tauri MarkdownContent parity). pub(in crate::features) fn markdown_content_view( diff --git a/crates/nyaterm-desktop/src/features/view_widgets/mod.rs b/crates/nyaterm-desktop/src/features/view_widgets/mod.rs index 6aea9596d..56645fd27 100644 --- a/crates/nyaterm-desktop/src/features/view_widgets/mod.rs +++ b/crates/nyaterm-desktop/src/features/view_widgets/mod.rs @@ -1,37 +1,26 @@ -use gpui::{ - App, ClickEvent, FontStyle, FontWeight, HighlightStyle, IntoElement, SharedString, - StrikethroughStyle, StyledText, TitlebarOptions, UnderlineStyle, Window, WindowControlArea, - div, prelude::*, px, rgb, rgba, svg, -}; -use nyaterm_core::{ - CloudSyncHistoryEntry, ConnectionType, NativeServiceStatus, SavedConnection, TunnelConfig, - truncate_preview, -}; -use nyaterm_transport::{DockerContainer, NetworkInfo, RemoteProcess}; - -use crate::models::WorkspaceSplitDirection; -use crate::widgets::{mode_button, small_button, status_pill}; - -use super::{ - InlineMdStyle, MarkdownBlock, ThemePalette, cloud_sync_history_summary, - cloud_sync_kind_text_color, cloud_sync_status_dot_color, cloud_sync_status_text_color, - compact_id, docker_state_color, docker_state_label, format_history_timestamp_ms, format_rate, - parse_inline_markdown, parse_markdown_blocks, tunnel_endpoint, tunnel_name, -}; - mod chrome; -pub(in crate::features) use chrome::*; +pub(in crate::features) use chrome::{ + child_window_header, child_window_titlebar, dialog_action_button, logo_mark, + modal_close_icon_button, modal_dialog_footer_localized, modal_dialog_footer_localized_danger, + modal_dialog_shell, panel_header_with_actions, window_control_button, +}; mod inspector_widgets; -pub(in crate::features) use inspector_widgets::*; +pub(in crate::features) use inspector_widgets::{ + empty_workspace_action, tab_action_button, tab_menu_item, tab_menu_item_enabled, + tab_menu_separator, +}; mod stats; -pub(in crate::features) use stats::*; +pub(in crate::features) use stats::{metric, service_status, stats_progress_bar}; mod rows; -pub(in crate::features) use rows::*; +pub(in crate::features) use rows::cloud_sync_history_row; mod icons; -pub(in crate::features) use icons::*; +pub(in crate::features) use icons::{ + activity_icon, color_icon, connection_type_icon, mono_icon, nyaterm_logo_mark, themed_icon, + transfer_entry_icon, +}; mod markdown; -pub(in crate::features) use markdown::*; +pub(in crate::features) use markdown::markdown_content_view; diff --git a/crates/nyaterm-desktop/src/features/view_widgets/rows.rs b/crates/nyaterm-desktop/src/features/view_widgets/rows.rs index 1e1c89c6c..14cc874ec 100644 --- a/crates/nyaterm-desktop/src/features/view_widgets/rows.rs +++ b/crates/nyaterm-desktop/src/features/view_widgets/rows.rs @@ -1,4 +1,13 @@ -use super::*; +use gpui::{ + App, ClickEvent, FontWeight, IntoElement, SharedString, Window, div, prelude::*, px, rgb, +}; +use nyaterm_core::{CloudSyncHistoryEntry, truncate_preview}; + +use crate::features::formatting::{ + cloud_sync_history_summary, cloud_sync_kind_text_color, cloud_sync_status_dot_color, + cloud_sync_status_text_color, compact_id, format_history_timestamp_ms, +}; +use crate::theme::ThemePalette; pub(in crate::features) fn cloud_sync_history_row( palette: ThemePalette, diff --git a/crates/nyaterm-desktop/src/features/view_widgets/stats.rs b/crates/nyaterm-desktop/src/features/view_widgets/stats.rs index 792098304..1723d6ec0 100644 --- a/crates/nyaterm-desktop/src/features/view_widgets/stats.rs +++ b/crates/nyaterm-desktop/src/features/view_widgets/stats.rs @@ -1,4 +1,8 @@ -use super::*; +use gpui::{FontWeight, IntoElement, SharedString, div, prelude::*, px, rgb}; +use nyaterm_core::NativeServiceStatus; + +use crate::theme::ThemePalette; +use crate::widgets::status_pill; pub(in crate::features) fn stats_progress_bar( palette: ThemePalette, diff --git a/docs/architecture/gpui-migration-status.md b/docs/architecture/gpui-migration-status.md index fcec40ce5..bb0a31010 100644 --- a/docs/architecture/gpui-migration-status.md +++ b/docs/architecture/gpui-migration-status.md @@ -12,7 +12,7 @@ Last updated from the working tree on 2026-07-28. | `NyaTermApp` fields | 261 | Counted from `features/app_state/mod.rs`; down from 585, still transitional. | | `impl NyaTermApp` blocks | 239 | Spread across 234 files under `crates/nyaterm-desktop/src`. | | `#[path = "..."]` declarations in desktop | 0 | Cleared. Every directory is a real module; the boundary script fails on any new occurrence. | -| `use super::*` imports in desktop | 144 | Includes indented test-module imports; historical migration debt, do not add new occurrences. | +| `use super::*` imports in desktop | 130 | Includes indented test-module imports; historical migration debt, do not add new occurrences. | | `features/prelude.rs` rough exported-token count | 179 | Still a broad shared prelude; two hundred sixty-six low-frequency GPUI/transport/core/http/model/helper/widget exports are now explicit imports. | | Entity Store structs | 4 | `Runtime`, `WindowRuntime`, `StartupRestore`, `Overlay`. Each owns state the app does not. | | Snapshot structs | 0 | Cleared. No store is a projection of `NyaTermApp` any more. | @@ -497,6 +497,18 @@ these as staged extraction candidates, not as formatting-only refactor targets. imports and prevents those prelude exports from returning. SSH host-key and credential prompting, OTP lookup, credential autofill, session startup and restore, recording, and TRZSZ/ZMODEM behavior are unchanged. +- The complete 18-module presentation-support set under `features/icons`, + `features/formatting` and `features/view_widgets` is now free of + `use super::*` imports. Icon compatibility tests, markdown parser tests and + GPUI view helpers name their exact data, theme, formatting, widget and GPUI + dependencies. The formatting, view-widget and top-level feature façades also + use named re-exports instead of glob re-exports; twenty-three low-frequency + aliases no longer flatten into `crate::features` and remain available only + through their owning module paths. The architecture script governs all three + trees and prevents their module-entry glob re-exports from returning. + Persisted connection/quick-command icon keys, icon resolution order, markdown + parsing and rendering, cloud-sync history rows, and shared widget behavior + are unchanged. - `connection_runtime/helpers.rs` no longer depends on the connection runtime wildcard import; its GPUI, app, model, and core dependencies are explicit. - `connection_runtime/actions.rs` no longer depends on the connection runtime diff --git a/scripts/check-architecture-boundaries.sh b/scripts/check-architecture-boundaries.sh index 20638f397..8fbc56e23 100755 --- a/scripts/check-architecture-boundaries.sh +++ b/scripts/check-architecture-boundaries.sh @@ -167,6 +167,11 @@ check_no_matches \ crates/nyaterm-desktop/src/features/panels/mod.rs \ crates/nyaterm-desktop/src/features/panels/tab_actions_overlay/mod.rs +check_no_matches \ + "presentation support module entry points must use named re-exports" \ + '^[[:space:]]*pub\(in crate::features\)[[:space:]]+use[[:space:]]+(formatting|view_widgets|labels|ai_history|markdown|chrome|inspector_widgets|stats|rows|icons)::\*;' \ + crates/nyaterm-desktop/src/features + check_no_matches \ "cloud sync HTTP backend helpers must stay out of features/prelude.rs" \ '(^|[,{[:space:]])(NativeAliyunDriveRemote|NativeGoogleDriveRemote|NativeOneDriveRemote|NativeS3Remote|NativeSnippetHttpClient|NativeWebdavRemote|run_github_gist_device_flow)([},[:space:]]|$)' \ @@ -672,6 +677,17 @@ declare -A SUPER_BASELINE=( [crates/nyaterm-desktop/src/features/settings/settings_runtime/recording_transfer.rs]=0 [crates/nyaterm-desktop/src/features/settings/settings_runtime/search_engines.rs]=0 [crates/nyaterm-desktop/src/features/settings/settings_runtime/terminal_remote.rs]=0 + [crates/nyaterm-desktop/src/features/formatting/ai_history.rs]=0 + [crates/nyaterm-desktop/src/features/formatting/labels.rs]=0 + [crates/nyaterm-desktop/src/features/formatting/markdown.rs]=0 + [crates/nyaterm-desktop/src/features/formatting/mod.rs]=0 + [crates/nyaterm-desktop/src/features/icons/aliases.rs]=0 + [crates/nyaterm-desktop/src/features/icons/connection.rs]=0 + [crates/nyaterm-desktop/src/features/icons/file_kind.rs]=0 + [crates/nyaterm-desktop/src/features/icons/mod.rs]=0 + [crates/nyaterm-desktop/src/features/icons/quick.rs]=0 + [crates/nyaterm-desktop/src/features/icons/remote_system.rs]=0 + [crates/nyaterm-desktop/src/features/icons/search.rs]=0 [crates/nyaterm-desktop/src/features/inspector/mod.rs]=0 [crates/nyaterm-desktop/src/features/inspector/ai_ask.rs]=0 [crates/nyaterm-desktop/src/features/inspector/commands.rs]=0 @@ -792,6 +808,13 @@ declare -A SUPER_BASELINE=( [crates/nyaterm-desktop/src/features/tunnels/tunnel_runtime/helpers.rs]=0 [crates/nyaterm-desktop/src/features/tunnels/tunnel_runtime/proxy_editor.rs]=0 [crates/nyaterm-desktop/src/features/tunnels/tunnel_runtime/tunnel_editor.rs]=0 + [crates/nyaterm-desktop/src/features/view_widgets/chrome.rs]=0 + [crates/nyaterm-desktop/src/features/view_widgets/icons.rs]=0 + [crates/nyaterm-desktop/src/features/view_widgets/inspector_widgets.rs]=0 + [crates/nyaterm-desktop/src/features/view_widgets/markdown.rs]=0 + [crates/nyaterm-desktop/src/features/view_widgets/mod.rs]=0 + [crates/nyaterm-desktop/src/features/view_widgets/rows.rs]=0 + [crates/nyaterm-desktop/src/features/view_widgets/stats.rs]=0 ) for file in "${!SUPER_BASELINE[@]}"; do @@ -806,10 +829,13 @@ done < <(rg -n --path-separator / '^[[:space:]]*use super::\*;' \ crates/nyaterm-desktop/src/features/ai \ crates/nyaterm-desktop/src/features/connections \ crates/nyaterm-desktop/src/features/commands \ + crates/nyaterm-desktop/src/features/formatting \ + crates/nyaterm-desktop/src/features/icons \ crates/nyaterm-desktop/src/features/inspector \ crates/nyaterm-desktop/src/features/panels \ crates/nyaterm-desktop/src/features/session \ crates/nyaterm-desktop/src/features/settings \ + crates/nyaterm-desktop/src/features/view_widgets \ crates/nyaterm-desktop/src/features/pages/mod.rs \ crates/nyaterm-desktop/src/features/pages/connections \ crates/nyaterm-desktop/src/features/pages/tunnels \