Generated: 2026-01-08 Updated: 2026-04-15 Flutter: 3.41.4 (via FVM)
Cross-platform desktop terminal aggregator with AI agent integration. Built with Flutter + shadcn_ui, using BLoC/HydratedBloc for state persistence.
flutter_agent_panel/
├── lib/
│ ├── main.dart # Entry: error handling, HydratedStorage init
│ ├── app.dart # Root widget: MultiBlocProvider, theming
│ ├── core/ # Cross-cutting: services, router, l10n, extensions
│ ├── features/ # Feature modules (BLoC pattern)
│ │ ├── home/ # App shell layout
│ │ ├── info/ # About/Help dialogs
│ │ ├── settings/ # App configuration (851 lines)
│ │ ├── terminal/ # PTY management, themes
│ │ └── workspace/ # Multi-workspace organization
│ └── shared/ # Utils, constants, common widgets
├── packages/
│ ├── flutter_pty/ # FFI PTY bindings (ConPTY/POSIX)
│ └── xterm/ # Terminal emulator core (60fps render)
└── assets/ # Images, agent logos
| Task | Location | Notes |
|---|---|---|
| Add new feature | lib/features/{name}/ |
Create bloc/, models/, views/, widgets/ |
| Modify theming | lib/app.dart |
ShadThemeData, colorScheme switching |
| Add localization | lib/core/l10n/ |
ARB files, regenerate with flutter gen-l10n |
| Configure routing | lib/core/router/app_router.dart |
AutoRoute, regenerate with lean_builder |
| Add service | lib/core/services/ |
Singleton pattern, init in main.dart |
| Terminal rendering | packages/xterm/lib/src/ui/ |
Custom RenderBox, pixel-aligned painting |
| PTY native code | packages/flutter_pty/src/ |
C files per platform |
- HydratedBloc for persistent state (workspace, settings)
- Regular Bloc for ephemeral state (terminal instances)
- Event/State in
partfiles:{name}_event.dart,{name}_state.dart - Always use
.copyWith()for immutable updates
- shadcn_ui components: ShadDialog, ShadSelect, ShadInput, ShadTooltip
- Context extensions:
context.theme,context.t(localization) - LucideIcons throughout
- Gap widgets for spacing (not SizedBox)
- Single quotes for strings
- Trailing commas required
- Relative imports within lib/
@pragma('vm:prefer-inline')on hot paths (xterm painter)
| Forbidden | Reason |
|---|---|
| Direct list mutation | Use .copyWith() or create new list |
Heavy logic in build() |
Move to Bloc or extract methods |
| Inline sorting | Delegate to Bloc events |
| Hardcoded strings | Use context.t localized strings |
| Manual mock edits | *.mocks.dart are generated |
flutter_pty_bindings_generated.dart edits |
Auto-generated by ffigen |
| Sub-pixel offsets in painter | Use roundToDouble() for crispness |
| Blocking PTY calls on main isolate | Use dedicated isolates |
# Setup
flutter pub get
dart run lean_builder build # Generate routes (must run after any route/l10n change)
flutter gen-l10n # Generate l10n (rarely needed separately)
# Development
flutter run -d windows
# Build
flutter build windows --release
flutter build macos --release
flutter build linux --release
# Packages (run from package dir for ffigen)
flutter pub run ffigen --config ffigen.yaml # Regenerate PTY bindingslean_builder build → dart format --set-exit-if-changed . → flutter analyze
CI uses --no-fatal-infos for analyze, but strict locally.
No Android/iOS directories - configured for Windows, macOS, Linux only.
This project uses FVM. The Flutter version is pinned in .fvmrc (3.41.4). CI workflows use kuhnroyal/flutter-fvm-config-action to auto-detect and use the correct version.
analysis_options.yaml excludes:
packages/flutter_pty/**packages/xterm/**lib/core/l10n/**.dartlib/core/router/**.gr.dart
Uses Flutter workspace with local packages:
packages/xterm- forked/customized terminal emulatorpackages/flutter_pty- native PTY bindings
settings_dialog.dart(851 lines) - Tab-based settings UIworkspace_drawer.dart(541 lines) - Drag-drop with pin constraintsterminal_bloc.dart(430 lines) - Cross-platform shell handling
Terminal creation handles: PowerShell, pwsh, cmd, WSL, bash, zsh. See TerminalServiceImpl and TerminalBloc._createTerminalNode().
workspace → terminal (TerminalConfig model)
settings → terminal (font/theme models)
terminal → flutter_pty, xterm packages