NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev
Flutter integration for armature: ArmatureApp bootstrap, slot widgets, reactive providers, and a debug overlay.
Last release 5 months ago
29 Apr 2026
Too new to tell
only 1 release windows
Nearly every release is documented
notes for 6 of 6 stable releases
Nothing withdrawn
no release was ever pulled
5 months old
6 releases · first in 2026
One column per month.
> First stable release. Tracks armature 1.0.0; existing widgets and
First stable release. Tracks
armature1.0.0; existing widgets and providers from 0.4.0 are unchanged. New widgets (StoreListener,TaskBuilder) are additive.
StoreListener<S> — side-effect host for a Store<S> that fires
the listener on transitions without rebuilding child. The state
generic infers from the store: Store<S> argument; an optional
listenWhen: (prev, next) => ... predicate filters which transitions
trigger the callback. Use for navigation, snackbars, analytics —
anywhere StoreBuilder would over-rebuild.
StoreListener(
store: context.store<AuthStore>(),
listenWhen: (p, n) => !p.isLoggedIn && n.isLoggedIn,
listener: (ctx, _) => Navigator.of(ctx).pushReplacementNamed('/home'),
child: const LoginForm(),
)
TaskBuilder — reactive four-way switch on Task.state. All
three generics (TParams, TResult, TError) infer from the task
argument; the four branch builders (idle, pending, done,
failed) are required so the compiler enforces exhaustive coverage.
TaskBuilder(
task: store.fetchUser, // Task<int, User, ApiException>
idle: (_) => const _Placeholder(),
pending: (_, userId) => const CircularProgressIndicator.adaptive(),
done: (_, user) => UserCard(user),
failed: (_, e) => ErrorBanner(message: e.message),
)
MultiPortBuilder build hoists — the per-build tracked Set,
_reconcile stale List, and error-reporter closure are now
allocated once in initState and reused, instead of being recreated
on every reactive rebuild.MultiSlot.apply empty-handlers / empty-entries fast paths —
return initialValue directly when the port has no registered
handlers, or when no active feature contributes a descriptor for the
current data payload, instead of allocating an empty entries
list and copying initialValue into a new List<Widget>.package:armature/advanced.dart to
package:armature/framework.dart for Port / PortType. The
framework.dart barrel is the new home for sibling-package
plumbing types.armature: ^1.0.0 (was ^0.4.0).> Tracks the armature 0.4.0 container lifecycle rename. No new
Tracks the
armature0.4.0 container lifecycle rename. No new Flutter-side surface — but consumers that calleddispose()on a container directly must migrate.
ArmatureApp now calls container.stop() instead of
container.dispose() when the widget is disposed. With the new
restart-friendly cycle, the container can be start()-ed again from
user code if the same ArmatureApp is remounted.container_dispose_test.dart removed; the equivalent restart-cycle
coverage now lives in armature's container_test.dart.container.dispose() directly (for example,
when bootstrapping a container outside ArmatureApp) must switch to
container.stop(). See the armature 0.4.0 changelog for the full
rationale.SlotDescriptor, SlotLoaderBuilder, and Renderer.renderLoader
doc-comments now reference FeatureStatus.pending /
FeatureStatus.active / ContainerStatus.starting explicitly instead
of the .pending / .active shorthand.single_slot_provider.dart,
multi_slot_provider.dart, flutter_renderer.dart) cleaned up the
same way.armature: ^0.4.0 — see that package's CHANGELOG for the lifecycle
rename details.armature_reactive: ^1.0.0 (was ^0.1.0) — first stable release;
public API unchanged.Public reset() supersedes in-flight runs (gen token), cancels strategy timers, rejects coalesced callers, clears .once cache. Optional autoReset: dura
Public reset() supersedes in-flight runs (gen token), cancels
strategy timers, rejects coalesced callers, clears .once cache.
Optional autoReset: duration on createTask / createVoidTask
auto-returns state to TaskIdle after TaskDone / TaskFailed.
Refactor: _supersedeInFlight extracted from dispose/reset, doc on
_generation as cross-strategy supersession token. Docs add Picking
TError guidance (Exception / domain / Never / Object) in README +
website + createTask docstring. Example counter gains a
flakyFetch + SnackBar demo. 19 new tests in task_reset_test.dart.
Docs and example refresh. No library code changes.
.queue / asc defaults, package:armature/advanced.dart
barrel, explicit FeatureStatus / ToggleState).example/example.dart switches to the new cleanup.subscribe(...)
sugar from armature 0.3.1.BREAKING CHANGE: internal API only. Feature.internal → Feature.config (immutable config) + container.runtimeOf(feature) (per-container state). Port.ad…
Move mutable feature state (scope API, status store, cleanup bags,
ownActive, toggle, exports cache) out of shared Feature.internal
into a per-container FeatureRuntime owned by AppContainer. Port
handler maps move from Port onto the container.
Fixes a race where two ArmatureApp widgets sharing top-level final
features corrupted each other's state during async dispose/construct.
BREAKING CHANGE: internal API only. Feature.internal →
Feature.config (immutable config) + container.runtimeOf(feature)
(per-container state). Port.addHandler/removeHandler/handlers/ handlerCount/handlerFeatureNames removed — use
container.addPortHandler / container.handlersOf<THandler>(port).
feature.storeOf<T>(container) now takes an explicit container.
User-facing API (createFeature, ArmatureApp, StoreContext.of,
providers, activation helpers) unchanged.
createFeature(...) instances no longer carry mutable runtime state. Scope API, status store, cleanup bags, ownActive, toggle, and bound FeatureParentApi now live in a per-AppContainer FeatureRuntime. Two concurrent or sequentially-remounted containers backed by the same feature list hold independent runtime state.Feature.internal getter replaced by Feature.config (immutable post-cascade); runtime state reached via container.runtimeOf(feature). Port handler maps moved off Port onto AppContainer.handlersOf / addPortHandler / removePortHandler; Port.addHandler / removeHandler / hasHandlerFor / handlerCount / handlerFeatureNames / handlers deleted. Port.check now takes container:. FeatureParentApi is per-container; FeatureHandlerContext / FeatureScopeApi gained an @internal container field. feature.storeOf<T>() now requires an AppContainer argument: feature.storeOf<T>(container).rendererContext global
singleton has been replaced by a per-AppContainer renderer slot,
accessed via the new ContainerRenderer extension
(container.renderer). Two ArmatureApps living sibling-by-sibling
or mounting / unmounting in rapid succession each carry their own
renderer — the previous race where an outgoing widget's async
dispose nulled out the incoming widget's renderer is gone.rendererContext global removed. ArmatureApp.initState and
bootstrap() now call container.setRenderer(...) instead of
assigning the global. Custom renderers and slot implementations read
via container.renderer.initTestRenderer in test_utils.dart now takes an AppContainer:
initTestRenderer(container). pumpFeature installs a
FlutterRenderer lazily on each container, so most widget tests
don't need to call initTestRenderer directly anymore.useSingleSlot / useMultiSlot extensions record the binding into
the feature's config (via the new internal Feature.recordPortBinding
helper) instead of calling port.addHandler. User-facing API is
unchanged.container.renderer.renderSlot(...) instead
of rendererContext.renderer.renderSlot(...). The container is
available at every existing call site — no extra plumbing needed.armature: ^0.3.0 — see that package's CHANGELOG for the full
config/runtime split.BREAKING FEAT (website): add interactive docs and examples site.
Note: This release has breaking changes.
Initial release — Flutter integration for armature:
armature:
ArmatureApp — top-level widget that bootstraps the container and
installs providers. bootstrap(...) remains as the manual
alternative for custom lifecycles.FeatureRoot / createFeatureRoot — mounts a feature as a
top-level root widget via its descriptor (widget: + optional
loader:).SingleSlot, MultiSlot, SingleSwitchSlot,
MultiSwitchSlot. Registration via the typed
feature.useSingleSlot(...) / useMultiSlot(...) extensions —
handlers return Widget? and the framework wraps them into
descriptors.PipeProvider, BehaviorProvider,
SingleSlotProvider, MultiSlotProvider, MultiPortBuilder /
PortReader for multi-port reactive reads.context.store<T>() — one-shot imperative store lookup.StoreBuilder<T> — reactive DI + rebuild on any tracked state
change.StoreSelector<V> — equality-based rebuild on derived values,
for multi-store projections and fine-grained optimisation.StateObserver — raw reactive wrapper for custom builders.Renderer interface with FlutterRenderer
as the default; FlutterRendererOptions.errorBuilder /
loaderBuilder for customising slot error / loading states.FeatureGraphOverlay — interactive feature-graph
canvas with pan / zoom / drag, node detail panel, live store
inspector, minimap, refresh button, gesture hint.package:armature_flutter/test_utils.dart):
initTestRenderer, wrapForTesting, pumpFeature.Your coding agent can read these notes before it upgrades. Set up the MCP server →