# dungngminh/simutil architecture

> Architecture diagram of the GitHub repository dungngminh/simutil, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-16). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/dungngminh/simutil
- Repository: https://github.com/dungngminh/simutil

## Overview

1. **What this repo is**
   - SimUtil is a **cross-platform Dart terminal application** for managing mobile devices from the command line: Android emulators, iOS simulators, and some Android physical-device workflows.
   - The runtime boundary is the local machine; the app acts as an orchestration layer over platform/device tooling rather than hosting network services.

2. **Startup and command-line entry**
   - The executable entrypoint is `bin/simutil.dart`.
   - CLI parsing and command registration live under `lib/cli`, with a command runner (`simutil_command_runner.dart`) and commands such as `simutil` and `version`.
   - This is the thin outer shell that starts the terminal UI app and exposes version/help-style behavior.

3. **Terminal UI layer**
   - The main interactive experience is built in `lib/simutil_app.dart` using **Nocterm**, a Flutter-like terminal UI framework for Dart.
   - Reusable UI pieces are in `lib/components` and include device lists, detail panels, status bars, dialogs, input fields, overlays, and themed styling.
   - The UI is split into feature-oriented dialogs and components rather than a single monolithic screen.

4. **Core domain model**
   - Shared state and data contracts live in `lib/models`.
   - The model set covers devices, device OS/type/state, Android launch options, wireless pairing/connect flows, app settings, and isolate messaging.
   - These models form the boundary between the UI and the platform-specific services.

5. **Device management services**
   - `lib/services/device_service.dart` is the abstraction for device operations.
   - Platform-specific implementations are split into `android_device_service.dart` and `ios_device_service.dart`.
   - This service layer is the main bridge from UI intent (“launch this device”, “shut it down”, “connect wirelessly”) to platform commands.

6. **External command execution boundary**
   - `lib/services/command_exec.dart` centralizes shell/process execution.
   - This is the critical integration point with external tooling such as Android emulator/ADB utilities and iOS simulator tooling.
   - Architecturally, most “real work” is delegated through this boundary, keeping the UI and models mostly tool-agnostic.

7. **Android-specific feature modules**
   - Android tooling is grouped under `lib/plugins/adb_tools`.
   - It includes dialogs for ADB operations, QR pairing, wireless pairing, and connect flows.
   - Logcat support lives under `lib/plugins/logcat`, with its own dialog, filter bar, and helper logic, indicating a dedicated streaming/log-processing subsystem.
   - `lib/plugins/scrcpy` exists as an integration point, but the tree suggests it is currently only a placeholder for that feature area.

8. **Connectivity and discovery**
   - `lib/services/wifi_discovery_service.dart` supports discovering devices on the local network for wireless connection workflows.
   - The pairing/connect models (`wireless_connect_request`, `wireless_pairing_info`, `wifi_pairing_device`, `adb_connect_result`) show that wireless ADB is a first-class flow, not an ad hoc UI action.

9. **Concurrency and background work**
   - `lib/services/isolate_runner.dart` and `lib/models/isolate_message.dart` indicate that longer-running tasks or streaming operations are moved off the main UI thread via isolates.
   - This is likely used for operations such as logcat streaming, device enumeration, and discovery so the terminal UI remains responsive.

10. **Application state and dependency wiring**
   - `lib/services/settings_service.dart` persists app-level preferences using the `app_settings` model.
   - `lib/services/service_locator.dart` wires together shared services, suggesting a lightweight dependency-injection pattern rather than direct construction throughout the UI.
   - This keeps feature modules decoupled from concrete service implementations.

11. **Shared utilities**
   - `lib/utils` contains constants, string/iterable extensions, and version helpers.
   - These are support layers only; they do not own core behavior but reduce duplication across UI and service code.

12. **Build, distribution, and release architecture**
   - The repo is set up for multi-channel distribution: `pub.dev`, Homebrew, and Windows winget, plus binary installers (`install.sh`, `install.ps1`).
   - GitHub Actions workflows handle CI and release publishing, so packaging is part of the project’s architecture, not an afterthought.
   - This matters because the app is meant to be installed as a local CLI tool across macOS, Linux, and Windows.

13. **Overall data flow**
   - User action in the terminal UI → command/UI component → feature dialog or controller → domain model → service layer → external device tooling/processes → result back through models/isolate messages → UI update.
   - The main architectural boundaries are therefore: **UI**, **domain/models**, **device/platform services**, and **external command/tooling integration**.

