CLI Commands
On this page
Introduction#
Magic Starter provides five CLI commands that manage the full lifecycle of the plugin inside a host Magic application, from initial scaffolding through configuration, diagnostics, customization, and removal. The commands surface through the host app's dowel dispatcher (run them as dart run magic:dowel starter:<command>): each extends DowelCommand (install extends DowelInstallCommand), declares a signature DSL string for its arguments and flags, and implements async handle(DowelContext ctx) for the execution logic.
Every command resolves the host project root via FileHelper.findProjectRoot() and validates that the target is a Magic project before proceeding.
Install Command#
dart run magic_starter install
The installer is a multi-step scaffolding command that sets up Magic Starter in a host application. It validates the host project, prompts for feature selection, generates files from stubs, and injects registrations into existing config files.
What It Creates#
The installer generates the following files from stub templates:
| File | Purpose |
|---|---|
lib/config/magic_starter.dart |
Feature toggle configuration with selected features enabled |
lib/app/middleware/ensure_authenticated.dart |
Auth guard middleware |
lib/app/middleware/redirect_if_authenticated.dart |
Guest redirect middleware |
lib/app/models/user.dart |
User model with Authenticatable implementation |
lib/app/models/team.dart |
Team model (only when teams feature is enabled) |
lib/app/providers/app_service_provider.dart |
Service provider with facade setup |
lib/resources/views/dashboard_view.dart |
Dashboard view scaffold |
lib/routes/app_routes.dart |
App routes file with starter route registrations |
assets/lang/en.json |
Translation strings |
What It Injects#
Beyond creating new files, the installer modifies existing host files:
lib/config/app.dart— AddsMagicStarterServiceProviderto the providers list and its importlib/main.dart— AddsmagicStarterConfigfactory to the config factories list and its importlib/app/kernel.dart— RegistersEnsureAuthenticatedandRedirectIfAuthenticatedmiddleware aliaseslib/app/providers/route_service_provider.dart— Adds starter route registration calls (registerMagicStarterAuthRoutes, etc.)pubspec.yaml— Ensuresassets/lang/is listed in the assets section
// Injected into lib/config/app.dart
MagicStarterServiceProvider(),
// Injected into lib/main.dart
() => magicStarterConfig,
Flags#
| Flag | Description |
|---|---|
--force, -f |
Overwrite existing generated files |
--non-interactive |
Skip interactive prompts, use defaults or --features |
--features |
Comma-separated feature keys for non-interactive mode |
# Interactive installation (prompts for each feature)
dart run magic_starter install
# Non-interactive with specific features
dart run magic_starter install --non-interactive --features teams,notifications,registration
# Force overwrite existing files
dart run magic_starter install --force
Configure Command#
dart run magic_starter configure
Updates individual feature flags in lib/config/magic_starter.dart without modifying any other file. All I/O is delegated through MagicStarterConfigHelper.
Show Current Config#
dart run magic_starter configure --show
Displays a formatted table of all feature toggles and their current status:
Current Magic Starter Feature Configuration:
Feature Status
teams enabled
social_login disabled
two_factor disabled
notifications enabled
...
Toggle Features#
Each feature has a boolean flag that can be enabled or disabled:
# Enable teams and notifications
dart run magic_starter configure --teams --notifications
# Disable social login
dart run magic_starter configure --no-social-login
# Mix enable and disable
dart run magic_starter configure --teams --no-social-login --notifications
Available feature flags:
| CLI Flag | Config Key |
|---|---|
--teams |
teams |
--social-login |
social_login |
--two-factor |
two_factor |
--sessions |
sessions |
--phone-otp |
phone_otp |
--newsletter |
newsletter |
--notifications |
notifications |
--email-verification |
email_verification |
Non-Interactive Mode#
The configure command is non-interactive by design — it operates entirely through CLI flags. This makes it suitable for CI pipelines and automation scripts.
Doctor Command#
dart run magic_starter doctor
Runs a series of independent health checks to verify that Magic Starter was installed correctly. Each check reports pass or fail, and the command exits with code 0 (all pass) or code 1 (any failure).
Health Checks#
| Check | What It Verifies |
|---|---|
| Magic Framework | lib/config/app.dart exists |
| Starter Config | lib/config/magic_starter.dart exists |
| Provider | MagicStarterServiceProvider registered in app.dart |
| Config Factory | magicStarterConfig wired in main.dart |
| Middleware | EnsureAuthenticated registered in kernel.dart |
| Routes | registerMagicStarterAuthRoutes called in route_service_provider.dart |
| Facade | MagicStarter.useNavigation configured in app_service_provider.dart |
| Translations | assets/lang/en.json exists |
Magic Starter — Doctor Report
==================================================
Magic Framework: ✓
Starter Config: ✓
Provider: ✓
Config Factory: ✓
Middleware: ✓
Routes: ✓
Facade: ✗
Translations: ✓
Missing Requirements:
✗ MagicStarter facade not configured in app_service_provider.dart
1 check(s) failed. Run `dart run magic_starter install` to fix.
Verbose Mode#
dart run magic_starter doctor --verbose
Shows the file path inspected for each check and the specific string searched for:
Provider: ✓
File: lib/config/app.dart
Contains: MagicStarterServiceProvider
Publish Command#
dart run magic_starter publish
Copies plugin source files into the host application for customization — the Magic Starter equivalent of Laravel's vendor:publish. Published files can be edited freely; the view registry will pick up your custom versions when you re-register them.
Publish Tags#
# Publish everything
dart run magic_starter publish
# Publish only views
dart run magic_starter publish --tag views
# Publish with force overwrite
dart run magic_starter publish --force
| Tag | What It Publishes |
|---|---|
config |
lib/config/magic_starter.dart |
views |
All view files to lib/resources/views/starter/ |
middleware |
Auth middleware files to lib/app/middleware/ |
lang |
Translation file to assets/lang/en.json |
all (default) |
All of the above |
Uninstall Command#
dart run magic_starter uninstall
Performs a safe reverse of the install command. It removes generated files and cleans up injected lines from host config files while keeping user code intact.
What it removes:
lib/config/magic_starter.dartmagic_starterdependency frompubspec.yamlMagicStarterServiceProviderimport/registration fromlib/config/app.dartmagicStarterConfigimport/factory fromlib/main.dart- Middleware aliases/imports from
lib/app/kernel.dart - Route imports/registrations from
route_service_provider.dart
# Skip confirmation prompt
dart run magic_starter uninstall --force
Each removal step is wrapped in error handling — already-clean projects and partial installations will not crash the command. After removal, dart format . is run automatically.
Stub Templates#
All generated files are built from stub templates in the assets/stubs/install/ directory:
| Stub | Output |
|---|---|
magic_starter_config.stub |
lib/config/magic_starter.dart |
ensure_authenticated.stub |
lib/app/middleware/ensure_authenticated.dart |
redirect_if_authenticated.stub |
lib/app/middleware/redirect_if_authenticated.dart |
user.stub |
lib/app/models/user.dart |
team.stub |
lib/app/models/team.dart |
app_service_provider.stub |
lib/app/providers/app_service_provider.dart |
dashboard_view.stub |
lib/resources/views/dashboard_view.dart |
app_routes.stub |
lib/routes/app_routes.dart |
en.stub |
assets/lang/en.json |
Stub paths are resolved relative to the plugin package at runtime. The installer searches multiple paths with fallback via getStubSearchPaths():
List<String> getStubSearchPaths() {
return [
_resolvePluginStubsDir(), // Package URI resolution
'${Directory.current.path}/assets/stubs', // Local fallback
];
}
Testing CLI Commands#
All CLI commands expose overridable methods for testability. Override these to isolate commands from the real filesystem:
class TestableInstallCommand extends MagicStarterInstallCommand {
final String _testRoot;
TestableInstallCommand(this._testRoot);
@override
String getProjectRoot() => _testRoot;
@override
List<String> getStubSearchPaths() => [
'$_testRoot/stubs',
];
@override
Future<ProcessResult> runDartFormat(String rootPath) async {
return ProcessResult(0, 0, '', ''); // No-op in tests
}
}
Key overridable methods across commands:
| Method | Commands | Purpose |
|---|---|---|
getProjectRoot() |
All | Redirect to temp directory |
getStubSearchPaths() |
Install | Point to test stub fixtures |
runDartFormat() |
Install, Uninstall | Skip formatting in tests |
runNotificationInstaller() |
Install | Skip notification package setup |
getPluginSourceDir() |
Publish | Point to test plugin source |
Related Links: