@meadow-studio/platform 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/MeadowPlatform.podspec +17 -0
  2. package/Package.swift +23 -0
  3. package/README.md +147 -2
  4. package/android/build.gradle +42 -0
  5. package/android/src/main/AndroidManifest.xml +1 -0
  6. package/android/src/main/java/app/meadow/platform/MeadowAppRatingPlugin.java +38 -0
  7. package/dist/cli/app-skill.d.ts +3 -0
  8. package/dist/cli/app-skill.d.ts.map +1 -0
  9. package/dist/cli/app-skill.js +38 -0
  10. package/dist/cli/app-skill.js.map +1 -0
  11. package/dist/cli/commands.d.ts +74 -0
  12. package/dist/cli/commands.d.ts.map +1 -0
  13. package/dist/cli/commands.js +1095 -0
  14. package/dist/cli/commands.js.map +1 -0
  15. package/dist/cli/config.d.ts +123 -0
  16. package/dist/cli/config.d.ts.map +1 -0
  17. package/dist/cli/config.js +428 -0
  18. package/dist/cli/config.js.map +1 -0
  19. package/dist/cli/inspiration.d.ts +3 -0
  20. package/dist/cli/inspiration.d.ts.map +1 -0
  21. package/dist/cli/inspiration.js +12 -0
  22. package/dist/cli/inspiration.js.map +1 -0
  23. package/dist/cli/meadow.d.ts +8 -0
  24. package/dist/cli/meadow.d.ts.map +1 -0
  25. package/dist/cli/meadow.js +466 -0
  26. package/dist/cli/meadow.js.map +1 -0
  27. package/dist/cli/product-brief.d.ts +3 -0
  28. package/dist/cli/product-brief.d.ts.map +1 -0
  29. package/dist/cli/product-brief.js +38 -0
  30. package/dist/cli/product-brief.js.map +1 -0
  31. package/dist/cli/recipes.d.ts +10 -0
  32. package/dist/cli/recipes.d.ts.map +1 -0
  33. package/dist/cli/recipes.js +575 -0
  34. package/dist/cli/recipes.js.map +1 -0
  35. package/dist/cli/sync.d.ts +14 -0
  36. package/dist/cli/sync.d.ts.map +1 -0
  37. package/dist/cli/sync.js +310 -0
  38. package/dist/cli/sync.js.map +1 -0
  39. package/dist/cli/templates.d.ts +27 -0
  40. package/dist/cli/templates.d.ts.map +1 -0
  41. package/dist/cli/templates.js +1292 -0
  42. package/dist/cli/templates.js.map +1 -0
  43. package/dist/cli/website.d.ts +5 -0
  44. package/dist/cli/website.d.ts.map +1 -0
  45. package/dist/cli/website.js +262 -0
  46. package/dist/cli/website.js.map +1 -0
  47. package/dist/index.d.ts +5 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +5 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/notifications.d.ts +119 -0
  52. package/dist/notifications.d.ts.map +1 -0
  53. package/dist/notifications.js +320 -0
  54. package/dist/notifications.js.map +1 -0
  55. package/dist/platform.d.ts +163 -0
  56. package/dist/platform.d.ts.map +1 -0
  57. package/dist/platform.js +623 -0
  58. package/dist/platform.js.map +1 -0
  59. package/dist/purchases.d.ts +88 -0
  60. package/dist/purchases.d.ts.map +1 -0
  61. package/dist/purchases.js +296 -0
  62. package/dist/purchases.js.map +1 -0
  63. package/dist/ui/app-build.component.d.ts +18 -0
  64. package/dist/ui/app-build.component.d.ts.map +1 -0
  65. package/dist/ui/app-build.component.js +56 -0
  66. package/dist/ui/app-build.component.js.map +1 -0
  67. package/dist/ui/app-build.model.d.ts +11 -0
  68. package/dist/ui/app-build.model.d.ts.map +1 -0
  69. package/dist/ui/app-build.model.js +18 -0
  70. package/dist/ui/app-build.model.js.map +1 -0
  71. package/dist/ui/app-links.component.d.ts +14 -0
  72. package/dist/ui/app-links.component.d.ts.map +1 -0
  73. package/dist/ui/app-links.component.js +77 -0
  74. package/dist/ui/app-links.component.js.map +1 -0
  75. package/dist/ui/app-links.model.d.ts +18 -0
  76. package/dist/ui/app-links.model.d.ts.map +1 -0
  77. package/dist/ui/app-links.model.js +17 -0
  78. package/dist/ui/app-links.model.js.map +1 -0
  79. package/dist/ui/index.d.ts +5 -0
  80. package/dist/ui/index.d.ts.map +1 -0
  81. package/dist/ui/index.js +5 -0
  82. package/dist/ui/index.js.map +1 -0
  83. package/docs/CLI.md +389 -0
  84. package/docs/PLATFORM_GUIDE.md +423 -0
  85. package/docs/POC_FINDINGS.md +218 -0
  86. package/docs/PROJECT_BRIEF.md +501 -0
  87. package/docs/RELEASING.md +49 -0
  88. package/docs/V0.1_PATH.md +310 -0
  89. package/ios/Sources/MeadowPlatformPlugin/MeadowAppRatingPlugin.swift +39 -0
  90. package/package.json +89 -4
  91. package/schema/meadow-config.schema.json +250 -0