Main entry points: [`lib/simutil_app.dart`](https://github.com/dungngminh/simutil/blob/main/lib/simutil_app.dart) (Simutil app), [`lib/services/service_locator.dart`](https://github.com/dungngminh/simutil/blob/main/lib/services/service_locator.dart) (Service locator), [`lib/services/device_service.dart`](https://github.com/dungngminh/simutil/blob/main/lib/services/device_service.dart) (Device service), [`lib/services/command_exec.dart`](https://github.com/dungngminh/simutil/blob/main/lib/services/command_exec.dart) (Command exec)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_cli["CLI"]
  node_bin_entry["simutil.dart<br/>entrypoint<br/>[simutil.dart]"]
  node_cli_runner["Command runner<br/>cli runner"]
  node_cli_main["Simutil command<br/>cli command"]
  node_cli_version["Version command<br/>cli command"]
end

subgraph group_ui["Terminal UI"]
  node_app["Simutil app<br/>terminal app<br/>[simutil_app.dart]"]
  node_device_list["Device list<br/>ui component"]
  node_device_panel["Detail panel<br/>ui component"]
  node_dialogs["Dialogs<br/>ui components"]
  node_theme["Theme<br/>ui styling<br/>[simutil_theme.dart]"]
end

subgraph group_domain["Domain"]
  node_device_model["Devices<br/>domain model<br/>[device.dart]"]
  node_wireless_model["Wireless flows<br/>domain model"]
  node_app_settings["App settings<br/>domain model<br/>[app_settings.dart]"]
  node_isolate_msg["Isolate messages<br/>domain model"]
end

subgraph group_services["Services"]
  node_device_service["Device service<br/>service interface"]
  node_android_service["Android service<br/>platform service"]
  node_ios_service["iOS service<br/>platform service"]
  node_command_exec["Command exec<br/>process boundary<br/>[command_exec.dart]"]
  node_wifi_discovery["Wi‑Fi discovery"]
  node_isolate_runner["Isolate runner<br/>concurrency"]
  node_settings_service["Settings service<br/>persistence service"]
  node_service_locator["Service locator<br/>wiring"]
end

subgraph group_plugins["Plugins"]
  node_adb_tools["ADB tools<br/>android plugin"]
  node_logcat["Logcat<br/>streaming plugin<br/>[logcat_dialog.dart]"]
  node_scrcpy["Scrcpy<br/>integration stub<br/>[.gitkeep]"]
end

subgraph group_release["Distribution"]
  node_release["Release flows<br/>build and publish<br/>[release.yaml]"]
end

node_bin_entry -->|"starts"| node_cli_runner
node_cli_runner -->|"registers"| node_cli_main
node_cli_runner -->|"registers"| node_cli_version
node_cli_main -->|"launches"| node_app
node_app -->|"renders"| node_device_list
node_app -->|"renders"| node_device_panel
node_app -->|"uses"| node_dialogs
node_app -->|"styles"| node_theme
node_app -->|"binds"| node_device_model
node_app -->|"orchestrates"| node_device_service
node_device_service -->|"implements"| node_android_service
node_device_service -->|"implements"| node_ios_service
node_android_service -->|"executes"| node_command_exec
node_ios_service -->|"executes"| node_command_exec
node_adb_tools -->|"drives"| node_android_service
node_logcat -->|"streams via"| node_isolate_runner
node_logcat -->|"reads"| node_command_exec
node_wifi_discovery -->|"produces"| node_wireless_model
node_wifi_discovery -->|"runs via"| node_isolate_runner
node_settings_service -->|"persists"| node_app_settings
node_service_locator -->|"wires"| node_device_service
node_service_locator -->|"wires"| node_settings_service
node_service_locator -->|"wires"| node_wifi_discovery
node_service_locator -->|"wires"| node_isolate_runner
node_service_locator -->|"wires"| node_command_exec
node_release -->|"packages"| node_bin_entry

click node_bin_entry "https://github.com/dungngminh/simutil/blob/main/bin/simutil.dart"
click node_cli_runner "https://github.com/dungngminh/simutil/blob/main/lib/cli/simutil_command_runner.dart"
click node_cli_main "https://github.com/dungngminh/simutil/blob/main/lib/cli/commands/simutil_command.dart"
click node_cli_version "https://github.com/dungngminh/simutil/blob/main/lib/cli/commands/version_command.dart"
click node_app "https://github.com/dungngminh/simutil/blob/main/lib/simutil_app.dart"
click node_device_list "https://github.com/dungngminh/simutil/blob/main/lib/components/device_list_component.dart"
click node_device_panel "https://github.com/dungngminh/simutil/blob/main/lib/components/device_detail_panel.dart"
click node_dialogs "https://github.com/dungngminh/simutil/tree/main/lib/components"
click node_theme "https://github.com/dungngminh/simutil/blob/main/lib/components/simutil_theme.dart"
click node_device_model "https://github.com/dungngminh/simutil/blob/main/lib/models/device.dart"
click node_wireless_model "https://github.com/dungngminh/simutil/blob/main/lib/models/wireless_connect_request.dart"
click node_app_settings "https://github.com/dungngminh/simutil/blob/main/lib/models/app_settings.dart"
click node_isolate_msg "https://github.com/dungngminh/simutil/blob/main/lib/models/isolate_message.dart"
click node_device_service "https://github.com/dungngminh/simutil/blob/main/lib/services/device_service.dart"
click node_android_service "https://github.com/dungngminh/simutil/blob/main/lib/services/android_device_service.dart"
click node_ios_service "https://github.com/dungngminh/simutil/blob/main/lib/services/ios_device_service.dart"
click node_command_exec "https://github.com/dungngminh/simutil/blob/main/lib/services/command_exec.dart"
click node_wifi_discovery "https://github.com/dungngminh/simutil/blob/main/lib/services/wifi_discovery_service.dart"
click node_isolate_runner "https://github.com/dungngminh/simutil/blob/main/lib/services/isolate_runner.dart"
click node_settings_service "https://github.com/dungngminh/simutil/blob/main/lib/services/settings_service.dart"
click node_service_locator "https://github.com/dungngminh/simutil/blob/main/lib/services/service_locator.dart"
click node_adb_tools "https://github.com/dungngminh/simutil/blob/main/lib/plugins/adb_tools/adb_tools_dialog.dart"
click node_logcat "https://github.com/dungngminh/simutil/blob/main/lib/plugins/logcat/logcat_dialog.dart"
click node_scrcpy "https://github.com/dungngminh/simutil/blob/main/lib/plugins/scrcpy/.gitkeep"
click node_release "https://github.com/dungngminh/simutil/blob/main/.github/workflows/release.yaml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_bin_entry,node_cli_runner,node_cli_main,node_cli_version toneBlue
class node_app,node_device_list,node_device_panel,node_dialogs,node_theme toneAmber
class node_device_model,node_wireless_model,node_app_settings,node_isolate_msg toneMint
class node_device_service,node_android_service,node_ios_service,node_command_exec,node_wifi_discovery,node_isolate_runner,node_settings_service,node_service_locator toneRose
class node_adb_tools,node_logcat,node_scrcpy toneIndigo
class node_release toneTeal
```

## Components

### CLI

Entry commands and startup shell

- [simutil.dart](https://github.com/dungngminh/simutil/blob/main/bin/simutil.dart): entrypoint · Dart executable entrypoint · `bin/simutil.dart`
- [Command runner](https://github.com/dungngminh/simutil/blob/main/lib/cli/simutil_command_runner.dart): cli runner · Registers commands and dispatches CLI behavior · `lib/cli/simutil_command_runner.dart`
- [Simutil command](https://github.com/dungngminh/simutil/blob/main/lib/cli/commands/simutil_command.dart): cli command · Primary command surface for the terminal app · `lib/cli/commands/simutil_command.dart`
- [Version command](https://github.com/dungngminh/simutil/blob/main/lib/cli/commands/version_command.dart): cli command · Version/help-style command · `lib/cli/commands/version_command.dart`

### Terminal UI

Interactive Nocterm application and components

- [Simutil app](https://github.com/dungngminh/simutil/blob/main/lib/simutil_app.dart): terminal app · Main interactive Nocterm application · `lib/simutil_app.dart`
- [Device list](https://github.com/dungngminh/simutil/blob/main/lib/components/device_list_component.dart): ui component · Primary device browsing view · `lib/components/device_list_component.dart`
- [Detail panel](https://github.com/dungngminh/simutil/blob/main/lib/components/device_detail_panel.dart): ui component · Shows selected device details and actions · `lib/components/device_detail_panel.dart`
- [Dialogs](https://github.com/dungngminh/simutil/tree/main/lib/components): ui components · Reusable dialogs, overlays, inputs, and status UI · `lib/components`
- [Theme](https://github.com/dungngminh/simutil/blob/main/lib/components/simutil_theme.dart): ui styling · Shared terminal styling and icons · `lib/components/simutil_theme.dart`

### Domain

Shared models and state contracts

- [Devices](https://github.com/dungngminh/simutil/blob/main/lib/models/device.dart): domain model · Device identity, type, OS, and state contracts · `lib/models/device.dart`
- [Wireless flows](https://github.com/dungngminh/simutil/blob/main/lib/models/wireless_connect_request.dart): domain model · Pairing and wireless connect request/result models · `lib/models/wireless_connect_request.dart`
- [App settings](https://github.com/dungngminh/simutil/blob/main/lib/models/app_settings.dart): domain model · Persisted user preferences and app configuration · `lib/models/app_settings.dart`
- [Isolate messages](https://github.com/dungngminh/simutil/blob/main/lib/models/isolate_message.dart): domain model · Message contracts for background work · `lib/models/isolate_message.dart`

### Services

Device orchestration, execution, discovery, and settings

- [Device service](https://github.com/dungngminh/simutil/blob/main/lib/services/device_service.dart): service interface · Abstraction for device operations · `lib/services/device_service.dart`
- [Android service](https://github.com/dungngminh/simutil/blob/main/lib/services/android_device_service.dart): platform service · Android device and emulator workflows · `lib/services/android_device_service.dart`
- [iOS service](https://github.com/dungngminh/simutil/blob/main/lib/services/ios_device_service.dart): platform service · iOS simulator workflows · `lib/services/ios_device_service.dart`
- [Command exec](https://github.com/dungngminh/simutil/blob/main/lib/services/command_exec.dart): process boundary · Shell and process execution for external tooling · `lib/services/command_exec.dart`
- [Wi‑Fi discovery](https://github.com/dungngminh/simutil/blob/main/lib/services/wifi_discovery_service.dart): service · Network discovery for wireless connection flows · `lib/services/wifi_discovery_service.dart`
- [Isolate runner](https://github.com/dungngminh/simutil/blob/main/lib/services/isolate_runner.dart): concurrency · Runs long-lived or blocking work off the UI thread · `lib/services/isolate_runner.dart`
- [Settings service](https://github.com/dungngminh/simutil/blob/main/lib/services/settings_service.dart): persistence service · Persists and loads app settings · `lib/services/settings_service.dart`
- [Service locator](https://github.com/dungngminh/simutil/blob/main/lib/services/service_locator.dart): wiring · Central dependency wiring for shared services · `lib/services/service_locator.dart`

### Plugins

Feature modules for Android tooling and log streaming

- [ADB tools](https://github.com/dungngminh/simutil/blob/main/lib/plugins/adb_tools/adb_tools_dialog.dart): android plugin · Android pairing, QR connect, and ADB workflows · `lib/plugins/adb_tools/adb_tools_dialog.dart`
- [Logcat](https://github.com/dungngminh/simutil/blob/main/lib/plugins/logcat/logcat_dialog.dart): streaming plugin · Dedicated log streaming and filtering subsystem · `lib/plugins/logcat/logcat_dialog.dart`
- [Scrcpy](https://github.com/dungngminh/simutil/blob/main/lib/plugins/scrcpy/.gitkeep): integration stub · Placeholder integration point · `lib/plugins/scrcpy/.gitkeep`

### Distribution

Packaging and release automation

- [Release flows](https://github.com/dungngminh/simutil/blob/main/.github/workflows/release.yaml): build and publish · CI and distribution pipelines for package and installer publishing · `.github/workflows/release.yaml`

## Connections

- simutil.dart → Command runner: starts · Entrypoint hands off to CLI parsing and dispatch
- Command runner → Simutil command: registers · Main command surface is registered with the runner
- Command runner → Version command: registers · Version command is exposed through the runner
- Simutil command → Simutil app: launches · CLI command starts the interactive terminal app
- Simutil app → Device list: renders · Main screen presents the device list
- Simutil app → Detail panel: renders · Selected device details flow into the detail panel
- Simutil app → Dialogs: uses · Feature dialogs and overlays drive interactions
- Simutil app → Theme: styles · Shared theme and iconography shape the UI
- Simutil app → Devices: binds · UI reads and updates device state models
- Simutil app → Device service: orchestrates · User intent is translated into device operations
- Device service → Android service: implements · Android-specific device workflows
- Device service → iOS service: implements · iOS-specific simulator workflows
- Android service → Command exec: executes · Android work is delegated to external tools and processes
- iOS service → Command exec: executes · iOS simulator work is delegated to external tools and processes
- ADB tools → Android service: drives · ADB dialogs and pairing flows invoke Android operations
- Logcat → Isolate runner: streams via · Logcat processing is isolated from the UI thread
- Logcat → Command exec: reads · Log streaming depends on external process execution
- Wi‑Fi discovery → Wireless flows: produces · Discovery supports wireless connect and pairing models
- Wi‑Fi discovery → Isolate runner: runs via · Network discovery can be offloaded to background work
- Settings service → App settings: persists · Settings service loads and saves app preferences
- Service locator → Device service: wires · Shared service graph exposes device operations
- Service locator → Settings service: wires · Shared service graph exposes persistence
- Service locator → Wi‑Fi discovery: wires · Shared service graph exposes discovery
- Service locator → Isolate runner: wires · Shared service graph exposes concurrency helpers
- Service locator → Command exec: wires · Shared service graph exposes process execution
- Release flows → simutil.dart: packages · Release automation builds and publishes the CLI tool
