NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #4395 most downloaded on pub.dev
Flutter CLI — scaffold Clean Architecture projects with Riverpod or flutter_bloc, FVM and your own conventions.
Last release 3 days ago
02 Oct 2026
Ships on a steady schedule
a new release about every 9 days
Nearly every release is documented
notes for 59 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
6 months old
211 releases · first in 2026
One column per month.
### Features - fcm token
### Features - app toast adjustment
### Features - new widgets
Firebase Auth is now a backend choice, not just a provider. Selecting it with the auth feature generates that feature against Firebase instead of REST
authStateChanges(). Same layers and provider names, no
token storage, and Dio is no longer pulled in for it.moarch create feature follows the project's backend: in a Firestore project
the datasource holds _firestore instead of _dio, with
fetchAll/fetchOne/watchAll/create/save/delete over one collection
and a String document id. With both backends installed, the layer checklist
asks which one the feature talks to.AppException maps the Firebase failures an app actually hits: a
fromFirebaseAuthError factory for the auth codes (invalid-credential,
email-already-in-use, weak-password, requires-recent-login,
too-many-requests…) and the Firestore codes (permission-denied,
unavailable…) in fromFirebaseError. New auth and cancelled types, plus
AppException.cancelled() for a dismissed sign-in sheet.core/network/safe_firebase_call.dart — the Firebase counterpart of
safeApiCall, for one-off calls and for streams.docs/FIREBASE_SETUP.md covering the work that lives outside Dart:
flutterfire configure, enabling the sign-in providers, the Android
SHA-1/SHA-256 fingerprints, the iOS GIDClientID and REVERSED_CLIENT_ID URL
scheme, the web client id, and a starting set of Firestore rules.init writes the two iOS Google sign-in keys into Info.plist, taking the
real values from GoogleService-Info.plist when it is already there and
leaving documented placeholders when it isn't. Existing URL types are kept.main.dart now calls Firebase.initializeApp() for Firestore and Firebase
Auth, not only for Crashlytics — a project with either selected used to throw
"No Firebase App '[DEFAULT]' has been created" on its first provider read.firebase_core or
google_sign_in, no Firebase.initializeApp() in main.dart, a missing
google-services.json / GoogleService-Info.plist, and Info.plist still
carrying the placeholder Google client ids — which --fix fills in from
GoogleService-Info.plist.app async view supports stream and future
`moarch update` now refreshes everything the CLI generates, not just the widget kit. The gap it closed for widgets was the same gap core/, config/, th
moarch update now refreshes everything the CLI generates, not just the
widget kit. The gap it closed for widgets was the same gap core/,
config/, the auth feature, the docs and the workflows had all along: a
project scaffolded two versions ago still carries the old
validation_service.dart, and nothing told you which improvements you were
missing or which changes were your own.
moarch update validation,
moarch update extensions, moarch update theme, moarch update logger.
With no arguments the whole project is considered, exactly as before.widgets, core,
network, security, services, config, auth, docs, workflows,
project, ios. They combine freely —
moarch update security docs extensions.moarch update --list prints every name and group with the file it maps
to, so the slugs don't have to be guessed.app_logger.dart keeps its Crashlytics branch,
main.dart keeps the router, localization and notification services the
project actually has, app_exception.dart keeps its Dio and Firebase
mappings, and build_ipa.yml keeps its Firebase steps. The options are
read back off the generated files and pubspec.yaml — the record that
stays true as the project is edited.init is not missing, so naming it does nothing rather than generating
it. moarch update biometric in a project without biometrics is a no-op.--force.moarch init now records every file it writes in .moarch.yaml, where it
previously recorded only the widgets. That record is the whole basis for
telling an untouched generated file from one you edited — without it the rest
of the scaffold could only ever be reported as needs review.
moarch update lists them as needing review even where they
are untouched. Refreshing or confirming them re-records them, and
subsequent runs are exact. That is the safe direction: nothing is
overwritten on the strength of a guess..fvmrc and flutter_native_splash.yaml are generated from DevTemplates
rather than from literals inside the init command, so what init writes and
what update compares against cannot drift apart.AppAudioPlayer (moarch create widget audio-player) — an audio player over just_audio that a screen configures rather than wires. It owns the AudioPlay
AppAudioPlayer (moarch create widget audio-player) — an audio player over
just_audio that a screen configures
rather than wires. It owns the AudioPlayer, loads the source and disposes
both. One AppAudioSource covers url, asset and file.
showControls, showSkip, showProgress, allowScrub,
showTimes, showRemaining and showSpeed are independent, and
AppAudioPlayerStyle.compact is the one-row arrangement.onCompleted fires once per
play-through rather than on every frame the player sits in completed.AppDragSection (moarch create widget drag-section) — a section whose
children drag into a new order, vertical or horizontal, with no dependency.
AppDragSection.reorder does the remove-and-insert.AppDragSize.small/medium/large off a
shared AppDragSizes, or an exact extent — and whether it can be moved.onReorder arrives already corrected for the ReorderableListView
off-by-one and for any pinned item in the way.AppDragTrigger.handle puts a grip on the trailing
edge instead.AppTable (moarch create widget table) — rows and columns sized for a
phone, with no dependency.
width) or flexible (flex), and a flexible one never
squeezes below its minWidth. Past the point where the minimums no longer
fit, the table pans sideways rather than crushing the columns.AppTableColumn.numeric right-aligns and switches on tabular figures.onTap, selected and a colour of their own; striped,
showRowDividers, showColumnDividers, showBorder and density decide
the rest. Cells are strings, or widgets for a chip or an avatar.AppSingleScrollView or a ListView.AppCountryPicker (moarch create widget country-picker) — the 238-country
AppCountry table as a field of its own, validating like the rest of the
family, or as AppCountryPicker.show(context) from anywhere that is not a
form.
AppCountry rather than a code, since the caller
usually wants the dial code or the flag too. display picks what the closed
field reads as, and countries narrows the list.AppPhoneInput carried its
own SearchPickerSheet setup — the flag leading each row, the calling code
trailing it, the ranked search that makes PT find Portugal rather than the
first name containing those letters. That configuration now lives in
AppCountryPicker.show, and the phone field opens it, so a standalone country
field and a phone prefix cannot drift apart. phone-input gains
country-picker as a dependency; the search sheet still arrives with it.AppAudioPlayer (moarch create widget audio-player) — an audio player over just_audio that a screen configures rather than wires. It owns the AudioPlay
AppAudioPlayer (moarch create widget audio-player) — an audio player over
just_audio that a screen configures
rather than wires. It owns the AudioPlayer, loads the source and disposes
both. One AppAudioSource covers url, asset and file.
showControls, showSkip, showProgress, allowScrub,
showTimes, showRemaining and showSpeed are independent, and
AppAudioPlayerStyle.compact is the one-row arrangement.onCompleted fires once per
play-through rather than on every frame the player sits in completed.AppDragSection (moarch create widget drag-section) — a section whose
children drag into a new order, vertical or horizontal, with no dependency.
AppDragSection.reorder does the remove-and-insert.AppDragSize.small/medium/large off a
shared AppDragSizes, or an exact extent — and whether it can be moved.onReorder arrives already corrected for the ReorderableListView
off-by-one and for any pinned item in the way.AppDragTrigger.handle puts a grip on the trailing
edge instead.AppTable (moarch create widget table) — rows and columns sized for a
phone, with no dependency.
width) or flexible (flex), and a flexible one never
squeezes below its minWidth. Past the point where the minimums no longer
fit, the table pans sideways rather than crushing the columns.AppTableColumn.numeric right-aligns and switches on tabular figures.onTap, selected and a colour of their own; striped,
showRowDividers, showColumnDividers, showBorder and density decide
the rest. Cells are strings, or widgets for a chip or an avatar.AppSingleScrollView or a ListView.AppCountryPicker (moarch create widget country-picker) — the 238-country
AppCountry table as a field of its own, validating like the rest of the
family, or as AppCountryPicker.show(context) from anywhere that is not a
form.
AppCountry rather than a code, since the caller
usually wants the dial code or the flag too. display picks what the closed
field reads as, and countries narrows the list.AppPhoneInput carried its
own SearchPickerSheet setup — the flag leading each row, the calling code
trailing it, the ranked search that makes PT find Portugal rather than the
first name containing those letters. That configuration now lives in
AppCountryPicker.show, and the phone field opens it, so a standalone country
field and a phone prefix cannot drift apart. phone-input gains
country-picker as a dependency; the search sheet still arrives with it.AppCalendar (moarch create widget calendar) — the inline month grid, for when the month itself is the content rather than one answer in a form. AppDat
AppCalendar (moarch create widget calendar) — the inline month grid, for
when the month itself is the content rather than one answer in a form.
AppDateInput still opens the platform picker; this is its sibling for
agendas, booking screens and streaks. A wrapper over
table_calendar that keeps its
parameters out of your screens: colors come from AppInputVariant like the
rest of the family, and the package is added to pubspec.yaml for you.
events is re-keyed to the day each entry falls on. Two DateTimes in
one day are not equal, which is the usual reason a marker never appears —
so you can pass the instants your data already carries, and two
appointments at 09:00 and 14:00 count as two dots on one day rather than
missing the grid.onMonthChanged reports the month's own bounds, not the six weeks drawn
around it — the range to fetch events for. For the two-week and week
formats it reports their own span.canChangeFormat offers the month/2-week/week toggle, and only then is a
vertical swipe live; without it a swipe means one thing.onSelected makes it a read-only display, and selectableDay greys out
the days that refuse a tap.lib/shared/widgets/calendar/ folder rather than
alongside the fields.AppActionSheet (moarch create widget action-sheet) — the sheet behind a
three-dot button or a long press. Material rows on Android and the iOS
grouped cards elsewhere, off the same platform split AppDateInput uses for
its pickers; either shape can be forced.
show<T> hands back what was picked and null
when it was dismissed — one honest "the user backed out" branch.onTap runs after the sheet has closed, rather than while it
is closing, where a handler that pushes a route fights the navigator for
it.AppSheetAction.destructive draws in the theme's error color. It confirms
nothing on its own — pair it with AppConfirmDialog when the answer should
be deliberate.
AppDialogs and AppBottomModals, so it costs the project no GoRouter.moarch create model --empty generated a factory that could not compile.
It patches <model>_entity.dart, whose class is <Model>Entity, but named the
factory after the model alone — factory LoginResponse.empty() => LoginResponse(...) inside class LoginResponseEntity. The guard that was
meant to stop a second run looked for that same wrong name, so it never
matched and every re-run stacked another broken factory into the file..empty()
and from copyWith. The type was matched with a character class holding
neither a comma nor a space, so Map<String, dynamic> meta; was not a field
as far as the parser was concerned — and the factory it built came out missing
a required argument. Types are now read up to the last identifier on the line
and then validated, which also ends the false positives that class allowed:
return value; in a method body was being read as a field named value of
type return, and String get title; as a field named title.AddressEntity's fields turned up in UserEntity's copyWith. It now scopes
to the named class's body — and so does the injection: create entity-copys
appended copyWith and the == / hashCode pair at the file's last closing
brace, landing them on whichever class was written last, after stripping the
existing equality members from every class in the file.create empty-factories reported replacements it had not made. Its
pattern only matches an arrow-bodied .empty(), so a hand-written block-bodied
one fell through replaceFirst unchanged while the log claimed it had been
replaced. It now leaves that factory alone and says so, and a factory already
matching what would be written is reported as skipped — which is what the
Skipped : line in the summary always claimed to count and never did.### Features - logger update
### Features - btn fix
### Features - bottom nav upgrade
AppAsyncView (moarch create widget async-view, generated by init) — takes one AsyncValue and draws the four states it can be in: a shimmered shape whi
AppAsyncView (moarch create widget async-view, generated by init) — takes
one AsyncValue and draws the four states it can be in: a shimmered shape
while the first load runs, ErrorView with a retry, EmptyView when the
screen says its data counts as empty, and your body when there is something to
show. A reload over existing data leaves that data on screen rather than
replacing a list mid-read with a spinner, and an error carrying no message of
its own shows no detail instead of a stringified exception.ref.listenAction(...) (moarch create widget action-listener, generated by
init) — surfaces the one-shot error / success fields a generated state
already carries as an AppToast. Pass onError / onSuccess to navigate or
log instead; providing one replaces the toast for that outcome rather than
adding to it, and a single action only ever reports one of the two.moarch create feature used
to write a .when(...) mapping by hand and leave // SHOW UI ERROR and
// SHOW UI SUCCESS as comments in every feature. It now wires the two
widgets up, passes its own body as the skeleton shape, and offers the retry
ErrorView draws a button for. It also writes both widgets if the project
predates them, so the view it generates always compiles.AppMultiSelectInput (moarch create widget multi-select) —
AppDropdownInput's plural: the same id/label entity list, any number
selected, ticked in the search sheet with a per-row checkbox and a Done
button. Shows its picks as removable chips, as labels, or as "3 selected";
enforces required, minSelected and maxSelected, and stops the unticked
rows at the ceiling rather than letting the form refuse the pick afterwards.SearchPickerSheet.showMulti(...) — the multi-select half of the sheet the
dropdown and the country picker already open. It works on its own copy of the
selection, so a dismissed sheet changes nothing and an empty result is a
deliberate "none of them".AppDateRangeInput (moarch create widget date-range-input) — a read-only
field holding a start and an end date, with a maxDays rule the picker itself
cannot express. It holds a DateTimeRange rather than the text of one.AppFilePickerField (moarch create widget file-input) — an attachment
field: an area that opens whichever picker the app already uses, and a row per
file with a thumbnail, a readable size and a remove button. It imports no
picker package, so it costs the project no dependency it had not already
chosen.AppRating (moarch create widget rating) — stars both ways round: tappable
with onChanged, a read-only score without it. Halves come from tapping the
left half of a star, and a display-only rating stays out of Form.validate().AppTabs / AppTabBar (moarch create widget tabs) — AppTabs owns the
controller and puts the views under the bar, replacing it when the tab count
changes; AppTabBar is the PreferredSizeWidget half that drops into
AppAppBar's bottom slot. Underline or pill indicator.AppDrawer (moarch create widget drawer) — the side menu, reading
AppBottomNav's destination list, with header and footer slots. It closes
itself after a pick, and does nothing when the same widget is pinned beside
the content instead.AppNavRail and AppAdaptiveNav (moarch create widget nav-rail) — the
vertical navigation a tablet shows instead of a bottom bar, and the scaffold
that picks between them off the 600dp short-side breakpoint. All three nav
widgets read one AppNavDestination list.AppFab (moarch create widget fab) — the screen's floating action,
circular or extended off one parameter, wearing AppButtonVariant /
AppButtonType rather than a vocabulary of its own. isLoading swaps the
icon for a spinner without resizing the button, and heroTag is exposed for
the two-FABs-on-one-screen case.AppTimeline (moarch create widget timeline) — a vertical sequence of
events joined by a connector, with done/current/pending/failed nodes.
AppTimeline.entryBuilder hands you one row for a lazy list.AppCarousel (moarch create widget carousel) — swipeable pages with
stretching dots, optional peek and auto-advance. The timer stops for good on
the first swipe and never starts when the platform asks for reduced motion;
AppCarouselDots is usable on its own.moarch init never wrote its own lib/main.dart. flutter create leaves
one behind and generated files are never clobbered, so on the documented quick
start (flutter create → moarch init) the counter demo survived and the
scaffold's main.dart — the one that installs ProviderScope and initialises
the selected services — was silently skipped. Every scaffolded app was missing
its provider root. The counter demo is now replaced, matched on the two
private names only that template declares; a main.dart you wrote is still left
alone, and init says so instead of passing over it in silence. The counter
widget_test.dart that pumped it is replaced on the same terms, so
flutter test passes on a fresh project.file_picker resolved to 3.0.4 (2021) whenever the media service was
selected, and 3.0.4 predates AGP's namespace requirement — so the Android
build failed with "Namespace not specified" before the app could run. The
entry was unversioned, and pub is free to resolve backwards: file_picker
11 wants win32 ^5, flutter_secure_storage_windows wants win32 ^6, and
walking file_picker back to 3.0.4 settled that Windows-only conflict. It now
carries a ^11.0.0 floor, and MediaService calls the static
FilePicker.pickFiles that version moved to.?header), which need the project's
pubspec to ask for Dart 3.8+ — not merely a recent SDK to be installed — so
they failed to compile in a project scaffolded a while ago. Rewritten to
constructs with no language-version floor, and a test now fails if a template
reaches for one again.AppToast was redrawn. It was a grey surfaceContainerHighest bar with a
4px accent stripe and an icon beside it — a Material 2 snackbar with a
decoration. It is now a card: a surface tinted 7% with the status color, a
status-colored outline, a soft shadow, and the icon in a tonal chip matching
AppLeadingIcon's. The outline is what the old one could not have — a
SnackBar takes a color and a shape but not a border — so the toast now draws
its own card inside a transparent, unelevated SnackBar.
It also gains a title over the detail line, an optional close button, a
warning / info helper to go with success / error, AppToast.dismiss,
a 480px ceiling so it stays a card rather than a banner on a tablet, and
sideways swipe-to-dismiss. In dark themes it now sits on
surfaceContainerHighest — an overlay has to be lighter than the page it
covers, and the old bar was darker than the content behind it.AppButton's hint moved inside the button, centered under the label, in the
button's own foreground color; the button grows to fit it. It used to be a
left-aligned line floating above the button, which read as a caption for
whatever was above it rather than as part of the action.AppPhoneInput and AppAsyncView — the
phone field has been in the kit since 2.4.0 without a preview, and the async
view's four states are steppable in it. A new test fails if a widget joins the
catalog without either a preview section or an explicit, reasoned exemption,
so the screen can no longer fall behind the kit unnoticed.moarch create feature records what it writes into shared/widgets/ in
.moarch.yaml, so moarch update can tell those files apart from ones you
have since edited.AppAsyncView (moarch create widget async-view, generated by init) — takes one AsyncValue and draws the four states it can be in: a shimmered shape whi
AppAsyncView (moarch create widget async-view, generated by init) — takes
one AsyncValue and draws the four states it can be in: a shimmered shape
while the first load runs, ErrorView with a retry, EmptyView when the
screen says its data counts as empty, and your body when there is something to
show. A reload over existing data leaves that data on screen rather than
replacing a list mid-read with a spinner, and an error carrying no message of
its own shows no detail instead of a stringified exception.ref.listenAction(...) (moarch create widget action-listener, generated by
init) — surfaces the one-shot error / success fields a generated state
already carries as an AppToast. Pass onError / onSuccess to navigate or
log instead; providing one replaces the toast for that outcome rather than
adding to it, and a single action only ever reports one of the two.moarch create feature used
to write a .when(...) mapping by hand and leave // SHOW UI ERROR and
// SHOW UI SUCCESS as comments in every feature. It now wires the two
widgets up, passes its own body as the skeleton shape, and offers the retry
ErrorView draws a button for. It also writes both widgets if the project
predates them, so the view it generates always compiles.AppMultiSelectInput (moarch create widget multi-select) —
AppDropdownInput's plural: the same id/label entity list, any number
selected, ticked in the search sheet with a per-row checkbox and a Done
button. Shows its picks as removable chips, as labels, or as "3 selected";
enforces required, minSelected and maxSelected, and stops the unticked
rows at the ceiling rather than letting the form refuse the pick afterwards.SearchPickerSheet.showMulti(...) — the multi-select half of the sheet the
dropdown and the country picker already open. It works on its own copy of the
selection, so a dismissed sheet changes nothing and an empty result is a
deliberate "none of them".AppDateRangeInput (moarch create widget date-range-input) — a read-only
field holding a start and an end date, with a maxDays rule the picker itself
cannot express. It holds a DateTimeRange rather than the text of one.AppFilePickerField (moarch create widget file-input) — an attachment
field: an area that opens whichever picker the app already uses, and a row per
file with a thumbnail, a readable size and a remove button. It imports no
picker package, so it costs the project no dependency it had not already
chosen.AppRating (moarch create widget rating) — stars both ways round: tappable
with onChanged, a read-only score without it. Halves come from tapping the
left half of a star, and a display-only rating stays out of Form.validate().AppTabs / AppTabBar (moarch create widget tabs) — AppTabs owns the
controller and puts the views under the bar, replacing it when the tab count
changes; AppTabBar is the PreferredSizeWidget half that drops into
AppAppBar's bottom slot. Underline or pill indicator.AppDrawer (moarch create widget drawer) — the side menu, reading
AppBottomNav's destination list, with header and footer slots. It closes
itself after a pick, and does nothing when the same widget is pinned beside
the content instead.AppNavRail and AppAdaptiveNav (moarch create widget nav-rail) — the
vertical navigation a tablet shows instead of a bottom bar, and the scaffold
that picks between them off the 600dp short-side breakpoint. All three nav
widgets read one AppNavDestination list.AppFab (moarch create widget fab) — the screen's floating action,
circular or extended off one parameter, wearing AppButtonVariant /
AppButtonType rather than a vocabulary of its own. isLoading swaps the
icon for a spinner without resizing the button, and heroTag is exposed for
the two-FABs-on-one-screen case.AppTimeline (moarch create widget timeline) — a vertical sequence of
events joined by a connector, with done/current/pending/failed nodes.
AppTimeline.entryBuilder hands you one row for a lazy list.AppCarousel (moarch create widget carousel) — swipeable pages with
stretching dots, optional peek and auto-advance. The timer stops for good on
the first swipe and never starts when the platform asks for reduced motion;
AppCarouselDots is usable on its own.AppPhoneInput and AppAsyncView — the
phone field has been in the kit since 2.4.0 without a preview, and the async
view's four states are steppable in it. A new test fails if a widget joins the
catalog without either a preview section or an explicit, reasoned exemption,
so the screen can no longer fall behind the kit unnoticed.moarch create feature records what it writes into shared/widgets/ in
.moarch.yaml, so moarch update can tell those files apart from ones you
have since edited.AppPhoneInput (moarch create widget phone-input) — a phone field that masks what is typed for the country it is set to, with a searchable country pick
AppPhoneInput (moarch create widget phone-input) — a phone field that
masks what is typed for the country it is set to, with a searchable country
picker in its prefix. The field holds only the national number, so the
calling code cannot be typed twice or deleted; read the joined-up value from
AppPhoneNumber.e164. Changing country re-masks the existing digits rather
than clearing them.AppCountry (moarch create widget country) — a table of 238 countries with
ISO code, calling code and every mask their numbering plan allows. Plans with
more than one shape are kept as a list, so the mask widens as the number grows
(Hungary 8–9 digits, Germany 10–13), and validation holds a number to those
exact lengths instead of a 7-to-15 range. Flags are derived from the ISO code,
so no assets ship with it.SearchPickerSheet (moarch create widget search-sheet) — a bottom sheet
that picks one row out of a long list, with a search field above it. Opens
scrolled to the current selection.AppDropdownInput — swaps the menu for that sheet once the list passes
AppInputConfig.searchableThreshold (30), which searchable: true/false
overrules per field. Both forms now validate: required: true is enforced by
Form.validate() rather than only marking the label, and validator /
autovalidateMode work as they do on AppInput. Also gains onSelected
(the picked entity, not just its id), onCleared (which puts a clear button
in the field), and the sheet's leadingOf, trailingLabelOf, filter and
emptyLabel.moarch update — refreshes generated UI-kit widgets against the current
templates. Files you never touched are refreshed automatically; files you
edited are listed, diffed and left alone unless you pass --force..moarch.yaml — a manifest written by init and create widget recording
the moarch version, the selected stack and a hash of every generated file.
It is what lets update tell an untouched file from an edited one.moarch doctor --fix — applies the fixes that don't need a decision.AppDateInput / AppTimeInput showed nothing without a caller-supplied
controller: every value, initialValue and each picked one alike, was written
only to widget.controller?.text. They now own a controller when none is
passed (and dispose it), so the simplest possible usage displays its value.
A controller that already holds text is no longer overwritten by
initialValue either — the caller's value wins, as it does on AppInput.required: true on AppDateInput and AppTimeInput only drew an asterisk;
Form.validate() passed an empty field. Both now validate, and take a
validator / autovalidateMode like the rest of the family.AppLoadingActionOverlay started its message timers only on a false-to-true
change, so a screen that mounted with a request already in flight showed a
bare spinner forever. They now start in initState too.AppSegmented and AppChoiceChip drew their selected foreground in
colorScheme.surface, which is only the right answer in a light theme. Both
now use the new AppInputStyle.onAccentOf, which AppCheckbox and
AppSwitch share.Selection controls validate. AppCheckboxLabel(required: true) is the
"accept the terms" checkbox a Form can enforce, and
AppRadioGroup(required: true) refuses to validate until one option is
chosen. Both render the error under the control through the new
SelectionFormField, which is exposed for wrapping any control of your own.
AppSegmented and AppRadioGroup assert that the current selection is
actually one of the options, instead of silently rendering with nothing
highlighted.
AppCheckboxLabel, AppRadioGroup, AppSegmented and AppChoiceChip all
take a null callback to disable themselves, matching AppCheckbox,
AppSwitch, AppSlider and AppStepper. AppDateInput and AppTimeInput
gain enabled alongside their existing readOnly.
AppStepper's − and + carry tooltips and semantics, and meet the 48px
minimum tap target.
moarch doctor now checks what the scaffold actually depends on: whether
build_runner has generated app_env.g.dart, whether both localization
approaches ended up installed, whether every generated widget's
dependencies and pub packages are present, and whether router-dependent
widgets have a router. Findings carry hints, and say which are fixable.
AppPhoneInput (moarch create widget phone-input) — a phone field that masks what is typed for the country it is set to, with a searchable country pick
AppPhoneInput (moarch create widget phone-input) — a phone field that
masks what is typed for the country it is set to, with a searchable country
picker in its prefix. The field holds only the national number, so the
calling code cannot be typed twice or deleted; read the joined-up value from
AppPhoneNumber.e164. Changing country re-masks the existing digits rather
than clearing them.AppCountry (moarch create widget country) — a table of 238 countries with
ISO code, calling code and every mask their numbering plan allows. Plans with
more than one shape are kept as a list, so the mask widens as the number grows
(Hungary 8–9 digits, Germany 10–13), and validation holds a number to those
exact lengths instead of a 7-to-15 range. Flags are derived from the ISO code,
so no assets ship with it.SearchPickerSheet (moarch create widget search-sheet) — a bottom sheet
that picks one row out of a long list, with a search field above it. Opens
scrolled to the current selection.AppDropdownInput — swaps the menu for that sheet once the list passes
AppInputConfig.searchableThreshold (30), which searchable: true/false
overrules per field. Both forms now validate: required: true is enforced by
Form.validate() rather than only marking the label, and validator /
autovalidateMode work as they do on AppInput. Also gains onSelected
(the picked entity, not just its id), onCleared (which puts a clear button
in the field), and the sheet's leadingOf, trailingLabelOf, filter and
emptyLabel.moarch update — refreshes generated UI-kit widgets against the current
templates. Files you never touched are refreshed automatically; files you
edited are listed, diffed and left alone unless you pass --force..moarch.yaml — a manifest written by init and create widget recording
the moarch version, the selected stack and a hash of every generated file.
It is what lets update tell an untouched file from an edited one.moarch doctor --fix — applies the fixes that don't need a decision.AppDateInput / AppTimeInput showed nothing without a caller-supplied
controller: every value, initialValue and each picked one alike, was written
only to widget.controller?.text. They now own a controller when none is
passed (and dispose it), so the simplest possible usage displays its value.
A controller that already holds text is no longer overwritten by
initialValue either — the caller's value wins, as it does on AppInput.required: true on AppDateInput and AppTimeInput only drew an asterisk;
Form.validate() passed an empty field. Both now validate, and take a
validator / autovalidateMode like the rest of the family.AppLoadingActionOverlay started its message timers only on a false-to-true
change, so a screen that mounted with a request already in flight showed a
bare spinner forever. They now start in initState too.AppSegmented and AppChoiceChip drew their selected foreground in
colorScheme.surface, which is only the right answer in a light theme. Both
now use the new AppInputStyle.onAccentOf, which AppCheckbox and
AppSwitch share.Selection controls validate. AppCheckboxLabel(required: true) is the
"accept the terms" checkbox a Form can enforce, and
AppRadioGroup(required: true) refuses to validate until one option is
chosen. Both render the error under the control through the new
SelectionFormField, which is exposed for wrapping any control of your own.
AppSegmented and AppRadioGroup assert that the current selection is
actually one of the options, instead of silently rendering with nothing
highlighted.
AppCheckboxLabel, AppRadioGroup, AppSegmented and AppChoiceChip all
take a null callback to disable themselves, matching AppCheckbox,
AppSwitch, AppSlider and AppStepper. AppDateInput and AppTimeInput
gain enabled alongside their existing readOnly.
AppStepper's − and + carry tooltips and semantics, and meet the 48px
minimum tap target.
moarch doctor now checks what the scaffold actually depends on: whether
build_runner has generated app_env.g.dart, whether both localization
approaches ended up installed, whether every generated widget's
dependencies and pub packages are present, and whether router-dependent
widgets have a router. Findings carry hints, and say which are fixable.
### Features - widget adjustments
### Features - input config
input formatters, extensions, validation service refactor
added return on listen if loading
added return on listen if loading
### Features - widget catalog adjustment
### Features - widget catalog
UI kit, UX improvements, app theme improvements
### Features - biometric service
### Features - checkbox, confirmDialog
### Features - button style
### Features - override in entity for ==
### Features - input size and textAlign
### Features - input type and variant
notifications tap handling reaches flutter
### Features - copy with for entitys
### Features - added splash for loading
### Features - added flags for datasource
deps for gradle and other fixes
### Features - Podfile
easy_localization option (mutually exclusive with flutter_localizations)
easy_localization option (mutually exclusive with flutter_localizations)
### Fixes - firebase notifications
### Fixes - notifier action
### Fixes - ACESSABILITY FIXES
### Fixes - WORFLOW ADJUSTMENTS
### Fixes - WORFLOW ADJUSTMENT
### Fixes - ADJUSTMENTS
### Fixes - APP IMAGE ADJUSTMENT
### Fixes - ADJUSTMENTS AND BUG FIXES
### Fixes - FIXES
### Fixes - Deploy workflow fix
### Fixes - Router fixes
### Fixes - Parent Provider
Found by actually running moarch init --all + moarch create feature --all against a real flutter create project and checking flutter pub get / flutter
Found by actually running moarch init --all + moarch create feature --all against a real flutter create project and checking flutter pub get / flutter analyze — several of these meant the documented quick-start flow didn't compile out of the box.
PubspecUtils._ensureSection corrupted pubspec.yaml. It misread the nested sdk: flutter line under flutter: (present in every flutter create project) as the end of the dependencies: section, so all new dependencies were inserted in the wrong place and produced a duplicate YAML key that made flutter pub get fail outright.app_router.dart referenced an undefined authNotifierProvider and AppRoutes.login (which is commented out by default) — a fresh moarch init --all project never compiled. The auth-guard redirect is now documented as an opt-in commented example instead of active code.dio_client.dart referenced AppEnv.prodBaseUrl / AppEnv.devBaseUrl, which don't exist on the generated AppEnv (only baseUrl does).safe_api_call.dart had a stray ~ character right after the opening string literal, which was a syntax error.connectivity_service.dart imported a garbled path (core/utils/appappLogger.iger.dart) and called an undefined top-level log() instead of appLogger.media_service.dart called FilePicker.pickFiles(...) statically; pickFiles is an instance method on FilePicker.platform.get_<name>.dart) imported a core/usecases/usecase.dart base class that is never generated anywhere, and its import path to repository_impl.dart had one extra ../. Use cases are now self-contained (no missing base class) with corrected import depth.getAll() method that the generated use case called against it.<name>_notifier.dart) only imported the repository provider when "Use Cases" was not selected, so authRepositoryProvider was undefined whenever use cases were included (the notifier's _repo getter needs it either way).<name>_remote_datasource.dart called safeApiCall without importing the file that defines it.create feature <name> with the "Local/Cache Datasource" layer selected wrote the connectivity service to the wrong path and passed the wrong variable name into the generated datasource (swapped arguments).AppImage widget had a syntax error (?.isValidUrl != null with no receiver).AppAvatar / AppImage widgets checked a method tear-off instead of calling isValidUrl(), so an invalid URL was never actually detected.dart analyze, dart format --set-exit-if-changed, dart test, dart pub publish --dry-run) on push/PR to main.moarch doctor command to sanity-check an existing scaffolded project.--dry-run flag on moarch init to preview generated files without writing them.--verbose flag to print stack traces on unexpected errors.q) in the interactive checklist prompt.AppTheme.dark) instead of an empty stub, with matching dark color tokens in AppConstants.flutter_native_splash.yaml.init and create feature/create model now roll back files they created if scaffolding fails partway through, instead of leaving the target project in a half-generated state. init also restores the original pubspec.yaml on failure.lib/src/version.dart) instead of being hardcoded in runner.dart.test/test_helper.dart references mocktail, which isn't declared as a dependency, so it doesn't compile as-is. Left untouched since testing scaffolding is handled by the separate mogen_unit_tests/mogen_integration_tests packages.### UPDATE - FIXES
### UPDATE - ERROR MANAGEMENT
### UPDATE - FIXED GO ROUTER
### UPDATE - ADJUSTMENTS
### UPDATE - NEW WORKFLOWS
### UPDATE - REDIRECT IN GO ROUTER
### UPDATE - NEW FEATURES
### UPDATE - FIXED WORKFLOW
### UPDATE - FIXED EMPTY GENERATION
Your coding agent can read these notes before it upgrades. Set up the MCP server →