magic 0.0.3
magic: ^0.0.3 copied to clipboard
A Laravel-inspired Flutter framework with Eloquent ORM, routing, and MVC architecture.
Changelog #
All notable changes to this project will be documented in this file.
[Unreleased] #
Contributing checklist (before merging into [Unreleased]) #
- ❌ CHANGELOG entry added under the appropriate bucket (BREAKING / Added / Changed / Removed / Fixed / Improvements)
- ❌
doc/updated when the change touches public-facing behavior - ❌
README.mdupdated when the change touches the overview or quick-start - ❌
skills/magic-framework/updated when the change touches APIs the skill documents - ❌
example/updated when the change touches the canonical consumer scaffold - ❌
flutter testgreen;dart analyzeclean;dart formatno diff;dart pub publish --dry-runno blocking errors
0.0.3 - 2026-06-17 #
Stabilization (magic-stabilize-dusk-telescope plan) #
-
BREAKING: the Dusk + Telescope Magic adapters moved out of magic core into the new sibling
magic_devtoolspackage.MagicDuskIntegration(14 enrichers),MagicTelescopeIntegration(5 watchers +MagicHttpFacadeAdapter) and their tests now live inmagic_devtools; magic core no longer depends onfluttersdk_duskorfluttersdk_telescopeat all. The class and function names are unchanged; only the import path moves and ownership shifts to a dedicated dev-tooling package. Consumer migration (pre-1.0 clean break, no shim):// before (interim sub-barrel, never released): import 'package:magic/dusk_integration.dart'; import 'package:magic/telescope_integration.dart'; // after — add magic_devtools as a dev_dependency, then: import 'package:magic_devtools/dusk.dart'; import 'package:magic_devtools/telescope.dart'; // MagicDuskIntegration.install(); / MagicTelescopeIntegration.install();Deletes
lib/src/cli/{dusk,telescope}_integration.dart, thelib/{dusk,telescope}_integration.dartsub-barrels, andtest/cli/{dusk,telescope}_integration_test.dartfrom magic; drops the twofluttersdk_dusk/fluttersdk_telescopedependency lines frompubspec.yaml. -
Granular scaffold + documentation is the default (M1). The E2E-drivability defaults (
processingListenable+MagicBuilder, stableValueKey,semanticLabelon ambiguous interactive widgets) are documented in.claude/rules/testability.mdand reflected in generated view stubs. Opt-in, no runtime behavior break for existing consumers. -
Testability rules formalized (M2).
.claude/rules/testability.mddefines view drivability as the third gate of "done" alongside passing tests and correct appearance, with the three widget-identity rules dusk depends on. -
fluttersdk_artisanconstraint bumped^0.0.7->^0.0.8. Drop-in: magic uses no artisan symbol changed between the two versions.
Fixed (consumer-blocking bugs surfaced by /tmp fresh-app E2E test plan) #
make:*commands now work on consumers that pull magic from pub.dev / path: dependency.MakeControllerCommand,MakeModelCommand, and the other 12make:*commands used to callStubLoader.load('controller')directly, which searches$ARTISAN_STUBS_DIR→$MAGIC_CLI_STUBS_DIR→fluttersdk_artisan-<version>/assets/stubs/. Magic's own stubs live at<magic>/assets/stubs/; neither env var was set in typical environments, and the fluttersdk_artisan pub-cache fallback contained only artisan substrate stubs. The 14 generators now load raw stub content via the newMagicStubLoaderhelper (which resolves<magic>/assets/stubs/<name>.stubfrom the consumer's.dart_tool/package_config.jsonmagic entry) and pass the content throughgetStub()forArtisanGeneratorCommand.buildClassto consume as a literal template. Addslib/src/cli/helpers/magic_stub_loader.dart; toucheslib/src/cli/commands/make_*.dart× 14.magic:installis now self-registering — adds magic to.artisan/plugins.jsonbeforeplugins:refreshruns, soMagicArtisanProviderappears inlib/app/_plugins.g.dartautomatically. Consumers no longer need a separatedart run magic:artisan plugin:install magicstep before invokingmake:controlleretc. Toucheslib/src/cli/commands/magic_install_command.dart(adds_selfRegisterPlugin).plugin:install magicre-invocations no longer corruptlib/config/app.dart. The staticinstall/app_configpublish entry rendered the raw{{ allImports }}/{{ allProviders }}placeholders when invoked outsideMagicInstallCommand.handle(where the fluent override would overwrite with the dynamic providers list). Removedinstall/app_config: lib/config/app.dartfrominstall.yamlpublish:; the fluent override is now the sole writer. Touchesinstall.yaml.assets/lang/en.jsonis now scaffolded on install. Addsinstall/lang_en: assets/lang/en.jsontoinstall.yamlpublish:with a minimal stub coveringcommon.welcome,common.loading, …, and avalidation.*block matching the built-in rule names. Consumers usingLang.trans('common.welcome')now resolve out of the box; previously the lang dir was empty until the operator ranmake:lang. Touchesinstall.yaml, addsassets/stubs/install/lang_en.stub.
Fixed (PR #87 code review) #
- Cache hit/miss detection no longer misclassifies.
CacheManager.get()decided hit-vs-miss withvalue == defaultValue, which dispatched aCacheMisswhen the stored value happened to equal the caller'sdefaultValue, or when a storednullwas read with anulldefault. It now usesdriver().has(key)for presence. Toucheslib/src/cache/cache_manager.dart; adds two regression cases totest/cache/cache_manager_event_dispatch_test.dart. KeyGenerateCommandreuses a singleRandom.secure()instead of constructing one per byte. Toucheslib/src/cli/commands/key_generate_command.dart.- Removed the unused
yaml_editdependency frompubspec.yaml(nolib/,test/, orbin/references), trimming transitive deps and publish surface. - Example app shows a real title.
example/.envAPP_NAMEis now"Magic Example"(was"") andwelcome_view.dartfalls back to a non-emptyapp.name, so the example no longer renders a blank title. Touchesexample/.env,example/lib/resources/views/welcome_view.dart.
Improvements (UX) #
magic:installpost-install message documents the optional Dusk + Telescope setup chain. Removed the obsolete sqlite3.wasm warning (the install command auto-fetches sqlite3.wasm 3.3.1 since the artisan-install-command-magic plan). Added a setup recipe pointing operators at themagic_devtoolsdev_dependency (plusfluttersdk_dusk/fluttersdk_telescope) and thepackage:magic_devtools/{dusk,telescope}.dartadapter imports, so the debug-tooling path is discoverable without consulting the docs. Touchesinstall.yaml(post_install.message).
Changed #
- Documentation: CLAUDE.local.md updated to reflect artisan-based CLI. The stale
magic_clicompanion-project sync protocol (cross-repo stub sync, provider coupling) has been retired. Magic now owns its CLI and generators underlib/src/cli/on thefluttersdk_artisansubstrate. UpdatedCLAUDE.local.mdto document the current architecture (command locations, install manifest, stub loading) and deprecation of the legacy magic_cli sync procedure.
Deferred #
magic:install --with-debug-toolingsingle-command flag that chains the 6-step Dusk + Telescope setup recipe (currently the post_install message documents the recipe; the flag would auto-execute it). Tracking issue: TBD.MainDartSmartMergershould consolidate the 4if (kDebugMode) { ... }blocks thatdusk:install+telescope:installemit into 2 blocks (pre-Magic.init()host plugins + post-Magic.init()Magic adapters). Currently each install command writes its own block, producing four single-statement blocks. Tracking issue: TBD.
Changed (artisan-install-command-magic plan) #
magic:installnow delegates canonical Flutter scaffold to artisan'sinstallcommand in-process. AfterstagedInstaller.commit()returns Success,delegateArtisanInstallinvokesInstallCommand.scaffoldInto(from the artisan public barrel) to writebin/dispatcher.dart+ barrels + pubspec dep + bin/fsa. Gated inside the existingif (result is Success)block so dry-run / Conflict / Error results skip the delegation and atomic-commit semantics are preserved. Magic-specific extras (conditional configs, dynamiclib/config/app.dart,lib/main.dartsmart-merge, sqlite3.wasm) remain magic-side.
Removed (artisan-install-command-magic plan) #
install.yaml11th publish entry (install/consumer_artisan: bin/artisan.dart) dropped. Artisan'sinstallcommand now writes the canonical dispatcher tobin/dispatcher.dart; magic no longer ships a separate consumer wrapper. Magic-managed consumers reach the same canonical state via the delegation flow.
Added (dusk-magic-wind enrichment Wave 3 / Wave 4 wiring) #
MagicHttpFacadeAdapter.pendingCountoverride (Step 3.4 cross-package). Proxies to the file-private_TelescopeNetworkInterceptor._pending.length(null-guarded pre-install, returns 0). Reads the live in-flight FIFO soTelescopeStore.pendingHttpCountcan sum across registered adapters. Powers dusk'sext.dusk.wait_for_network_idleend-to-end.- Magic-side reader wiring for dusk's telescope-backed tools
(Steps 3.4 + 3.5).
MagicTelescopeIntegration.install()now also assigns three function-pointer readers exported frompackage:fluttersdk_dusk/dusk.dart:pendingHttpCountReader = () => TelescopeStore.pendingHttpCountrecentLogsReader = TelescopeStore.recentLogs(...) → dusk envelope(renamesloggerName→logger, ISO-formats timestamps)recentExceptionsReader = TelescopeStore.recentExceptions(...) → dusk envelope(renamesexceptionType→type, truncates stackTrace to first 3 lines asstackHead) The indirection lives on the dusk side; dusk has no hard dep on telescope. Magic is the only crossover point. Dusk hosts that do not shipfluttersdk_telescopeget the default empty-list readers (missing-telescope graceful path).
- New
test/cli/telescope_integration_test.dart(6 cases): pre-install null-guard, post-install zero, in-flight count, FIFO decrement, post-uninstall null-guard, end-to-end viaTelescopeStore.pendingHttpCount.
Changed (BREAKING for magic_cli legacy users; non-breaking via legacy fallback) #
-
magic:installrewrite to PluginInstaller DSL + install.yaml manifest. The command extendsArtisanInstallCommand(from fluttersdk_artisan ^1.0.0-alpha.1+) and delegates the install.yaml-expressible 60% toManifestInstaller. The conditional 40% (per-flag config emission, dynamiclib/main.dartconfigFactories list, dynamiclib/config/app.dartprovider list, app name extraction from pubspec.yaml) lives in a fluent override hook onManifestInstaller.prepare(). Existing--without-*flags map 1:1 to install.yamlprompts:(bool type, default false).Backward compat:
dart run :artisan magic:installcontinues to work via legacy fallback; the new canonical workflow isdart run :artisan plugin:install magic(auto-detects install.yaml, routes through ManifestInstaller in one step). -
REVERTED: First install on a fresh
flutter createapp NO LONGER requires--force.MagicInstallCommand._resolveMainDartStrategycallsMainDartScaffoldDetector.isFlutterCreateScaffoldBEFORE the ConflictDetector path; when the existinglib/main.dartmatches the flutter create scaffold heuristic,scaffoldDetected=trueflows intoPluginInstaller.commit(force: true)and bypasses the unmanaged-file check silently. Operators now rundart run magic:artisan magic:installon a freshflutter createapp without any flag; customizedlib/main.dartstill requires--forceor--preserveexplicitly. (CHANGELOG entry from an earlier alpha was stale; the scaffold detector landed before alpha-15 but the entry was not removed.) -
sqlite3.wasmauto-download wired intomagic:install. When the database feature is enabled (no--without-databaseflag) and the run is not a dry-run,MagicInstallCommandnow fetches the matchingsqlite3.wasmfromsimolus3/sqlite3.dart(pinned to 3.3.1) and writes it toweb/sqlite3.wasmafter the install commits. Closes the white-screen /WebAssembly TypeErrorfailure mode that hit fresh Flutter web targets on first run.
✨ New Features #
-
Dusk enricher expansion (7 new enrichers + 1 extension):
magicControllerFlagsEnricher- captures FutureOr status, loading/success/error flags fromMagicStateMixinmagicRouteParamsEnricher- emits route parameters (path params + query string)magicFormErrorsEnricher(extension) - now quotes per-field error messages to preserve whitespacemagicEchoConnectionEnricher- reports broadcast connection state (connecting/connected/disconnected/reconnecting)magicGateResultsAllEnricher- emits last N gate check results (ability: allowed/denied) from MRU cachemagicRecentHttpEnricher- emits last 5 HTTP requests (method, URL, status, elapsed time)magicRecentLogsEnricher- emits last 5 log entries (level, message, timestamp)magicRecentExceptionsEnricher- emits last 5 exceptions (type, message, stack trace truncated to 500 chars)
All new enrichers guard
kDebugModeand handle missing dependencies gracefully (telescope-not-installed returns null buffer). Registered byMagicDuskIntegration.install(). Combined with existing 7 enrichers (magicControllerState,magicFormErrors,magicGateResult,magicMiddleware,magicAuthUser,magicFormField,magicRoute), magic-side surface now totals 14 enrichers. Ships in coordinated bump with fluttersdk_dusk 1.0.0-alpha.3+. -
Dusk integration: 5 new snapshot enrichers (
magicControllerState,magicFormErrors,magicGateResult,magicMiddleware,magicAuthUser) registered byMagicDuskIntegration.install()for richer LLM-agent E2E context. Combined with the 2 alpha-1 enrichers (magicFormField,magicRoute) this brings the magic-side surface to 7 enrichers; with Wind's 6-fieldWindClassNameEnricherthe total enricher surface is 8. Ships in coordinated bump with fluttersdk_dusk 1.0.0-alpha.2 (seereferences/fluttersdk_dusk/CHANGELOG.mdfor the matching dusk-side contract additions: 7 new handlers, 10 new MCP descriptors, 8 new CLI commands, actionability gate,dusk_findLocator pattern, Chrome reaper,dusk:doctor). Requires fluttersdk_dusk ^1.0.0-alpha.2 — theDuskSnapshotEnrichertypedef is frozen across both repos for the alpha-2 cycle. -
Cache events:
CacheHit,CacheMiss,CachePut,CacheForget,CacheFlushevent classes added underlib/src/cache/events/cache_events.dartand exported frompackage:magic/magic.dart.CacheManager.get/put/forget/flushnow dispatch the matching event throughEventDispatcher.instanceafter the underlying store operation completes. Enablesfluttersdk_telescope'sMagicCacheWatcher(and any user-defined listener) to observe the full cache lifecycle. -
Test coverage: new
MagicInstallCommandexercised by 27 tests using InstallContext.test + InMemoryFs + FakePromptDriver + FakeStubDriver injection; one test per--without-Xflag plus first-install--force- app name extraction edge cases. Coverage: 76.5% (defensive error paths not covered; accepted per Risks Accepted in the migration plan).
🔧 Improvements #
- Routing:
MagicRouter.currentRoutepublic getter for the currently-resolved RouteDefinition. - Auth:
GateManager.lastResult(ability)accessor backed by an MRU cache (64 entries) of the most recent gate-check outcome per ability.
✨ New Features #
- Eloquent:
Model.fillnow accepts astrictflag. Whentrue, any non-fillable key throwsMassAssignmentExceptioninstead of being silently dropped. Pair with validated request payloads to catch schema drift at the boundary. (#69) - Validation:
FormRequest— Laravel-style request object that collapses authorize → prepare → validate into a single class. ThrowsAuthorizationExceptionon denied access andValidationExceptionwith a field-keyed error map on rule failure. Pairs withModel.fill(validated, strict: true). (#66) - HTTP:
MagicController.authorize(ability, [arguments]), a Laravel-style controller helper that delegates toGate.allows()and throwsAuthorizationExceptionon denial. Avoids hand-rolling gate checks in every action. (#72) - Auth:
Gate.allowsAny(abilities, [arguments])andGate.allowsAll(abilities, [arguments]), short-circuiting sugar for checking multiple abilities at once. (#72) - Routing:
MagicRoute.resource(name, controller, {only, except})auto-wires up to four canonical routes (index, create, show, edit) to a controller that mixes inResourceController. Controllers declare supported methods viaresourceMethods;only/exceptnarrow the set further. Each route gets an auto-assigned{slug}.{method}name and title. (#67) - Validation:
AsyncRulecontract plusUnique(endpoint, field: ...)rule, an async uniqueness check with per-instance debounce (coalesces rapid calls) and a pluggable.via()resolver. Network errors log and pass so they never block submission.Validator.validateAsync()runs async rules after sync rules; sync failures short-circuit per field. (#68) - Session: Add
Sessionfacade with Laravel-style flash data —Session.flash(data),Session.flashErrors(errors),Session.old(field, [fallback]),Session.error(field),Session.errors(field),Session.hasError(field),Session.hasFlash,Session.tick(). Two-bucket store promotes flashed data exactly one navigation hop so forms can repopulate after a failed submit. Top-level helpersold()anderror()mirror Laravel's Blade API - UI:
MagicFormData.validate()automatically flashes form data on validation failure — downstream views can repopulate viaold('field')without manual wiring - Validation:
In<T>rule accepts a primitive whitelist (strings, ints, etc.) andInList<T extends Enum>validates enum-backed fields, accepting either the enum instance or a wire string.InListsupportscaseInsensitive:and an optionalwire:mapper for snake_case or custom representations. Both emit the sharedvalidation.inmessage with a comma-joined:valuesparameter. (#81)
1.0.0-alpha.13 - 2026-04-16 #
✨ New Features #
- Routing: Add
currentPathgetter toMagicRouter— returns the current route path without query string, complementing the existingcurrentLocationproperty
🐛 Bug Fixes #
- Routing: Use
GoRouter.pop()instead ofNavigator.pop()inback()— syncs router state and preserves custom page transitions on reverse animation. AddStateErrorguard when router is not initialized, consistent withto()andreplace()
🔧 Improvements #
- Skill: Optimize
magic-frameworkskill for Claude Code progressive disclosure — split frontmatter, extract templates to references, compress sections (669 → 416 lines). Add version frontmatter and source-to-skill mapping in release command - Deps: Bump magic version constraint in example app
1.0.0-alpha.12 - 2026-04-09 #
✨ New Features #
- Broadcasting: Client-side activity monitor — detects silent connection loss using Pusher protocol
activity_timeoutandpusher:ping/pusher:pong. Automatically reconnects when the server stops responding - Broadcasting: Random jitter (up to 30%) on reconnection backoff delay — prevents thundering herd when many clients reconnect simultaneously after a server restart
- Broadcasting: Configurable connection establishment timeout (default 15s) — prevents indefinite hang when server doesn't complete the Pusher handshake. Automatically triggers reconnect on timeout
1.0.0-alpha.11 - 2026-04-07 #
🐛 Bug Fixes #
- Routing: Fix intermittent page title loss on web — Flutter's
Titlewidget was overwriting TitleManager's route-level title ondidChangeDependencies()rebuilds. UseonGenerateTitleto keep both in sync
⚠️ Breaking Changes #
- file_picker: Upgrade from
^10.3.10to^11.0.2— migrates to static API (FilePicker.platformremoved). Consumers usingFilePicker.platformdirectly (viamagic.dartre-export) must switch to static calls (FilePicker.pickFiles(),FilePicker.getDirectoryPath(),FilePicker.saveFile()). Includes Android path traversal security fix (CWE-22) and WASM web support
1.0.0-alpha.10 - 2026-04-07 #
✨ New Features #
- Routing: Route-level page title management with
TitleManagersingleton. Per-route titles viaRouteDefinition.title(), automatic suffix pattern viaMagicApplication(titleSuffix:), declarativeMagicTitlewidget for data-dependent titles, and imperativeMagicRoute.setTitle()/MagicRoute.currentTitleAPI. Title resolution: MagicTitle > setTitle > RouteDefinition.title > MagicApplication.title. (#49)
🔧 Improvements #
- Dependencies: Bump
magic_clito^0.0.1-alpha.6(scaffold templates now include.title()andtitleSuffix)
1.0.0-alpha.9 - 2026-04-07 #
🐛 Bug Fixes #
- Broadcasting: Auth failures in private/presence channels now surface via
Log.error()and interceptoronError()chain instead of being silently swallowed. Reconnect resubscribes all channels withawait—onReconnectstream emits only after completion. Per-channel error handling ensures one auth failure does not block other channels. (#45) - Database:
sqlite3.wasmnow loads via absolute URI (/sqlite3.wasm) instead of relative — fixes 404s on deep routes when using path URL strategy. (#46)
1.0.0-alpha.8 - 2026-04-07 #
✨ Features #
- feat: config-driven path URL strategy for Flutter web (#40)
1.0.0-alpha.7 - 2026-04-06 #
✨ Features #
- Broadcasting:
Echofacade,BroadcastManager,ReverbBroadcastDriver(Pusher-compatible WebSocket with reconnection, dedup, heartbeat),NullBroadcastDriver,BroadcastInterceptorpipeline,FakeBroadcastManager,BroadcastServiceProvider. Laravel Echo equivalent for real-time channels. (#38) - Router Observers:
MagicRouter.instance.addObserver()enables NavigatorObserver integration for analytics/monitoring (Sentry, Firebase Analytics, custom observers). Observers are passed to GoRouter automatically. (#34) - Network Driver Plugin Hook:
DioNetworkDriver.configureDriver()exposes the underlying Dio instance for SDK integrations (sentry_dio, certificate pinning, custom adapters). (#35) - Custom Log Drivers:
LogManager.extend()enables custom LoggerDriver registration (Sentry, file, Slack). Config-driven resolution with built-in override support. (#36)
1.0.0-alpha.6 - 2026-04-05 #
✨ Features #
- Http Faking:
Http.fake()enables Laravel-style HTTP faking for testing. Swap the real network driver with aFakeNetworkDriverthat records requests and returns stubbed responses. Supports URL pattern stubs, callback stubs, and assertion methods (assertSent,assertNotSent,assertNothingSent,assertSentCount). (#18) - Facade Faking:
Auth.fake(),Cache.fake(),Vault.fake(),Log.fake()— Laravel-style facade faking for testing. Swap real service implementations with in-memory fakes that record operations and expose assertion helpers. (#19) - Fetch Helpers:
fetchList()/fetchOne()onMagicStateMixin— auto state management for HTTP fetches with defensive type guards against malformed responses (#20) - MagicTest:
MagicTest.init()/MagicTest.boot()— standardized test bootstrap helper,package:magic/testing.dartbarrel export (#21)
🐛 Bug Fixes #
- Log.channel(): Now returns
LoggerDrivervia_manager.driver(name)instead ofLogManager, enablingLog.channel('slack').error(...)as documented (#27) - Http.response() null data: Sentinel pattern allows
Http.response(null, 204)for No Content stubs whileHttp.response()still returns mutable empty map (#26) - URL pattern escaping:
FakeNetworkDriverstub patterns now escape regex metacharacters (.,?,+) viaRegExp.escape()— only*is treated as wildcard (#26) - fetchList/fetchOne defensive guards: Type-check
response.dataasMapbefore indexing, filter non-Mapelements in lists viawhereType<Map>(), guardfetchOnedata cast (#28)
1.0.0-alpha.5 - 2026-03-29 #
🐛 Bug Fixes #
- Route Back Navigation:
MagicRoute.back()now works aftergo()-based navigation (cross-shell). Maintains lightweight history stack with automatic fallback. Optionalfallbackparameter for explicit control. (#11)
1.0.0-alpha.4 - 2026-03-29 #
🔧 Improvements #
- Localization Hot Restart: Translation JSON changes now reflect on hot restart during development. Uses fetch with cache-busting on web and best-effort disk reads on desktop, bypassing Flutter's asset bundle cache. Zero impact on release builds.
1.0.0-alpha.3 - 2026-03-24 #
1.0.0-alpha.2 - 2026-03-24 #
⚠️ Breaking Changes #
- Pub.dev Migration: Replaced git submodule path dependencies with pub.dev hosted packages (
fluttersdk_wind: ^1.0.0-alpha.4,magic_cli: ^0.0.1-alpha.3). Removedplugins/directory entirely. - SDK Bump: Dart
>=3.11.0 <4.0.0, Flutter>=3.41.0(previously Dart >=3.4.0, Flutter >=3.22.0)
✨ New Features #
- Launch Facade: URL, email, phone, and SMS launching via
url_launcherwithLaunch.url(),Launch.email(),Launch.phone(),Launch.sms() - Form Processing:
process(),isProcessing, andprocessingListenableonMagicFormDatafor form-scoped loading state - Reactive Auth State:
stateNotifieron Guard contract and BaseGuard for reactive auth state UI - Query Parameters:
Request.query(),Request.queryAll,MagicRouter.queryParameter()for URL query parameter access - Localization Interceptor: Automatic
Accept-LanguageandX-Timezoneheaders on HTTP requests - Theme Persistence: Auto-persist dark/light theme preference via Vault in
MagicApplication - Validation Helpers:
clearErrors()andclearFieldError()onValidatesRequestsmixin - Route Names: Route name registration on
RouteDefinition
🐛 Bug Fixes #
- Auth Config: Default config now properly wrapped under
'auth'key - Session Restore: Guards against missing
userFactory— gracefully skips instead of throwing - Barrel Export:
FileStoreexported from barrel file - Package Name: Renamed internal references from
fluttersdk_magictomagic
🔧 Improvements #
- Dependency Upgrades: go_router ^17.1.0, sqlite3 ^3.2.0, share_plus ^12.0.1, file_picker ^10.3.10, flutter_lints ^6.0.0, and more
- CLI Docs: Rewrote Magic CLI documentation with all 16 commands and
dart run magic:magicsyntax - Wind UI Docs: Moved to wind.fluttersdk.com, removed local copy
- Example App: Rebuilt with fresh
flutter createandmagic install - CI Pipeline: Upgraded GitHub Actions, added validate gate to publish workflow
- Claude Code: Added path-scoped
.claude/rules/for 8 domains, auto-format and auto-analyze hooks
1.0.0-alpha.1 - 2026-02-05 #
✨ Core Features #
- Laravel-inspired MVC architecture
- Eloquent-style ORM with relationships
- GoRouter-based routing with middleware support
- Service Provider pattern
- Facade pattern for global access
- Policy-based authorization
📦 Package Structure #
- Complete model system with HasTimestamps, InteractsWithPersistence
- HTTP client with interceptors
- Form validation system
- Event/Listener system
🔧 Developer Experience #
- Magic CLI integration
- Hot reload support
- AI agent documentation