From 6900f62aedfacb7aff299dd158e3c0dd08c2a2f5 Mon Sep 17 00:00:00 2001 From: Anilcan Cakir Date: Fri, 11 Sep 2026 02:47:38 +0300 Subject: [PATCH 1/2] docs(skill): follow magic_starter off the alpha rail magic_starter's next release is 0.0.27 rather than 0.0.1-alpha.27, so the reference stamp moves with it and the release markers inside the file read 0.0.27 where they described that release. Its magic_notifications requirement moves to ^0.3.0, the floor the starter release carries. The notification section gains the five notifications.* keys the mounted screens read and no package supplies: bulk_title, bulk_description, delete, delete_failed and channel_sms. An adopter upgrading with a hand-written catalogue sees each rendered as its own key, and this file is the only agent-facing document for that package because .pubignore keeps its CLAUDE.md out of the published archive. SKILL.md's version moves to 0.1.17 because reference content moved. --- CHANGELOG.md | 4 ++++ skills/magic-framework/SKILL.md | 4 ++-- skills/magic-framework/references/plugin-starter.md | 10 +++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 477a8608..94e48a9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Improvements + +- **`plugin-starter.md` follows `magic_starter` off the alpha rail.** That package's next release is `0.0.27` rather than `0.0.1-alpha.27`, so the reference stamp moves with it and the release markers inside the file now read `0.0.27` where they described that release. The `magic_notifications` requirement it states moves to `^0.3.0`, which is the floor the starter release carries, and the notification section gains the five `notifications.*` keys the mounted screens read and no package supplies (`bulk_title`, `bulk_description`, `delete`, `delete_failed`, `channel_sms`): an adopter upgrading with a hand-written catalogue sees each of them rendered as its own key. This file is the only agent-facing document for that package, since `.pubignore` keeps its `CLAUDE.md` out of the published archive, and `magic_starter`'s own `skill_reference_stamp_test.dart` fails against a stale stamp whenever a sibling checkout exists. (`skills/magic-framework/references/plugin-starter.md`, `skills/magic-framework/SKILL.md`) + ## [0.0.10] - 2026-09-11 ### BREAKING diff --git a/skills/magic-framework/SKILL.md b/skills/magic-framework/SKILL.md index 19813010..4d9d7503 100644 --- a/skills/magic-framework/SKILL.md +++ b/skills/magic-framework/SKILL.md @@ -2,10 +2,10 @@ name: magic-framework description: "Write correct, idiomatic code in a Flutter app that depends on the `magic` framework (Laravel-inspired: IoC container, 18 facades, Eloquent-style ORM, service providers, reactive controllers, GoRouter routing, validation, auth, broadcasting). Use whenever code imports `package:magic/magic.dart` or `package:magic/testing.dart`, or the work touches Magic.init, MagicApp, a facade (Auth/Http/Cache/DB/Echo/Event/Gate/Config/Lang/Launch/Log/Pick/MagicRoute/Schema/Session/Storage/Vault/Crypt), a Model, MagicController, a MagicView, MagicFormData, FormRequest, a ServiceProvider, a migration, or the artisan make:* CLI. UI styling is Wind (separate wind-ui skill). Do NOT use for plain Flutter or Wind-only work with no magic import." when_to_use: "Use proactively when editing or scaffolding a magic app: Magic.init / a facade / a Model / a MagicController or MagicView / a form (MagicFormData, FormRequest, Validator) / a ServiceProvider / a route or MagicMiddleware / a migration / MagicStateMixin + RxStatus + fetchList / Session flash + old() + trans() / testing with MagicTest + Http.fake/Auth.fake / the artisan make:* CLI / the magic_deeplink, magic_notifications, magic_social_auth, magic_starter, magic_payments, or magic_devtools plugins. Trigger even when the user does not say the word 'magic'. Do NOT trigger for plain Flutter or Wind-only UI with no package:magic import." -version: 0.1.16 +version: 0.1.17 --- - + # Magic Framework diff --git a/skills/magic-framework/references/plugin-starter.md b/skills/magic-framework/references/plugin-starter.md index 300275e6..5ad13ab8 100644 --- a/skills/magic-framework/references/plugin-starter.md +++ b/skills/magic-framework/references/plugin-starter.md @@ -1,8 +1,10 @@ - + # magic_starter Plugin -Full-stack Flutter starter kit for Magic Framework: pre-built auth flows, team management, profile settings, billing, and responsive app/guest layouts with an opt-in feature flag system. The notification UI moved to `magic_notifications` in alpha.25; this package mounts it and requires `magic_notifications ^0.2.0`. +Full-stack Flutter starter kit for Magic Framework: pre-built auth flows, team management, profile settings, billing, and responsive app/guest layouts with an opt-in feature flag system. The notification UI moved to `magic_notifications` in alpha.25; this package mounts it and requires `magic_notifications ^0.3.0`. + +Versions leave the alpha rail at this release: `0.0.1-alpha.26` is followed by `0.0.27`, carrying the counter rather than resetting it. An existing `^0.0.1-alpha.N` pin already covers it, since a caret on a zero major ends at `0.1.0`, and `flutter pub add magic_starter` now takes the current release without a prerelease pin. ## Contents @@ -223,6 +225,8 @@ Notify.view.slot(NotificationViewRegistry.typeIconSlotView, 'monitor_down', What stays here: `registerMagicStarterNotificationRoutes()` mounts `/notifications` and `/settings/notifications` in the `layout.app` shell and re-registers both screens wrapped in `MSPageContainer`, so they inherit the host's page geometry. The delete row asks first, through this package's `MSConfirmDialog`. See `plugin-notifications.md` for the `Notify` facade API. +Those screens read five `notifications.*` keys no package supplies: `bulk_title` and `bulk_description` (the bulk channel card, `magic_notifications` 0.3.0), `delete` (the row's delete glyph, which a screen reader otherwise announces as "button"), `delete_failed`, and `channel_sms`. `starter:install` scaffolds all five into `en.stub`; an app upgrading with a hand-written catalogue adds them itself, or `Translator.get` renders each key as its own text. + ### Access | Property | Type | Description | @@ -514,7 +518,7 @@ Two guards ship ready to register as the `auth` and `guest` aliases in the app's Both override `redirectTarget` (a pre-build synchronous redirect) rather than `handle` (a post-build remount), so a guarded page never mounts for someone who is about to be sent away. Each one guards its own destination so the redirect cannot loop, which matters because go_router raises after more than five successive redirects. -`EnsureAuthenticated` also records the requested location with `MagicRouter.setIntendedUrl` before bouncing (alpha.27), and the `NavigatesRoutes.navigateHome()` every post-auth path calls reads it back with `pullIntendedUrl`, falling back to `MagicStarterConfig.homeRoute()`. So a deep link that lands on a signed-out device survives the login bounce. Nothing is recorded for the guest-only auth routes themselves, and `redirectTarget` only sees `state.matchedLocation`, so a recorded intent loses the original query string. +`EnsureAuthenticated` also records the requested location with `MagicRouter.setIntendedUrl` before bouncing (0.0.27), and the `NavigatesRoutes.navigateHome()` every post-auth path calls reads it back with `pullIntendedUrl`, falling back to `MagicStarterConfig.homeRoute()`. So a deep link that lands on a signed-out device survives the login bounce. Nothing is recorded for the guest-only auth routes themselves, and `redirectTarget` only sees `state.matchedLocation`, so a recorded intent loses the original query string. ## Plan upgrade wall From 65e0342656bc4e06e7657bd74cdbfaec7ee76fac Mon Sep 17 00:00:00 2001 From: Anilcan Cakir Date: Fri, 11 Sep 2026 09:23:37 +0300 Subject: [PATCH 2/2] docs(skill): cover what 0.0.27 added to magic_starter Three commits landed on that package's main after the stamp move was written (#130, #131, #132), all into the same unreleased section, so the release this file is stamped for now ships more than it described. The configuration block gains notifications.external_id_prefix and a paragraph on the identity lifecycle: the provider declares off Auth.stateNotifier, releases it when a session ends, and reads the current state once at boot. The value has to equal the backend's own, since OneSignal accepts a mismatch and delivers to nobody, so the only trace is a zero-recipient report on the server. starter:doctor reports the resolved prefix and never fails on it, because three of the four sites that compose the id live in magic-starter-laravel. Also records that polling now stops on the two sign-outs the auth controller never sees, which is the one behaviour an app could notice. --- CHANGELOG.md | 2 +- .../magic-framework/references/plugin-starter.md | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94e48a9e..56f1c29a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. ### Improvements -- **`plugin-starter.md` follows `magic_starter` off the alpha rail.** That package's next release is `0.0.27` rather than `0.0.1-alpha.27`, so the reference stamp moves with it and the release markers inside the file now read `0.0.27` where they described that release. The `magic_notifications` requirement it states moves to `^0.3.0`, which is the floor the starter release carries, and the notification section gains the five `notifications.*` keys the mounted screens read and no package supplies (`bulk_title`, `bulk_description`, `delete`, `delete_failed`, `channel_sms`): an adopter upgrading with a hand-written catalogue sees each of them rendered as its own key. This file is the only agent-facing document for that package, since `.pubignore` keeps its `CLAUDE.md` out of the published archive, and `magic_starter`'s own `skill_reference_stamp_test.dart` fails against a stale stamp whenever a sibling checkout exists. (`skills/magic-framework/references/plugin-starter.md`, `skills/magic-framework/SKILL.md`) +- **`plugin-starter.md` follows `magic_starter` off the alpha rail.** That package's next release is `0.0.27` rather than `0.0.1-alpha.27`, so the reference stamp moves with it and the release markers inside the file now read `0.0.27` where they described that release. The `magic_notifications` requirement it states moves to `^0.3.0`, which is the floor the starter release carries, and the notification section gains the five `notifications.*` keys the mounted screens read and no package supplies (`bulk_title`, `bulk_description`, `delete`, `delete_failed`, `channel_sms`): an adopter upgrading with a hand-written catalogue sees each of them rendered as its own key. The configuration section also gains `notifications.external_id_prefix`, which 0.0.27 introduced: the provider now declares `` as the push external id off `Auth.stateNotifier` and the value has to equal the backend's own, since OneSignal accepts a mismatch and delivers to nobody. This file is the only agent-facing document for that package, since `.pubignore` keeps its `CLAUDE.md` out of the published archive, and `magic_starter`'s own `skill_reference_stamp_test.dart` fails against a stale stamp whenever a sibling checkout exists. (`skills/magic-framework/references/plugin-starter.md`, `skills/magic-framework/SKILL.md`) ## [0.0.10] - 2026-09-11 diff --git a/skills/magic-framework/references/plugin-starter.md b/skills/magic-framework/references/plugin-starter.md index 5ad13ab8..eabd723d 100644 --- a/skills/magic-framework/references/plugin-starter.md +++ b/skills/magic-framework/references/plugin-starter.md @@ -278,6 +278,9 @@ Copy from `lib/config/magic_starter.dart` into your app config: 'billing': { 'web_origin': null, // REQUIRED once billing is on, and no default exists }, + 'notifications': { + 'external_id_prefix': 'user_', // must equal the backend's own prefix (0.0.27+) + }, 'legal': { 'terms_url': null, // Shows ToS link on register page when set 'privacy_url': null, // Shows Privacy link on register page when set @@ -292,6 +295,18 @@ concatenates it into Stripe's `successUrl`, `cancelUrl` and the portal `returnUr relative url, and the resulting `BillingException` is logged rather than shown, so the customer sees a checkout button that does nothing. `starter:doctor` reports the missing key (alpha.23+). +`notifications.external_id_prefix` is new in 0.0.27 and needs no host code: `MagicStarterServiceProvider` +listens to `Auth.stateNotifier` and declares `` as the push external id when a session +begins, releases it when one ends, and reads the current state once at boot so a session restored before +this provider boots is declared too. The default `user_` is what `magic-starter-laravel`'s `HasNotifications` +composes, and the two must agree EXACTLY: OneSignal accepts a mismatch and delivers to nobody, so the only +trace is a zero-recipient report on the server. A blank value resolves to `user_` rather than to no prefix. +`starter:doctor` prints the prefix it resolves to (0.0.27+) and never fails on it, since any value is valid +as long as the backend uses the same one; three of the four sites that compose the id live in the backend, +where no check inside this package can reach them. The release also stops `Notify` polling on the two +sign-outs the auth controller never sees (account deletion, and magic's `AuthInterceptor` failing a token +refresh); `MagicStarterAppLayout.initState` re-arms it when the shell remounts. + ## View Registry Override any pre-built screen by registering a custom builder under its string key. Call `MagicStarter.view.register()` in a service provider `boot()`.