SG CLI
Flutter Architecture Generator by SolGuruz
Scaffold production-ready Flutter apps in seconds โ BLoC, type-safe navigation, state handlers, and 48+ widgets, all wired up from a single command.
โจ What You Get
One sg init sets up the entire Max Architecture โ the same foundation used in SolGuruz production apps:
| Feature | Details | |
|---|---|---|
| ๐งฑ | BLoC State Management | Typed base classes, events, 5 ready-to-use state handlers |
| ๐งญ | Type-Safe Navigation | Go class, route configs, typed arguments โ zero magic strings |
| โก | ViewState Widgets | Auto-handles loading / error / empty / data โ no boilerplate |
| ๐จ | Design System | AppColors (light + dark), AppTextStyles, 48+ production widgets |
| โ๏ธ | Code Generators | Screens, bottom sheets, dialogs, events โ routes wired automatically |
| ๐ | Flavor & Deep Link Setup | Dev / stage / prod in one command |
๐ฆ Installation
dart pub global activate sg_cli
Add the pub cache bin to your PATH (one-time setup):
export PATH="$PATH":"$HOME/.pub-cache/bin"
Verify:
sg help
โก Quick Start
# 1. Go to your Flutter project root
cd my_flutter_app
# 2. Scaffold the entire Max architecture
sg init
# 3. Generate screens, bottom sheets, dialogs
sg create screen login
sg create screen home
sg create bs select_language
sg create dialog confirm_action
# 4. Add BLoC events
sg create event submit_login in login
Routes, BLoC files, state classes, and widget folders โ all generated and wired automatically.
๐ Commands
Project Setup
| Command | What it does |
|---|---|
sg init |
Scaffold the complete Max architecture into your Flutter project |
sg setup_flavors |
Add dev / stage / prod flavors for Android & iOS |
sg setup_deeplink |
Configure per-flavor deep links (Android manifests + iOS entitlements) |
sg setup_firebase |
Automated Firebase setup via FlutterFire CLI |
sg setup_firebase_manual |
Generate Firebase placeholder configs |
Code Generation
| Command | What it does |
|---|---|
sg create screen <name> |
Screen + BLoC (event, state) + route auto-registered |
sg create sub_screen <name> in <parent> |
Sub-screen nested under a parent route |
sg create bs <name> |
Bottom sheet + BLoC + route auto-registered |
sg create dialog <name> |
Dialog + BLoC + route auto-registered |
sg create event <name> in <page> |
Add a BLoC event + handler to an existing screen / bs / dialog |
All names must be
snake_case. All generated code follows Max Architecture conventions.
๐ What Gets Generated
sg create screen profile
lib/presentation/screens/profile/
โโโ logic/
โ โโโ profile_bloc.dart โ BaseBloc with eventListeners()
โ โโโ profile_event.dart โ Abstract event extends BaseEvent
โ โโโ profile_state.dart โ Immutable state with copyWith
โโโ view/
โโโ profile_screen.dart โ StatefulWidget, BLoC via context extension
โโโ widgets/ โ Screen-specific widget files
Auto-updated:
app/app_routes/screen_routes.dartapp/app_routes/_route_names.dart
sg create event load_profile in profile
class LoadProfile extends ProfileEvent {
const LoadProfile();
@override
Map<String, dynamic> getAnalyticParameters() => {};
@override
List<Object?> get props => [];
}
Handler stub registered in profile_bloc.dart automatically.
๐ Architecture Highlights
๐งญ Type-Safe Navigation
// Navigate with typed arguments
Go.to(ProfileRoute(
arguments: ProfileArguments(userId: '42', userName: 'John'),
));
// Open a bottom sheet and await its result
final result = await Go.openBottomSheet<bool, SelectLanguageArguments>(
const SelectLanguageRoute(),
showDragHandle: true,
);
// Clear stack and go to login
Go.replaceAllTo(const LoginRoute());
โก State Handlers + ViewState Widgets
Five handlers cover every data-loading pattern. Pair with the matching widget โ loading, error, empty, and data are handled automatically:
// BLoC โ one handler replaces all manual emit() calls
late final scriptsHandler = PaginatedListHandler<ScriptModel>(
bloc: this,
getViewState: () => state.scripts,
updateViewState: (s) => emit(state.copyWith(scripts: s)),
loadMoreEvent: () => const ScriptsLoadMore(),
repositoryCall: () => ScriptRepository.getScripts(
page: state.scripts.paginationData?.nextPage,
search: state.scripts.searchController?.text,
),
);
// Screen โ auto loading / empty / error / paginate
SliverListStateWidget<ScriptsBloc, ScriptsState, ScriptModel>(
listStateSelector: (s) => s.scripts,
onLoadMore: (_) => bloc.add(const ScriptsLoadMore()),
padding: const EdgeInsets.symmetric(horizontal: kHorizontalPadding),
itemBuilder: (context, script, index) => ScriptCard(script: script),
)
๐งฑ BLoC Pattern
class LoginBloc extends BaseBloc<LoginEvent, LoginState> {
LoginBloc() : super(LoginState.initial());
final emailCtrl = TextFieldController();
final submitCtrl = AppButtonController();
@override
void eventListeners() {
on<SubmitLogin>(_onSubmitLogin);
}
Future<void> _onSubmitLogin(SubmitLogin event, Emitter<LoginState> emit) async {
submitCtrl.startLoading();
final response = await AuthRepository.loginWithEmail(email: emailCtrl.text);
submitCtrl.stopLoading();
if (response.isSuccess) Go.replaceAllTo(const HomeRoute());
}
@override
Future<void> close() {
emailCtrl.dispose();
submitCtrl.dispose();
return super.close();
}
}
๐ท Architecture Versions
| Version | Best For | Includes |
|---|---|---|
| Max โญ | Full production apps | All commands โ init, create, setup_* |
| Bronze | Apps with custom routing | create screen / bs / dialog / event |
| Amber | Role-based basic structure | create page / bs / event |
Version is configured in sg_cli.yaml at your project root after sg init.
๐ Requirements
| Minimum | |
|---|---|
| Dart SDK | ^3.11.0 |
| Flutter SDK | ^3.41.1 |
| Firebase CLI | Only needed for setup_firebase |
| FlutterFire CLI | Only needed for setup_firebase |
๐ Documentation
Full architecture docs, tutorials, and API reference at sgcli.solguruz.com
| Topic | What's covered |
|---|---|
| Architecture Overview | Folder structure, 3-layer design, data flow |
| State Handlers | All 5 handlers โ BasicData, PaginatedList, FullList, and more |
| Navigation | Type-safe routing, route arguments, nested navigation |
| Widget Library | 48+ widgets โ AppButton, OTP, TextFields, ImagePicker, tabs |
| Theming | AppColors (light/dark), AppTextStyles, design system |
| Forms & Validation | Controllers, validators, input formatters |
| Networking | ApiClient, repositories, response pipeline |
| Reactor | Cross-BLoC reactive sync without boilerplate |
| Local Storage | PrefManager, type-safe persistence |
| Environments | Dev / stage / prod config, flavors, deep links |
๐ง Troubleshooting
sg command not found
export PATH="$PATH":"$HOME/.pub-cache/bin"
# Persist: add the above line to ~/.zshrc or ~/.bashrc
Template errors after sg init
The boilerplate is bundled inside the package. Re-activating fixes most path issues:
dart pub global activate sg_cli
setup_firebase fails
npm install -g firebase-tools
dart pub global activate flutterfire_cli
firebase login
๐ข About SolGuruz
Engineering quality mobile and web solutions โ with passion.
๐ License
MIT ยฉ 2025 SolGuruz Private Limited โ see LICENSE for full text.
Made with โค๏ธ by SolGuruz ยท sgcli.solguruz.com
Libraries
- cli
- constants/console_symbols
- constants/constants
- data/global_vars
- models/sg_config
- utils/config_helper
- utils/console_logger
- utils/file_helper
- utils/get_value_in_line
- utils/name_helper
- utils/pubspec_helper
- utils/validate_command
- versions/amber/amber
- versions/amber/commands/init/init_command
- versions/bronze/bronze
- versions/max/max