dusk:install
One-shot bootstrap for fluttersdk_dusk. Runs in two phases, both idempotent:
- Patch
lib/main.dart— inject the imports,WidgetsFlutterBinding.ensureInitialized(), and akDebugMode-gatedDuskPlugin.install()block beforerunApp(. Magic-stack apps additionally wireMagicDuskIntegration.install()afterMagic.init(. - Chain fastcli setup — best-effort
dart run fluttersdk_artisan install(scaffoldsbin/dispatcher.dart+./bin/fsaAOT wrapper) +dart run fluttersdk_artisan plugin:install fluttersdk_dusk(registersDuskArtisanProvider). Both sub-process calls are skipped when their idempotency markers already exist (bin/dispatcher.dartfor the scaffold,.artisan/installed/fluttersdk_dusk.jsonfor the plugin record). Failures are swallowed with a warning; the Phase 1 patch always succeeds on its own, so the consumer can still drive dusk viadart run fluttersdk_duskeven when the chain skipped.
Together, the two phases mean a fresh consumer needs only:
flutter pub add fluttersdk_dusk
dart run fluttersdk_dusk dusk:install
After the second command, ./bin/fsa list surfaces all 32 dusk:* commands and ./bin/fsa mcp:serve exposes the 31 MCP tools.
Table of contents
Synopsis
dart run fluttersdk_dusk dusk:install
dusk:install accepts no positional arguments and no flags. The command reads lib/main.dart and pubspec.yaml from the current working directory and injects the runtime wiring snippets that fit the detected stack.
Arguments
dusk:install has no addOption or addFlag calls in its configure method. The two side-channel inputs are environment-derived:
| Input | Source | Purpose |
|---|---|---|
lib/main.dart path |
DuskInstallCommand.mainDartPathResolver() (defaults to lib/main.dart) |
Target file for snippet injection. Test seam: override the resolver to point at a fixture. |
pubspec.yaml path |
DuskInstallCommand.pubspecPathResolver() (defaults to pubspec.yaml) |
Inspected for magic: and fluttersdk_wind: dependency entries. Drives the conditional wiring decisions described under Anchor modes. |
Both resolvers are public static fields so tests can override per-test without leaking files into the running test process' cwd.
Returns
dusk:install returns an integer exit code via Future:
| Exit code | Meaning |
|---|---|
0 |
Success. lib/main.dart was either updated with the required snippets or already contained them. The command prints a dusk:install complete success line. |
1 |
lib/main.dart not found at the resolved path. The command prints an error advising the operator to run dusk:install from a Flutter project root. |
No structured payload is emitted. Status flows through ArtisanOutput.info / success / error so it surfaces with the same [info] / [ok] / [error] tokens as every other artisan command.
Anchor modes
The injector picks one of two anchor strings depending on what lib/main.dart already contains:
- Magic-stack apps (
lib/main.dartcontainsawait Magic.init():DuskPlugin.install()is wired BEFOREMagic.init(so the driver is live during Magic boot. Whenmagic:is also a pubspec dependency,MagicDuskIntegration.install()is also injected AFTERMagic.init()(the integration queriesMagic.findfor the form and nav enrichers, which only resolves once the container is ready).() - Vanilla apps (no
Magic.initanchor):DuskPlugin.install()is wired immediately beforerunApp(.
When the consumer's pubspec lists fluttersdk_wind: as a top-level dependency, Wind.installDebugResolver() lands inside the same kDebugMode block as DuskPlugin.install(). Wind alpha-10 no longer ships a dusk-specific integration class; dusk reads wind state through the neutral WindDebugRegistry bridge at snap time. The Wind enricher wiring is independent of the Magic detection: a magic-free app with fluttersdk_wind still gets the wind metadata block.
The full sub-step list (from the source docblock):
- Add the two required imports (
kDebugModefrompackage:flutter/foundation.dart; thepackage:fluttersdk_dusk/dusk.dartbarrel). - Inject
WidgetsFlutterBinding.ensureInitialized()(skip when already present) plus thekDebugMode-gated dusk block before the canonical install anchor. - When pubspec has
magic:AND main.dart hasawait Magic.init(, injectMagicDuskIntegration.install()AFTER that call.
Examples
1. Fresh install in a vanilla Flutter app
flutter create my_app
cd my_app
dart run fluttersdk_dusk dusk:install
Expected output (illustrative):
[info] Wiring DuskPlugin into lib/main.dart...
[ok] dusk:install complete. Run `dart run fluttersdk_dusk ` to invoke dusk commands.
Diff against lib/main.dart:
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:fluttersdk_dusk/dusk.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
if (kDebugMode) {
DuskPlugin.install();
}
runApp(const MyApp());
}
2. Re-running on an already-installed project
dart run fluttersdk_dusk dusk:install
The injector early-returns on every duplicate snippet. The output still prints dusk:install complete; the file is left untouched.
3. Magic-stack app with wind enricher
When pubspec lists both magic: and fluttersdk_wind:, the post-install lib/main.dart looks like:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
if (kDebugMode) {
DuskPlugin.install();
Wind.installDebugResolver();
}
await Magic.init(MyApp.new);
if (kDebugMode) {
MagicDuskIntegration.install();
}
}
See also
- Getting Started: Installation: step-by-step walkthrough from
dart pub addto first snapshot. - dusk:doctor: verify the post-install wiring is healthy and the running session can be reached.
- Plugins: Magic integration: full surface of
MagicDuskIntegrationand which enrichers it ships. - Plugins: Wind integration: the six-field
wind:block surfaced through the neutralWindDebugRegistrybridge in wind alpha-10.