@@ -0,0 +1,423 @@
1
+ # Meadow Platform Guide
2
+
3
+ This is the current operating guide for developers and agents using or extending Meadow Platform.
4
+ It explains what the platform is, how its parts fit together, what it can do today, and which
5
+ responsibilities remain with each application.
6
+
7
+ In the source repository, this project lives in `platform/` beside the independent, optional
8
+ `design/` project. Each has its own dependencies and build. Apps install exact
9
+ `@meadow-studio/platform` versions from the public npm registry.
10
+
11
+ ## Mission
12
+
13
+ Meadow Platform is an app-production system for moving from an idea to a release-ready mobile
14
+ application as quickly and repeatably as possible.
15
+
16
+ It combines:
17
+
18
+ - a CLI that creates and maintains standalone repositories with an app and companion website;
19
+ - a pinned Angular and Capacitor foundation;
20
+ - reusable runtime services and small infrastructure UI components;
21
+ - integration setup and optional capability recipes;
22
+ - pull-request CI, screenshot testing, native builds, diagnostics, and release gates; and
23
+ - the conventions needed to apply that foundation consistently across many apps.
24
+
25
+ The intended result is not a generic starter template. It is an evolving system that preserves
26
+ proven app infrastructure so each new application can focus earlier on its unique product.
27
+
28
+ ```text
29
+ Idea or existing app
30
+ ↓
31
+ meadow new or meadow init
32
+ ↓
33
+ Standalone release-oriented app repository
34
+ ↓
35
+ Build app-owned product and design
36
+ ↓
37
+ Add/configure only the capabilities the app needs
38
+ ↓
39
+ Pull-request CI and visual review
40
+ ↓
41
+ meadow doctor + meadow release-check
42
+ ↓
43
+ Store preparation and release
44
+ ```
45
+
46
+ The long-term measure of success is simple: each subsequent Meadow app should be faster to build and
47
+ release than the previous one.
48
+
49
+ ## Mental model
50
+
51
+ Meadow Platform has three cooperating parts.
52
+
53
+ ### The `meadow` CLI
54
+
55
+ The CLI creates an ordinary standalone repository and automates repeatable development and release
56
+ work. Generated files belong to the application and remain understandable without hidden framework
57
+ machinery.
58
+
59
+ Use the CLI to:
60
+
61
+ - create and validate a new app;
62
+ - adopt the Meadow control plane into a supported existing app without replacing app-owned work;
63
+ - synchronize typed project intent into generated web, native, test, and package configuration;
64
+ - add optional capabilities such as local data;
65
+ - install app-owned service configuration;
66
+ - generate native assets and signing guidance;
67
+ - inspect readiness, synchronize versions, and run release checks; and
68
+ - optionally create and push the app's GitHub repository.
69
+
70
+ The complete command reference is in [CLI.md](CLI.md).
71
+
72
+ ### The `@meadow-studio/platform` runtime
73
+
74
+ Every app consumes one pinned npm package. Its small public API provides stable Meadow-owned
75
+ boundaries around runtime configuration, app metadata, analytics policy, purchases, and app-rating
76
+ behavior. Third-party provider types should not spread through application code when a Meadow
77
+ boundary exists.
78
+
79
+ The package also ships the native app-rating plugin and an optional `@meadow-studio/platform/ui` entry point.
80
+
81
+ ### The generated application foundation
82
+
83
+ Each app and its companion website share one repository with app-owned domain code, visual language, credentials, store
84
+ records, and release history. The generated foundation currently uses:
85
+
86
+ - Angular 22 with standalone components and strict TypeScript;
87
+ - Capacitor 8 with generated iOS and Android projects;
88
+ - a separate static `website/` project with home, support, privacy, and terms pages;
89
+ - Node 24.15 and npm 11;
90
+ - Vitest unit tests and coverage thresholds;
91
+ - Playwright phone and tablet screenshot comparisons;
92
+ - a repository-local app-development skill linked from `AGENTS.md`;
93
+ - GitHub Actions for quality, web, visual, Android, and unsigned iOS builds; and
94
+ - exact dependency versions and immutable GitHub Action revisions.
95
+
96
+ Ionic and Meadow Design are not part of the foundation. Either may be adopted by an app as an explicit
97
+ app-owned choice.
98
+
99
+ ## Ownership boundary
100
+
101
+ Meadow Platform owns infrastructure that is useful across multiple applications:
102
+
103
+ - the shared toolchain and repository structure;
104
+ - provider-neutral runtime boundaries;
105
+ - repeatable integration setup;
106
+ - build, test, CI, diagnostics, and release guardrails;
107
+ - small infrastructure-oriented UI; and
108
+ - optional recipes proven by real apps.
109
+
110
+ The application owns everything that makes the product distinct:
111
+
112
+ - domain models, actions, rules, and terminology;
113
+ - pages, navigation, visual design, and product UI;
114
+ - analytics event names and the moments at which events are recorded;
115
+ - the moment at which a rating request is appropriate;
116
+ - purchase products, entitlement policy, pricing, and paywall copy;
117
+ - database tables, validation, repositories, and deletion behavior;
118
+ - Supabase schema, RLS, grants, storage policies, and backend lifecycle;
119
+ - credentials, native service files, signing material, and store accounts; and
120
+ - legal copy, privacy choices, store metadata, and final release decisions.
121
+
122
+ Stay Light is a donor and evidence source, not the platform's architecture specification. 24h
123
+ Pushups is the first POC consumer. New abstractions should continue to come from repeated real-app
124
+ needs rather than hypothetical completeness.
125
+
126
+ ## Current capability map
127
+
128
+ | Capability | Current behavior | Important boundary |
129
+ | --- | --- | --- |
130
+ | App creation | `meadow new` creates, installs, formats, builds, tests, generates native projects and visual baselines, initializes Git, and can create a GitHub repository. `meadow init` generates the same foundation inside an empty Git checkout while preserving its remote and history. | Product code and visual design remain app-owned. A clean checkout must contain only `.git`. |
131
+ | Companion website | `meadow new` creates a static `website/` project in the same repository; `meadow init` adds it when absent and preserves an existing site. An optional base domain derives a subdomain URL, and `meadow sync` updates generated site metadata. The privacy draft pre-fills Meadow Development's publisher/contact details and explains the two Firebase consent choices. | Hosting, DNS, TLS, publication, app-specific data/events/retention/deletion details, and final legal review remain app-owned. Draft pages are marked `noindex`. |
132
+ | Existing-app adoption | `meadow init` verifies Angular 22 and Capacitor 8, infers app/provider metadata, previews changes, installs the pinned platform, creates project configuration, and maintains marked agent and safety guidance. | It preserves existing source, scripts, CI, test configuration, and unmarked instructions; `meadow doctor` reports remaining foundation gaps. |
133
+ | Typed project configuration | `meadow.config.json` v2 is the source of truth for identity, releases, targets, environments, links, capabilities, public provider identifiers, and analytics definitions. `meadow sync` generates dependent files and `meadow sync --check` detects drift. | Secrets and product behavior remain outside the config. Generated files are replaceable; app-owned files are not silently overwritten. |
134
+ | Runtime configuration | `provideMeadowPlatform(...)` validates and freezes app identity, environment, links, and analytics allowlists. | Secrets never belong in runtime config committed to source. |
135
+ | App information | `MeadowAppInfoService` returns platform, native version, and native build number behind Meadow types. | Web and unavailable native metadata return `null`, not invented values. |
136
+ | Analytics | `MeadowAnalyticsService` persists explicit consent, requires a configured production environment, allowlists events/properties, and delivers native events through Firebase without exposing provider types. | The app owns its event catalogue, tracking moments, consent UI/copy, disclosures, and Firebase project. Web, development, and test delivery remain off. |
137
+ | Crash reporting | `MeadowCrashReportingService` persists separate explicit consent and provides failure-safe handled-error and breadcrumb APIs over native Firebase Crashlytics. Generated native projects start collection off and eagerly enforce environment and consent state at startup. | The app owns consent UI/copy and decides which non-sensitive diagnostic context is appropriate. Final Firebase console and iOS symbol-upload verification remain release checks. |
138
+ | App rating | `MeadowAppRatingService` calls the system store surface on native platforms with concurrency, version, cooldown, and rolling-year safeguards. | The app decides the meaningful success moment; Apple and Google decide whether a prompt appears. |
139
+ | Infrastructure UI | `@meadow-studio/platform/ui` provides app-build information and privacy/support links with app-overridable labels and CSS variables. | It is not a design system; feature UI stays with the app or optional Meadow Design. |
140
+ | Local data | `meadow add local-data` generates migrated SQLite, transactions, a typed document store, browser IndexedDB persistence, tests, and safety checks. Browser persistence and Android compilation are validated; a clean iOS simulator compile of this optional recipe remains pending. | Tables, domain mapping, data sensitivity decisions, and deletion/reset behavior remain app-owned. |
141
+ | Local notifications | `meadow add notifications` pins and synchronizes the native provider. `MeadowNotificationService` exposes permission state, an explicit permission request, one-off and calendar schedules, replace/cancel/pending operations, Android channels, normalized failures, and tap actions. Web and disabled apps safely report the capability as unavailable. Clean generated Android and iOS simulator builds passed; on-device delivery remains app release verification. | The app owns permission explanation and trigger, copy, IDs, timing rules, channels, tap navigation, and analytics. Meadow never prompts as a scheduling side effect and uses inexact Android alarms by default. |
142
+ | Firebase setup | The base app includes Analytics and Crashlytics dependencies; `meadow configure firebase` validates the files needed by enabled platforms, synchronizes native projects, installs Android build plugins, and registers `GoogleService-Info.plist` as an iOS app resource. `meadow doctor` checks dependencies, files, plugins, bundled resources, and opt-in defaults. | The app owns its Firebase project and must verify an event and test crash on a device before release. iOS dSYM upload configuration remains app-specific release setup. |
143
+ | Purchases | Creation can add RevenueCat; `meadow configure revenuecat` validates public platform keys and records offering and entitlement identifiers. Generated builds load the ignored local keys, and `MeadowPurchaseService` provides products, live entitlement and premium state, purchase, restore, refresh, support ID, and normalized outcomes without exposing RevenueCat types. | The app owns its paywall UI and copy, product and package identifiers, pricing policy, entitlement policy, analytics, store catalog, and final sandbox/device verification. Web and unconfigured apps safely report the capability as unavailable. |
144
+ | Supabase setup | Creation can add the client; configuration validates and records the URL and publishable key in an ignored local environment file. | The app must still create its client and own schema, RLS, grants, storage, auth UX, and database tests. Never use a service-role key in a client. |
145
+ | Assets and metadata | CLI commands generate native assets and maintain support, privacy, terms, version, and build metadata. | Store listings and final legal content remain app-owned. |
146
+ | Signing guidance | `meadow configure signing` creates app-local Android and iOS signing instructions. | It does not create certificates, profiles, keystores, passwords, or CI secrets. |
147
+ | Diagnostics and release | `meadow doctor` explains missing or inconsistent setup; `meadow release-check` runs quality, visual, and selected native gates. | Passing technical checks does not publish the app or replace store review. |
148
+ | Pull-request CI | Generated CI audits dependencies and runs formatting, linting, coverage-gated tests, app and website builds, screenshot comparison, Android build, and unsigned iOS build. Successful Android builds upload a downloadable debug APK; screenshot failures upload the report and receive a PR comment from a trusted follow-up workflow. | CI installs the exact public npm platform version with no Meadow package secret. Visual baselines are reviewed artifacts and are never silently updated. APKs and reports are Actions artifacts rather than externally hosted previews. |
149
+
150
+ “Configured” in `meadow.config.json` means the CLI successfully installed or recorded the required
151
+ setup inputs. It does not imply that an unfinished provider abstraction has become a complete
152
+ product feature.
153
+
154
+ ## Standard app workflow
155
+
156
+ ### 1. Create the repository
157
+
158
+ ```sh
159
+ meadow new my-app
160
+ ```
161
+
162
+ Use the interactive questions for a one-off app or `--config`/`--yes` for repeatable creation. A
163
+ normal creation produces a working web app, iOS and Android projects, a companion website, initial screenshots, CI, a
164
+ release checklist, and an initial gitmoji commit.
165
+
166
+ For a supported existing Angular 22 and Capacitor 8 repository, use the adoption path instead:
167
+
168
+ ```sh
169
+ meadow init --dry-run
170
+ meadow init
171
+ ```
172
+
173
+ Review the plan first. Initialization installs the Meadow control plane conservatively, then uses
174
+ `meadow doctor` to expose release-foundation work that cannot safely be inferred or merged.
175
+
176
+ ### 2. Build the smallest useful product
177
+
178
+ Replace the generated home screen with the app's domain behavior. Keep the product model and UI in
179
+ the app. Do not introduce optional infrastructure until the product demonstrates that it needs it.
180
+
181
+ Treat `meadow.config.json` as project intent rather than editing generated native or TypeScript values
182
+ in several places. After changing identity, releases, targets, environments, capabilities, links,
183
+ provider identifiers, analytics definitions, or screenshot viewports, run:
184
+
185
+ ```sh
186
+ meadow sync
187
+ ```
188
+
189
+ Generated CI runs `meadow sync --check` to prevent drift. Credentials, service-role keys, signing
190
+ material, and other secrets remain external.
191
+
192
+ ### 3. Add or configure capabilities
193
+
194
+ Examples:
195
+
196
+ ```sh
197
+ meadow add local-data
198
+ meadow add notifications
199
+ meadow configure firebase --google-services ... --google-service-info ...
200
+ meadow configure revenuecat --ios-key ... --android-key ... --entitlement ... --offering ...
201
+ meadow configure supabase --url ... --publishable-key ...
202
+ meadow configure assets --source resources/icon.png
203
+ meadow configure store --support-email ... --privacy-url ... --terms-url ...
204
+ ```
205
+
206
+ Use [CLI.md](CLI.md) for the exact arguments and safety constraints.
207
+
208
+ ### 4. Keep every pull request releasable
209
+
210
+ Run the same categories enforced by generated CI:
211
+
212
+ ```sh
213
+ npm run check
214
+ meadow sync --check
215
+ npm run test:visual
216
+ npm run build:android:ci
217
+ npm run build:ios:ci
218
+ ```
219
+
220
+ Screenshot differences are product changes. Review them rather than updating baselines merely to
221
+ make CI green.
222
+
223
+ ### 5. Diagnose and prepare a release
224
+
225
+ ```sh
226
+ meadow doctor
227
+ meadow version patch production
228
+ meadow release-check all
229
+ ```
230
+
231
+ Then complete the app-owned release checklist, signing, privacy disclosures, store metadata, and
232
+ submission. Meadow currently validates readiness; it does not upload releases to App Store Connect or
233
+ Google Play.
234
+
235
+ ## Runtime usage
236
+
237
+ Configure the runtime once in the Angular root providers:
238
+
239
+ ```ts
240
+ import { ApplicationConfig } from '@angular/core';
241
+ import { provideMeadowPlatform } from '@meadow-studio/platform';
242
+
243
+ export const appConfig: ApplicationConfig = {
244
+ providers: [
245
+ provideMeadowPlatform({
246
+ app: {
247
+ name: 'Example App',
248
+ id: 'app.meadow.example',
249
+ supportEmail: 'support@example.com',
250
+ privacyUrl: 'https://example.com/privacy',
251
+ },
252
+ environment: 'development',
253
+ analytics: {
254
+ enabled: true,
255
+ allowedEvents: ['item_created'],
256
+ allowedProperties: ['source'],
257
+ },
258
+ crashReporting: { enabled: true },
259
+ notifications: { enabled: true },
260
+ }),
261
+ ],
262
+ };
263
+ ```
264
+
265
+ The generated app already supplies this provider and maps development, device, and production
266
+ builds to the matching environment. When RevenueCat is configured, it also maps public iOS and
267
+ Android SDK keys from the ignored `.env.meadow.local` through a generated runtime asset. Those public
268
+ client keys reach the compiled app by design; they do not belong in committed source.
269
+
270
+ Use app-owned wrappers for product semantics:
271
+
272
+ ```ts
273
+ import { inject, Injectable } from '@angular/core';
274
+ import { MeadowAnalyticsService } from '@meadow-studio/platform';
275
+
276
+ @Injectable({ providedIn: 'root' })
277
+ export class ExampleAnalytics {
278
+ private readonly analytics = inject(MeadowAnalyticsService);
279
+
280
+ itemCreated(source: string): void {
281
+ this.analytics.track('item_created', { source });
282
+ }
283
+ }
284
+ ```
285
+
286
+ This keeps event names in the app and provider behavior behind Meadow Platform. The app's consent UI
287
+ applies the user's separate choices without importing Firebase:
288
+
289
+ ```ts
290
+ await inject(MeadowAnalyticsService).setConsent(analyticsGranted);
291
+ await inject(MeadowCrashReportingService).setConsent(crashReportingGranted);
292
+ ```
293
+
294
+ Both services expose `consentStatus()` and `isEnabled()`. Consent is persisted per app, provider
295
+ errors are contained, and collection remains disabled outside a configured production environment.
296
+ `MeadowCrashReportingService.recordError(...)` records handled failures and `log(...)` adds short
297
+ diagnostic breadcrumbs after consent.
298
+
299
+ Apps build their own paywall over the provider-neutral purchase service:
300
+
301
+ ```ts
302
+ import { inject } from '@angular/core';
303
+ import { MeadowPurchaseService } from '@meadow-studio/platform';
304
+
305
+ const purchases = inject(MeadowPurchaseService);
306
+
307
+ await purchases.loadProducts();
308
+ const products = purchases.products();
309
+ const outcome = await purchases.purchase(products[0].packageId);
310
+ const premium = purchases.isPremium();
311
+ ```
312
+
313
+ `products`, `entitlement`, `isPremium`, `status`, and `error` are Angular signals. Purchase and
314
+ restore return a small Meadow-owned outcome union: `completed`, `cancelled`, `pending`, or `failed`.
315
+ The service listens for customer-info changes and also exposes `refreshEntitlement()`, `restore()`,
316
+ and `getSupportId()`. The app decides how those outcomes look and what premium means to the
317
+ product. Before release, verify the real offering, products, purchase, cancellation/pending flow,
318
+ restore, and entitlement state in both store sandboxes.
319
+
320
+ Apps also own the notification experience while Meadow owns safe native delivery:
321
+
322
+ ```ts
323
+ import { Injectable, inject } from '@angular/core';
324
+ import { MeadowNotificationService } from '@meadow-studio/platform';
325
+
326
+ @Injectable({ providedIn: 'root' })
327
+ export class ReminderService {
328
+ private readonly notifications = inject(MeadowNotificationService);
329
+
330
+ // Call from an app-owned button after explaining why reminders are useful.
331
+ async enableDailyReminder() {
332
+ if (await this.notifications.requestPermission() !== 'granted') return;
333
+ return this.notifications.replace({
334
+ id: 1001,
335
+ title: 'Time to move',
336
+ body: 'Do a few pushups.',
337
+ schedule: { on: { hour: 18, minute: 0 }, repeats: true },
338
+ channel: { id: 'motivation', name: 'Motivation', importance: 'high' },
339
+ data: { route: '/today' },
340
+ });
341
+ }
342
+ }
343
+ ```
344
+
345
+ `permission`, `status`, and `lastAction` are Angular signals. `initialize()` and scheduling only
346
+ check permission; only `requestPermission()` can display the native prompt. Scheduling returns
347
+ `scheduled`, `permission_required`, `unavailable`, or a normalized `failed` outcome. Meadow uses
348
+ inexact Android alarms so ordinary reminders do not require exact-alarm access. If exact timing
349
+ becomes a real product requirement, it remains a separate native and release-policy decision.
350
+
351
+ Infrastructure UI is imported separately:
352
+
353
+ ```ts
354
+ import { MeadowAppBuildComponent, MeadowAppLinksComponent } from '@meadow-studio/platform/ui';
355
+ ```
356
+
357
+ Apps may use these small components or their exported pure model functions without adopting a
358
+ shared visual design.
359
+
360
+ ## Local-data model
361
+
362
+ Local data is generated into the app rather than exposed as a broad package API. This lets the app
363
+ own its schema while Meadow owns the repetitive native and browser setup.
364
+
365
+ ```text
366
+ Page or domain service
367
+ ↓
368
+ App-owned repository and validation
369
+ ↓
370
+ Generated LocalDocumentStore or LocalDatabase
371
+ ↓
372
+ SQLite on iOS/Android; SQLite persisted in IndexedDB on web
373
+ ```
374
+
375
+ The recipe pins `jeep-sqlite` 2.8.0 with `sql.js` 1.11.0 because newer WebAssembly binaries are not
376
+ ABI-compatible with that web component. Do not loosen this version without a real browser
377
+ write/read/reload test. See [CLI.md](CLI.md#add-local-data) for migration and data-safety rules.
378
+
379
+ ## Release-ready means a foundation, not a finished product
380
+
381
+ Meadow shortens the path to release by making the technical foundation reproducible. A generated app
382
+ is ready for product development and has the machinery needed to become releasable. It is not ready
383
+ for a store merely because generation succeeded.
384
+
385
+ Every app must still provide and verify:
386
+
387
+ - its useful product behavior and accessible UI;
388
+ - real icons, screenshots, descriptions, and store records;
389
+ - a published companion website with final support, privacy, and terms pages;
390
+ - consent behavior and privacy disclosures matching actual data collection;
391
+ - production service projects, policies, products, and public client keys;
392
+ - signing identities and protected release credentials;
393
+ - account/data deletion behavior where applicable; and
394
+ - device testing and final human review.
395
+
396
+ ## Using or extending Meadow Platform as an agent
397
+
398
+ Before changing an app or the platform:
399
+
400
+ 1. Identify the pinned `@meadow-studio/platform` version and read that version's documentation.
401
+ 2. Read `meadow.config.json` and run `meadow doctor` in a generated app before guessing about setup.
402
+ 3. Use an existing Meadow command, service, or recipe when it covers the need.
403
+ 4. Keep provider details, product policy, and domain behavior on the correct side of the ownership
404
+ boundary.
405
+ 5. Validate changes in a real consuming app when they affect generated or native behavior.
406
+ 6. After meaningful platform work, apply the documentation check in
407
+ `agent/skills/meadow-platform-documentation/SKILL.md`.
408
+
409
+ Do not infer a capability from an installed dependency alone. Use this guide and the implementation
410
+ to distinguish a complete Meadow capability from setup that is intentionally awaiting a proven app
411
+ need.
412
+
413
+ ## Documentation map
414
+
415
+ - [Project brief](PROJECT_BRIEF.md): purpose, architecture, constraints, and product direction.
416
+ - [CLI guide](CLI.md): exact creation, configuration, diagnostics, CI, and release commands.
417
+ - [POC findings](POC_FINDINGS.md): evidence and conclusions from Stay Light and 24h Pushups.
418
+ - [Platform release guide](RELEASING.md): versioning and distributing `@meadow-studio/platform` itself.
419
+ - [v0.1 path](V0.1_PATH.md): historical POC plan and dated implementation record.
420
+ - Generated app documentation: app-local CI, release, signing, and local-data instructions.
421
+
422
+ Source code remains authoritative for exact types and behavior. Documentation preserves the mental
423
+ model and constraints that code alone cannot communicate efficiently.
@@ -0,0 +1,218 @@
1
+ # POC application findings
2
+
3
+ These findings were gathered from the current Stay Light and 24h Pushups applications on 2026-09-14. They are implementation evidence, not permanent architecture requirements.
4
+
5
+ ## Application roles
6
+
7
+ - Stay Light is close to its initial release. It is the donor and reference implementation for infrastructure that has survived real release work.
8
+ - 24h Pushups is an early concept prototype. It is the first POC consumer of Meadow Platform, and integration should preserve fast product iteration.
9
+ - Both applications currently live as workspaces in the same `website` repository. Meadow Platform remains a separate repository and package.
10
+
11
+ ## Shared proven baseline
12
+
13
+ Both applications use:
14
+
15
+ - Angular 20.3 with standalone application configuration;
16
+ - Capacitor 7;
17
+ - TypeScript 5.9;
18
+ - RxJS 7.8;
19
+ - Node 22 and npm 10–11; and
20
+ - Angular dependency injection for application services.
21
+
22
+ 24h Pushups also uses Ionic 9. Stay Light does not currently depend on Ionic, so Ionic must not be a platform runtime requirement for the first POC.
23
+
24
+ This supports an Angular-first platform API with Capacitor peer dependencies. A framework-neutral abstraction is not yet justified by a real consumer.
25
+
26
+ ## Stay Light donor inventory
27
+
28
+ ### App configuration
29
+
30
+ Stay Light uses Angular `ApplicationConfig` plus build-time Angular environment replacement. Its environment fields mix generic concerns with app-specific development modes and RevenueCat public SDK keys.
31
+
32
+ Generic candidates:
33
+
34
+ - production/deployment identity;
35
+ - app name, ID, support URL/email, and privacy URL; and
36
+ - externally supplied provider configuration.
37
+
38
+ Leave in Stay Light:
39
+
40
+ - mock-photo behavior;
41
+ - visual-test mode;
42
+ - branch-preview routing;
43
+ - Stay Light product identifiers; and
44
+ - developer scenarios.
45
+
46
+ ### App information
47
+
48
+ Stay Light reads the native version with `@capacitor/app` directly inside its About page and falls back to a hard-coded version on web. This is a small, clear first extraction target.
49
+
50
+ The platform should own the mapping from Capacitor results to:
51
+
52
+ ```ts
53
+ interface MeadowAppInfo {
54
+ version: string | null;
55
+ buildNumber: string | null;
56
+ platform: 'ios' | 'android' | 'web';
57
+ }
58
+ ```
59
+
60
+ Build ref, commit SHA, build timestamp, release channel, About-page links, and UI remain app concerns until reuse is proven.
61
+
62
+ ### Analytics and consent
63
+
64
+ Stay Light already has a single Angular analytics service wrapping Firebase. It provides valuable proven behavior:
65
+
66
+ - production-only collection;
67
+ - explicit opt-in persisted locally;
68
+ - native-only event delivery;
69
+ - allowlisted events and properties;
70
+ - property sanitization;
71
+ - safe no-op behavior; and
72
+ - provider failures that never interrupt product flows.
73
+
74
+ The event union and property schema are entirely Stay Light-specific. Meadow Platform should provide a typed generic mechanism that lets each app own its event catalogue. Consent storage currently uses Stay Light-specific keys and coordinates analytics with crash reporting, so consent orchestration should not be copied into the first POC.
75
+
76
+ ### Purchases and entitlements
77
+
78
+ Stay Light's purchase implementation is mature but large: purchase access, entitlement evaluation, payment flow, and consent together exceed 1,300 lines before UI tests and components.
79
+
80
+ Reusable candidates include:
81
+
82
+ - RevenueCat configuration by native platform;
83
+ - product loading;
84
+ - normalized product metadata;
85
+ - purchase outcome/error categories;
86
+ - restore purchases;
87
+ - customer-info refresh/listening;
88
+ - entitlement verification; and
89
+ - resilience during provider or network failures.
90
+
91
+ Stay Light-specific concerns include:
92
+
93
+ - monthly versus lifetime product taxonomy;
94
+ - unlimited-review terminology;
95
+ - product identifiers;
96
+ - payment-modal behavior and copy;
97
+ - developer payment simulations;
98
+ - subscription upgrade rules;
99
+ - analytics funnel events; and
100
+ - entitlement persistence in Stay Light's database service.
101
+
102
+ Purchases should therefore be designed as its own vertical slice. Moving the existing services wholesale would preserve too much product policy and expose RevenueCat types.
103
+
104
+ ### Purchase capability conclusion — 2026-09-18
105
+
106
+ The implemented Meadow boundary follows that evidence: it owns native key selection, RevenueCat
107
+ initialization, offering product loading, normalized product and entitlement state, live customer
108
+ updates, purchase/restore, support identifiers, and a small outcome/error model. RevenueCat types
109
+ do not cross the public API. The app still owns its product identifiers and taxonomy, paywall,
110
+ copy, upgrade rules, analytics, persistence decisions, and entitlement meaning.
111
+
112
+ The capability was verified through platform unit tests, a packed clean consumer, generated
113
+ RevenueCat configuration, and clean Android and iOS simulator compilation. A real app must still
114
+ exercise store sandbox transactions with its own catalog and public SDK keys before release.
115
+
116
+ ### App ratings
117
+
118
+ Stay Light uses the system-owned App Store and Play Store review surfaces rather than a custom rating modal. Its reusable safeguards are:
119
+
120
+ - native-only availability with a safe web no-op;
121
+ - one in-flight request at a time;
122
+ - no repeated request for the same app version;
123
+ - a 120-day cooldown;
124
+ - no more than two attempts in a rolling year;
125
+ - persistence only after the native store accepts the request; and
126
+ - failures that never interrupt the product flow.
127
+
128
+ Stay Light's swipe count, active-day threshold, and premium-purchase trigger are product policy and remain app-owned. The native plugin implementation and frequency safeguards are generic platform infrastructure.
129
+
130
+ ## 24h Pushups consumer inventory
131
+
132
+ 24h Pushups currently has:
133
+
134
+ - a small standalone Angular/Ionic bootstrap;
135
+ - one environment field (`production`);
136
+ - a generated Android project;
137
+ - no generated iOS project yet;
138
+ - local-only persistence behind app-owned repositories;
139
+ - local notifications behind an app-owned service;
140
+ - no analytics provider, crash reporting, or purchases;
141
+ - Meadow Platform app information and provider-neutral analytics foundations; and
142
+ - an app-owned rating qualification based on completed pushups and winning days.
143
+
144
+ Its local persistence, pushup calculations, progression, notifications, UI primitives, and domain actions are product logic. They should stay in the app.
145
+
146
+ Potential future analytics events are visible—intro completed, pushups logged, level changed, notifications enabled. The first provider-neutral foundation now records the app-owned `pushups_logged` action behind a disabled transport, allowing the API to be exercised without introducing Firebase/native/privacy setup during concept exploration.
147
+
148
+ ## First POC boundary
149
+
150
+ Add only:
151
+
152
+ ```ts
153
+ provideMeadowPlatform({
154
+ app: {
155
+ name: '24h Pushups',
156
+ id: 'app.pushups24h'
157
+ },
158
+ environment: 'development'
159
+ });
160
+ ```
161
+
162
+ and a Meadow-owned app-information service for use in Settings.
163
+
164
+ The first POC uses a local file dependency and separately verifies the publishable files with `npm pack --dry-run`. This keeps the feedback loop local while checking the same package contents a registry would receive.
165
+
166
+ ## Explicit POC exclusions
167
+
168
+ - analytics and Firebase configuration;
169
+ - privacy/diagnostics consent UI;
170
+ - RevenueCat and premium behavior;
171
+ - notification abstraction;
172
+ - persistence abstraction;
173
+ - Meadow Design migration;
174
+ - iOS project generation;
175
+ - GitHub Packages publishing; and
176
+ - release automation.
177
+
178
+ Each exclusion can become a later slice when the app reaches the point where that infrastructure is genuinely needed.
179
+
180
+ App ratings were added after the initial POC boundary was proven. The shared capability remains separate from Meadow Design: the stores own the rating interface, Meadow Platform owns native delivery and frequency safeguards, and each app owns the moment at which it asks.
181
+
182
+ ## Local-notification capability evidence — 2026-10-06
183
+
184
+ 24h Pushups proves the reusable reminder lifecycle: permission is checked before scheduling,
185
+ permission is requested only from an explicit app action, an Android channel is created, existing
186
+ IDs can be replaced, and one-off or daily reminders carry app-owned navigation data. Stay Light's
187
+ review reminder independently proves explicit permission timing, failure containment, and warm or
188
+ cold tap navigation, while its photo-aware eligibility and custom alarm behavior are product
189
+ specific and were not generalized.
190
+
191
+ `meadow add notifications` therefore installs the pinned Capacitor provider and enables a Meadow-owned
192
+ runtime boundary. `MeadowNotificationService` owns permission state, scheduling mechanics,
193
+ replace/cancel/pending operations, Android channel adaptation, provider error containment, and tap
194
+ actions. Each app still owns permission copy, IDs, message copy, timing policy, channel names, tap
195
+ routing, and analytics. Scheduling never triggers the permission prompt, and Android uses inexact
196
+ alarms by default to avoid introducing special-alarm access for ordinary reminders.
197
+ Capacitor Local Notifications 8.3 [requests display permission during scheduling and defaults
198
+ Android notifications to exact alarms](https://capacitorjs.com/docs/apis/local-notifications).
199
+ Meadow checks display permission first and sets `isExactNotification: false` on each scheduled
200
+ notification to preserve the app's explicit permission moment and avoid a surprise exact-alarm
201
+ settings screen. A clean generated app passed its checks and compiled Android and iOS simulator
202
+ targets with this optional capability installed; device delivery and tap behavior remain app release
203
+ verification.
204
+
205
+ ## Local-data recipe evidence — 2026-09-16
206
+
207
+ The later CLI work revisited persistence as an opt-in app foundation rather than adding storage to
208
+ the original package API.
209
+
210
+ - 24h Pushups proves the app-owned repository boundary, typed domain mapping, validation on read,
211
+ and immutable migrations.
212
+ - Nyttebjerggaard proves `@capacitor-community/sqlite` on the shared Capacitor 8 baseline.
213
+ - Stay Light proves the value of queued writes, recovery, and deeper database lifecycle handling,
214
+ but those behaviors remain too specific to generalize from one mature app.
215
+
216
+ `meadow add local-data` therefore generates only the shared setup: native and browser SQLite,
217
+ parameterized operations, transactions, sequential migrations, a typed document store, and data
218
+ safety checks. Each app continues to own its tables, domain models, decoders, and repositories.