@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.
- package/MeadowPlatform.podspec +17 -0
- package/Package.swift +23 -0
- package/README.md +147 -2
- package/android/build.gradle +42 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/app/meadow/platform/MeadowAppRatingPlugin.java +38 -0
- package/dist/cli/app-skill.d.ts +3 -0
- package/dist/cli/app-skill.d.ts.map +1 -0
- package/dist/cli/app-skill.js +38 -0
- package/dist/cli/app-skill.js.map +1 -0
- package/dist/cli/commands.d.ts +74 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +1095 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/config.d.ts +123 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +428 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/inspiration.d.ts +3 -0
- package/dist/cli/inspiration.d.ts.map +1 -0
- package/dist/cli/inspiration.js +12 -0
- package/dist/cli/inspiration.js.map +1 -0
- package/dist/cli/meadow.d.ts +8 -0
- package/dist/cli/meadow.d.ts.map +1 -0
- package/dist/cli/meadow.js +466 -0
- package/dist/cli/meadow.js.map +1 -0
- package/dist/cli/product-brief.d.ts +3 -0
- package/dist/cli/product-brief.d.ts.map +1 -0
- package/dist/cli/product-brief.js +38 -0
- package/dist/cli/product-brief.js.map +1 -0
- package/dist/cli/recipes.d.ts +10 -0
- package/dist/cli/recipes.d.ts.map +1 -0
- package/dist/cli/recipes.js +575 -0
- package/dist/cli/recipes.js.map +1 -0
- package/dist/cli/sync.d.ts +14 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +310 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli/templates.d.ts +27 -0
- package/dist/cli/templates.d.ts.map +1 -0
- package/dist/cli/templates.js +1292 -0
- package/dist/cli/templates.js.map +1 -0
- package/dist/cli/website.d.ts +5 -0
- package/dist/cli/website.d.ts.map +1 -0
- package/dist/cli/website.js +262 -0
- package/dist/cli/website.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/notifications.d.ts +119 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/notifications.js +320 -0
- package/dist/notifications.js.map +1 -0
- package/dist/platform.d.ts +163 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +623 -0
- package/dist/platform.js.map +1 -0
- package/dist/purchases.d.ts +88 -0
- package/dist/purchases.d.ts.map +1 -0
- package/dist/purchases.js +296 -0
- package/dist/purchases.js.map +1 -0
- package/dist/ui/app-build.component.d.ts +18 -0
- package/dist/ui/app-build.component.d.ts.map +1 -0
- package/dist/ui/app-build.component.js +56 -0
- package/dist/ui/app-build.component.js.map +1 -0
- package/dist/ui/app-build.model.d.ts +11 -0
- package/dist/ui/app-build.model.d.ts.map +1 -0
- package/dist/ui/app-build.model.js +18 -0
- package/dist/ui/app-build.model.js.map +1 -0
- package/dist/ui/app-links.component.d.ts +14 -0
- package/dist/ui/app-links.component.d.ts.map +1 -0
- package/dist/ui/app-links.component.js +77 -0
- package/dist/ui/app-links.component.js.map +1 -0
- package/dist/ui/app-links.model.d.ts +18 -0
- package/dist/ui/app-links.model.d.ts.map +1 -0
- package/dist/ui/app-links.model.js +17 -0
- package/dist/ui/app-links.model.js.map +1 -0
- package/dist/ui/index.d.ts +5 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +5 -0
- package/dist/ui/index.js.map +1 -0
- package/docs/CLI.md +389 -0
- package/docs/PLATFORM_GUIDE.md +423 -0
- package/docs/POC_FINDINGS.md +218 -0
- package/docs/PROJECT_BRIEF.md +501 -0
- package/docs/RELEASING.md +49 -0
- package/docs/V0.1_PATH.md +310 -0
- package/ios/Sources/MeadowPlatformPlugin/MeadowAppRatingPlugin.swift +39 -0
- package/package.json +89 -4
- package/schema/meadow-config.schema.json +250 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-links.component.js","sourceRoot":"","sources":["../../src/ui/app-links.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EACL,8BAA8B,EAC9B,cAAc,GAEf,MAAM,sBAAsB,CAAC;;;;IAUpB,+BAIC;IACC,YACF;IAAA,oBAAI;;;IALF,wDAAkB;;IAIlB,cACF;IADE,8CACF;;;IARJ,8BAAqC;IACnC,sGAQC;IACH,oBAAM;;;;IATJ,cAQC;IARD,cAAA,cAAO,CAQN;;AAfT,2EAA2E;AA4C3E,MAAM,OAAO,uBAAuB;IACjB,MAAM,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAEhD,SAAS,GAAG,KAAK,CAAC,iBAAiB;kFAAC,CAAC;IACrC,YAAY,GAAG,KAAK,CAAC,8BAA8B,CAAC,OAAO;qFAAC,CAAC;IAC7D,YAAY,GAAG,KAAK,CAAC,8BAA8B,CAAC,OAAO;qFAAC,CAAC;IAC7D,UAAU,GAAG,KAAK,CAA4B,SAAS;mFAAC,CAAC;IACzD,YAAY,GAAG,KAAK,CAA4B,SAAS;qFAAC,CAAC;IAEjD,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE;QACvC,MAAM,MAAM,GAAwB;YAClC,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE;YAC5B,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE;SAC7B,CAAC;QACF,OAAO,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE;YAC7C,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE;YAC7B,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE;SAClC,CAAC,CAAC;IACL,CAAC;8EAAC,CAAC;iHAlBQ,uBAAuB;6DAAvB,uBAAuB;YAvChC,sFAAsB;;YAAtB,6CAYC;;;iFA2BQ,uBAAuB;cA3CnC,SAAS;2BACE,kBAAkB,cAChB,IAAI,YACN;;;;;;;;;;;;;;GAcT;;kFA0BU,uBAAuB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { MeadowAppConfig } from '../platform.js';
|
|
2
|
+
export type MeadowAppLinkKind = 'privacy' | 'support';
|
|
3
|
+
export interface MeadowAppLink {
|
|
4
|
+
readonly kind: MeadowAppLinkKind;
|
|
5
|
+
readonly label: string;
|
|
6
|
+
readonly href: string;
|
|
7
|
+
}
|
|
8
|
+
export interface MeadowAppLinkLabels {
|
|
9
|
+
readonly privacy: string;
|
|
10
|
+
readonly support: string;
|
|
11
|
+
}
|
|
12
|
+
export interface MeadowAppLinkOverrides {
|
|
13
|
+
readonly privacyUrl?: string | null;
|
|
14
|
+
readonly supportEmail?: string | null;
|
|
15
|
+
}
|
|
16
|
+
export declare const DEFAULT_MEADOW_APP_LINK_LABELS: Readonly<MeadowAppLinkLabels>;
|
|
17
|
+
export declare function meadowAppLinks(app: Readonly<MeadowAppConfig>, labels?: Readonly<MeadowAppLinkLabels>, overrides?: Readonly<MeadowAppLinkOverrides>): readonly Readonly<MeadowAppLink>[];
|
|
18
|
+
//# sourceMappingURL=app-links.model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-links.model.d.ts","sourceRoot":"","sources":["../../src/ui/app-links.model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC;AAED,eAAO,MAAM,8BAA8B,EAAE,QAAQ,CAAC,mBAAmB,CAGvE,CAAC;AAEH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,QAAQ,CAAC,eAAe,CAAC,EAC9B,MAAM,GAAE,QAAQ,CAAC,mBAAmB,CAAkC,EACtE,SAAS,GAAE,QAAQ,CAAC,sBAAsB,CAAM,GAC/C,SAAS,QAAQ,CAAC,aAAa,CAAC,EAAE,CAcpC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const DEFAULT_MEADOW_APP_LINK_LABELS = Object.freeze({
|
|
2
|
+
privacy: 'Privacy',
|
|
3
|
+
support: 'Contact support',
|
|
4
|
+
});
|
|
5
|
+
export function meadowAppLinks(app, labels = DEFAULT_MEADOW_APP_LINK_LABELS, overrides = {}) {
|
|
6
|
+
const privacyUrl = overrides.privacyUrl === undefined ? app.privacyUrl : overrides.privacyUrl;
|
|
7
|
+
const supportEmail = overrides.supportEmail === undefined ? app.supportEmail : overrides.supportEmail;
|
|
8
|
+
const links = [];
|
|
9
|
+
if (privacyUrl && /^https?:\/\//i.test(privacyUrl)) {
|
|
10
|
+
links.push({ kind: 'privacy', label: labels.privacy, href: privacyUrl });
|
|
11
|
+
}
|
|
12
|
+
if (supportEmail && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(supportEmail)) {
|
|
13
|
+
links.push({ kind: 'support', label: labels.support, href: `mailto:${supportEmail}` });
|
|
14
|
+
}
|
|
15
|
+
return Object.freeze(links.map((link) => Object.freeze(link)));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=app-links.model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-links.model.js","sourceRoot":"","sources":["../../src/ui/app-links.model.ts"],"names":[],"mappings":"AAoBA,MAAM,CAAC,MAAM,8BAA8B,GAAkC,MAAM,CAAC,MAAM,CAAC;IACzF,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,iBAAiB;CAC3B,CAAC,CAAC;AAEH,MAAM,UAAU,cAAc,CAC5B,GAA8B,EAC9B,SAAwC,8BAA8B,EACtE,YAA8C,EAAE;IAEhD,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC;IAC9F,MAAM,YAAY,GAChB,SAAS,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC;IACnF,MAAM,KAAK,GAAoB,EAAE,CAAC;IAElC,IAAI,UAAU,IAAI,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACnD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,YAAY,IAAI,4BAA4B,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QACpE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,YAAY,EAAE,EAAE,CAAC,CAAC;IACzF,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { MeadowAppBuildComponent } from './app-build.component.js';
|
|
2
|
+
export { DEFAULT_MEADOW_APP_BUILD_LABELS, formatMeadowAppBuild, type MeadowAppBuildLabels, } from './app-build.model.js';
|
|
3
|
+
export { MeadowAppLinksComponent } from './app-links.component.js';
|
|
4
|
+
export { DEFAULT_MEADOW_APP_LINK_LABELS, meadowAppLinks, type MeadowAppLink, type MeadowAppLinkKind, type MeadowAppLinkLabels, type MeadowAppLinkOverrides, } from './app-links.model.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EACL,+BAA+B,EAC/B,oBAAoB,EACpB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EACL,8BAA8B,EAC9B,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,GAC5B,MAAM,sBAAsB,CAAC"}
|
package/dist/ui/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { MeadowAppBuildComponent } from './app-build.component.js';
|
|
2
|
+
export { DEFAULT_MEADOW_APP_BUILD_LABELS, formatMeadowAppBuild, } from './app-build.model.js';
|
|
3
|
+
export { MeadowAppLinksComponent } from './app-links.component.js';
|
|
4
|
+
export { DEFAULT_MEADOW_APP_LINK_LABELS, meadowAppLinks, } from './app-links.model.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EACL,+BAA+B,EAC/B,oBAAoB,GAErB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EACL,8BAA8B,EAC9B,cAAc,GAKf,MAAM,sBAAsB,CAAC"}
|
package/docs/CLI.md
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
# Meadow CLI
|
|
2
|
+
|
|
3
|
+
The Meadow CLI turns an app idea into a validated standalone repository with the repetitive mobile
|
|
4
|
+
foundation already installed. It intentionally generates ordinary project files: the app owns its
|
|
5
|
+
product code and design, while Meadow supplies the common toolchain, integrations, checks, and release
|
|
6
|
+
guardrails.
|
|
7
|
+
|
|
8
|
+
Read the [Meadow Platform guide](PLATFORM_GUIDE.md) first for the overall idea-to-release system,
|
|
9
|
+
capability map, ownership boundaries, and current maturity limits.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
- Node 24.15.x and npm 11
|
|
14
|
+
- Git
|
|
15
|
+
- Xcode for local iOS builds
|
|
16
|
+
- Android Studio/JDK 21 for local Android builds
|
|
17
|
+
- GitHub CLI only when creating a remote repository
|
|
18
|
+
|
|
19
|
+
Install `@meadow-studio/platform` from npm at an exact version, then run `meadow` through its package
|
|
20
|
+
binary. During platform development, a local file installation is supported.
|
|
21
|
+
|
|
22
|
+
## Create an app
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
meadow new <name>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The app stays at the repository root. A second, static project is created in `website/` with home,
|
|
29
|
+
support, privacy, and terms pages. Both projects share one Git repository. To plan a subdomain, pass
|
|
30
|
+
`--website-base-domain meadow-development.app`; Flockbook then gets
|
|
31
|
+
`https://flockbook.meadow-development.app/` in `links.websiteUrl`. The domain is optional until it
|
|
32
|
+
is purchased. DNS, hosting, TLS, and publication are separate setup steps.
|
|
33
|
+
|
|
34
|
+
The privacy page starts with Meadow Development's publisher and support details, and reusable
|
|
35
|
+
explanations of the separately consented Firebase Analytics and Crashlytics services. New app
|
|
36
|
+
configs use `oestbalmer@gmail.com` as the support email unless another address is supplied.
|
|
37
|
+
The page is a draft with `noindex`: review the final app's data, events, retention, deletion,
|
|
38
|
+
website hosting, publisher address, and effective date before publication. The generated page
|
|
39
|
+
must match actual native behavior and store privacy disclosures.
|
|
40
|
+
|
|
41
|
+
Interactive creation asks for the display name, bundle/application ID, optional website base domain,
|
|
42
|
+
store links, supported orientation and device classes, and whether the app needs RevenueCat or Supabase. Firebase
|
|
43
|
+
Analytics and Crashlytics are part of the base stack but remain unconfigured until app-owned native
|
|
44
|
+
configuration is supplied.
|
|
45
|
+
|
|
46
|
+
Useful options:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
--yes Use safe defaults without prompts
|
|
50
|
+
--config <file> Read answers or a full Meadow config from JSON
|
|
51
|
+
--website-base-domain <name> Derive the companion subdomain from the app slug
|
|
52
|
+
--directory <path> Choose the parent directory
|
|
53
|
+
--github Create and push a GitHub repository
|
|
54
|
+
--github-owner <owner> Choose a GitHub account or organization
|
|
55
|
+
--visibility <value> private, internal, or public; defaults to private
|
|
56
|
+
--no-install Write files without installing or validating
|
|
57
|
+
--no-git Do not create the local Git repository
|
|
58
|
+
--skip-visual-baselines Defer baseline screenshot generation
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Creation is atomic. The final directory appears only after dependency installation, formatting,
|
|
62
|
+
native-project generation, unit tests, linting, and production/device builds succeed. A normal
|
|
63
|
+
creation also installs Chromium and creates initial phone and tablet screenshot baselines. The
|
|
64
|
+
repository receives an initial gitmoji commit unless `--no-git` is used.
|
|
65
|
+
|
|
66
|
+
Each generated repository includes:
|
|
67
|
+
|
|
68
|
+
- Angular 22 standalone application code and strict TypeScript;
|
|
69
|
+
- a separate, dependency-free `website/` project with editable home, support, privacy, and terms pages;
|
|
70
|
+
- Capacitor 8 iOS and Android projects;
|
|
71
|
+
- Firebase Analytics and Crashlytics native dependencies;
|
|
72
|
+
- optional RevenueCat and Supabase client dependencies;
|
|
73
|
+
- provider-neutral `@meadow-studio/platform` runtime APIs;
|
|
74
|
+
- Vitest unit tests with 80% line/function/statement and 70% branch thresholds;
|
|
75
|
+
- Playwright phone and tablet screenshot tests;
|
|
76
|
+
- formatting, linting, web, device, Android, and unsigned iOS build commands;
|
|
77
|
+
- GitHub Actions for pull-request verification and manual visual-baseline generation;
|
|
78
|
+
- exact dependency versions, immutable GitHub Action hashes, and dependency auditing;
|
|
79
|
+
- release, CI, signing, and store checklists;
|
|
80
|
+
- an editable root-level `PRODUCT_BRIEF.md` template for audience, core jobs, product rules,
|
|
81
|
+
experience, the first usable flow, and deferred ideas;
|
|
82
|
+
- an `inspiration/README.md` where app owners can add visual references with notes about what to
|
|
83
|
+
borrow for specific screens or flows;
|
|
84
|
+
- an `AGENTS.md` pointer to the capability guide bundled with the app's pinned platform version and
|
|
85
|
+
a repository-local `.agents/skills/meadow-app-development/SKILL.md` for normal app development; and
|
|
86
|
+
- a `.gitignore` that excludes generated web/native output, local configuration, signing files,
|
|
87
|
+
and test reports.
|
|
88
|
+
|
|
89
|
+
The template deliberately does not include Ionic or Meadow Design. An app may adopt either as an
|
|
90
|
+
app-owned decision, but neither is part of the Meadow foundation.
|
|
91
|
+
|
|
92
|
+
## Adopt an existing app
|
|
93
|
+
|
|
94
|
+
In a newly created, empty Git checkout, `meadow init` generates the full app and companion website
|
|
95
|
+
directly in that repository. The checkout must contain only `.git`; Meadow preserves its Git history
|
|
96
|
+
and remote and does not create or push another repository. The display name defaults to the checkout
|
|
97
|
+
directory name, and the command prompts for app details unless `--yes` is supplied. Use
|
|
98
|
+
`--website-base-domain meadow-development.app` to plan the app's subdomain. `--dry-run` lists the
|
|
99
|
+
files without writing. With installation enabled, initialization runs the same app, native, and
|
|
100
|
+
visual validation as `meadow new`. Build tools may print paths inside a temporary `.meadow-init-*`
|
|
101
|
+
directory during validation; Meadow moves the completed project into the existing checkout only after
|
|
102
|
+
every step succeeds.
|
|
103
|
+
|
|
104
|
+
The generated project includes Firebase Analytics and Crashlytics dependencies by default. Both
|
|
105
|
+
native collection switches start disabled; production collection requires each service's separate
|
|
106
|
+
consent and app-owned Firebase configuration. The app must provide the actual consent interface.
|
|
107
|
+
|
|
108
|
+
For an existing Angular and Capacitor application, `init` follows the adoption flow below.
|
|
109
|
+
|
|
110
|
+
Use `init` inside an existing Angular 22 and Capacitor 8 application:
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
meadow init --dry-run
|
|
114
|
+
meadow init
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Initialization also creates `website/` if it is missing. If the app already has a website project
|
|
118
|
+
in that directory, Meadow leaves it intact. `--dry-run` includes the website plan without writing.
|
|
119
|
+
It also adds `PRODUCT_BRIEF.md` when missing and preserves an existing brief.
|
|
120
|
+
It creates `inspiration/README.md` when missing and preserves existing reference notes and images.
|
|
121
|
+
The optional `--website-base-domain` sets a missing planned website URL; it does not replace an
|
|
122
|
+
existing URL in `meadow.config.json`.
|
|
123
|
+
|
|
124
|
+
The command inspects `package.json`, `angular.json`, and the Capacitor configuration before making
|
|
125
|
+
changes. It infers the display name, application ID, package version, and whether RevenueCat or
|
|
126
|
+
Supabase is already in use. Unsupported Angular or Capacitor major versions are rejected before any
|
|
127
|
+
file is written. Interactive mode asks for a missing website base domain and whether to add optional
|
|
128
|
+
providers that are not already detectable; use `--config` to override other inferred metadata.
|
|
129
|
+
|
|
130
|
+
The adoption plan can:
|
|
131
|
+
|
|
132
|
+
- create `meadow.config.json` when it is missing, while preserving an existing valid configuration;
|
|
133
|
+
- install a pinned `@meadow-studio/platform` and missing shared provider dependencies;
|
|
134
|
+
- add only missing Meadow-owned package scripts, leaving existing scripts unchanged;
|
|
135
|
+
- create `.nvmrc` only when the app does not already have one;
|
|
136
|
+
- add or refresh marked Meadow sections in `AGENTS.md`, `.gitignore`, and `.env.example`;
|
|
137
|
+
- add the app-development skill when it is missing, preserving any existing copy; and
|
|
138
|
+
- install dependencies and finish by printing the complete `meadow doctor` result.
|
|
139
|
+
|
|
140
|
+
Useful options:
|
|
141
|
+
|
|
142
|
+
```text
|
|
143
|
+
--dry-run Print the complete plan without writing or installing
|
|
144
|
+
--yes Accept inferred values without prompts
|
|
145
|
+
--config <file> Override inferred answers with JSON
|
|
146
|
+
--website-base-domain <name> Set a missing planned companion website URL
|
|
147
|
+
--directory <path> Initialize a project outside the current directory
|
|
148
|
+
--platform-spec <value> Install or intentionally replace the platform dependency spec
|
|
149
|
+
--no-install Update files without running npm install
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Managed sections are delimited by `meadow-platform:start` and `meadow-platform:end`. Re-running `init`
|
|
153
|
+
updates only those sections and is otherwise idempotent. A malformed or half-present marker pair is
|
|
154
|
+
treated as an error rather than risking app-owned content.
|
|
155
|
+
|
|
156
|
+
`init` establishes the Meadow control plane; it does not blindly replace application code, existing
|
|
157
|
+
CI, test configuration, Angular or Capacitor versions, or app-specific architecture. `meadow doctor`
|
|
158
|
+
reports missing pieces of the complete release-oriented foundation so they can be adopted
|
|
159
|
+
deliberately. Ionic and other app-owned dependencies are retained and reported without becoming
|
|
160
|
+
Meadow Platform dependencies.
|
|
161
|
+
|
|
162
|
+
## Synchronize typed configuration
|
|
163
|
+
|
|
164
|
+
`meadow.config.json` version 2 is the source of truth for durable application and release intent:
|
|
165
|
+
|
|
166
|
+
- display name, slug, and separate iOS and Android identifiers;
|
|
167
|
+
- enabled platforms, device classes, and orientation;
|
|
168
|
+
- semantic version, build number, and release channel;
|
|
169
|
+
- development, test, and production runtime behavior;
|
|
170
|
+
- support, privacy, terms, website, App Store, and Play Store links;
|
|
171
|
+
- enabled Firebase, RevenueCat, Supabase, local-data, and local-notification capabilities;
|
|
172
|
+
- RevenueCat entitlement, offering, and product identifiers;
|
|
173
|
+
- the Supabase project reference and names of variables containing public client configuration;
|
|
174
|
+
- analytics events and typed property definitions; and
|
|
175
|
+
- CI screenshot viewports.
|
|
176
|
+
|
|
177
|
+
For a Meadow-generated companion site, `meadow sync` also updates `website/site.config.json` with
|
|
178
|
+
the app name, description, planned URL, and support email. Website page content and styling stay
|
|
179
|
+
app-owned. Use `npm run website:start` to preview the site and `npm run website:check` to build it.
|
|
180
|
+
Draft support and legal content must be replaced and `noindex` removed before publication.
|
|
181
|
+
|
|
182
|
+
After editing the config, run:
|
|
183
|
+
|
|
184
|
+
```sh
|
|
185
|
+
meadow sync
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Synchronization updates:
|
|
189
|
+
|
|
190
|
+
- `package.json` release metadata, platform/capability dependencies, and Meadow scripts;
|
|
191
|
+
- `capacitor.config.ts` app identity and generated environment files;
|
|
192
|
+
- app-owned generated runtime configuration and typed analytics APIs under `src/app/meadow/`;
|
|
193
|
+
- the local-service configuration generator used before development and production builds;
|
|
194
|
+
- Playwright viewport projects;
|
|
195
|
+
- Android application ID, display name, orientation, version, and build metadata when present; and
|
|
196
|
+
- iOS bundle ID, display name, orientation, version, and build metadata when present.
|
|
197
|
+
|
|
198
|
+
When dependencies change, the command runs `npm install`; use `--no-install` when a separate process
|
|
199
|
+
will update the lockfile. Generated TypeScript and configuration files carry a warning header. Meadow
|
|
200
|
+
will not replace a conflicting unmarked file at one of those paths.
|
|
201
|
+
|
|
202
|
+
Use the read-only form locally and in CI:
|
|
203
|
+
|
|
204
|
+
```sh
|
|
205
|
+
meadow sync --check
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
It exits unsuccessfully when normalized configuration, dependencies, generated source, native
|
|
209
|
+
metadata, or testing viewports have drifted. `meadow doctor` includes the same drift check.
|
|
210
|
+
|
|
211
|
+
Analytics definitions generate an app-owned, compile-time API. For example:
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{
|
|
215
|
+
"analytics": {
|
|
216
|
+
"events": {
|
|
217
|
+
"pushups_logged": {
|
|
218
|
+
"properties": {
|
|
219
|
+
"reps": { "type": "integer", "required": true },
|
|
220
|
+
"source": {
|
|
221
|
+
"type": "string",
|
|
222
|
+
"required": false,
|
|
223
|
+
"values": ["home", "notification"]
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
This produces an `AppAnalytics` wrapper that rejects unknown events, missing required properties,
|
|
233
|
+
wrong value types, and invalid enumerated strings during TypeScript compilation.
|
|
234
|
+
|
|
235
|
+
Never put credentials, service-role keys, signing material, or other secrets in
|
|
236
|
+
`meadow.config.json`. Supabase and RevenueCat configuration records variable names and public product
|
|
237
|
+
identifiers; actual environment values remain external. Generated apps run `npm run
|
|
238
|
+
services:config` before serving or building. It reads local public client values and writes the
|
|
239
|
+
ignored `public/meadow-service-config.js` runtime asset.
|
|
240
|
+
|
|
241
|
+
## Add local notifications
|
|
242
|
+
|
|
243
|
+
From a generated app, add native local notifications with:
|
|
244
|
+
|
|
245
|
+
```sh
|
|
246
|
+
meadow add notifications
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
The recipe pins `@capacitor/local-notifications`, updates `meadow.config.json`, installs the package,
|
|
250
|
+
synchronizes each existing native project, updates the generated runtime and release checklist,
|
|
251
|
+
and runs the app checks before marking the capability configured. If installation or native sync
|
|
252
|
+
is interrupted, rerun the same command; an enabled but unconfigured capability is resumable.
|
|
253
|
+
|
|
254
|
+
The runtime does not request permission during initialization or scheduling. The app explains the
|
|
255
|
+
benefit and calls `MeadowNotificationService.requestPermission()` from a user action. The app also
|
|
256
|
+
owns notification IDs, copy, schedule rules, Android channels, tap navigation, and analytics.
|
|
257
|
+
Meadow owns provider adaptation, permission state, one-off and recurring calendar scheduling,
|
|
258
|
+
replace/cancel/pending operations, tap events, safe web behavior, and normalized failures.
|
|
259
|
+
|
|
260
|
+
Android schedules are inexact by default. Do not add exact-alarm permission unless a concrete app
|
|
261
|
+
requires exact timing and its store/disclosure implications have been reviewed. Before release,
|
|
262
|
+
test grant and denial behavior, scheduling, replacement, cancellation, the Android channel, and
|
|
263
|
+
tap navigation on both enabled platforms.
|
|
264
|
+
|
|
265
|
+
## Add local data
|
|
266
|
+
|
|
267
|
+
From a generated app, add the proven local-data foundation with:
|
|
268
|
+
|
|
269
|
+
```sh
|
|
270
|
+
meadow add local-data
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
The recipe installs pinned SQLite dependencies, synchronizes both native projects, and generates:
|
|
274
|
+
|
|
275
|
+
- a Meadow-owned `LocalDatabase` wrapper with parameterized queries, writes, and transactions;
|
|
276
|
+
- sequential, immutable database migrations;
|
|
277
|
+
- a small typed JSON document store for settings and other simple records;
|
|
278
|
+
- an example unit test and app-repository guidance;
|
|
279
|
+
- the SQLite WebAssembly runtime for browser development; and
|
|
280
|
+
- Android backup exclusions plus local-data release checks.
|
|
281
|
+
|
|
282
|
+
iOS and Android use native SQLite. Browser development uses the same SQLite engine persisted in
|
|
283
|
+
IndexedDB, avoiding a second storage behavior just for web previews. Application-specific tables,
|
|
284
|
+
models, validation, and repositories stay in the app rather than `@meadow-studio/platform`.
|
|
285
|
+
|
|
286
|
+
If installation or validation is interrupted, rerun the same command. Meadow records the incomplete
|
|
287
|
+
recipe, preserves any generated file you changed while fixing the problem, fills in missing files,
|
|
288
|
+
and validates the capability again before marking it configured.
|
|
289
|
+
|
|
290
|
+
After adding a migration, update `services.localData.databaseVersion` in `meadow.config.json` to match
|
|
291
|
+
the final migration. Never edit a migration that has shipped. Before release, test both a fresh
|
|
292
|
+
database and an upgrade from the previous app version, verify deletion/reset behavior, and review
|
|
293
|
+
the generated SQLCipher export-compliance checklist item.
|
|
294
|
+
|
|
295
|
+
## Configure integrations
|
|
296
|
+
|
|
297
|
+
Run configuration commands from the generated app directory:
|
|
298
|
+
|
|
299
|
+
```sh
|
|
300
|
+
meadow configure firebase \
|
|
301
|
+
--google-services /path/to/google-services.json \
|
|
302
|
+
--google-service-info /path/to/GoogleService-Info.plist
|
|
303
|
+
|
|
304
|
+
meadow configure revenuecat \
|
|
305
|
+
--ios-key <public-sdk-key> \
|
|
306
|
+
--android-key <public-sdk-key> \
|
|
307
|
+
--entitlement <id> \
|
|
308
|
+
--offering <id>
|
|
309
|
+
|
|
310
|
+
meadow configure supabase \
|
|
311
|
+
--url https://<project>.supabase.co \
|
|
312
|
+
--publishable-key <publishable-key>
|
|
313
|
+
|
|
314
|
+
meadow configure assets --source /path/to/icon.png
|
|
315
|
+
meadow configure signing
|
|
316
|
+
meadow configure store --support-email <email> --support-url <url> \
|
|
317
|
+
--privacy-url <url> --terms-url <url> --website-url <url> \
|
|
318
|
+
--apple-app-id <id> --app-store-url <url> --play-store-url <url>
|
|
319
|
+
meadow configure github --owner <owner> --visibility private
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
RevenueCat and Supabase client values go in the ignored `.env.meadow.local`. RevenueCat configuration
|
|
323
|
+
requires a public key only for each enabled native platform, validates the `appl_`, `goog_`, or
|
|
324
|
+
`test_` key prefix, installs the pinned SDK, synchronizes Capacitor, and records the app-owned
|
|
325
|
+
offering and entitlement identifiers. Builds convert those keys into the ignored runtime asset;
|
|
326
|
+
`MeadowPurchaseService` then owns initialization, product loading, entitlement state, purchase,
|
|
327
|
+
restore, and provider-error normalization.
|
|
328
|
+
|
|
329
|
+
The Supabase command rejects service-role and secret keys; release readiness still requires
|
|
330
|
+
explicit grants, row-level security, storage policies, and database tests. Firebase configuration
|
|
331
|
+
is required only for the enabled native platforms. The command validates and copies those
|
|
332
|
+
app-owned files, synchronizes Capacitor, installs the Android build plugins, registers the iOS
|
|
333
|
+
configuration file as an app resource, and keeps Analytics and Crashlytics collection off at the
|
|
334
|
+
native layer until the user grants consent. Firebase files are never added to the platform
|
|
335
|
+
package.
|
|
336
|
+
|
|
337
|
+
The application owns the consent screen and copy. Apply the resulting choices through
|
|
338
|
+
`MeadowAnalyticsService.setConsent(...)` and `MeadowCrashReportingService.setConsent(...)`. Choices are
|
|
339
|
+
persisted separately. Development and test environments remain disabled even when a stored
|
|
340
|
+
production consent choice exists.
|
|
341
|
+
|
|
342
|
+
## Diagnose and release
|
|
343
|
+
|
|
344
|
+
```sh
|
|
345
|
+
meadow doctor
|
|
346
|
+
meadow doctor --json
|
|
347
|
+
meadow version patch test
|
|
348
|
+
meadow release-check all
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
`meadow doctor` checks the pinned stack, required files and scripts, native projects, Meadow-generated
|
|
352
|
+
website pages, the local-data
|
|
353
|
+
runtime when enabled, Firebase dependencies, native opt-in defaults, the bundled iOS Firebase
|
|
354
|
+
resource, RevenueCat dependency, platform keys and catalog identifiers, local-notification
|
|
355
|
+
dependency and native synchronization, visual baselines, and integration state. `meadow version`
|
|
356
|
+
increments or sets the semantic app version, increments the build
|
|
357
|
+
number, and synchronizes web, Android, and iOS metadata.
|
|
358
|
+
|
|
359
|
+
`meadow release-check` turns missing native projects, baselines, or enabled-service configuration into
|
|
360
|
+
failures and then runs the complete quality, visual, and selected native build gates. Production
|
|
361
|
+
also requires a website URL plus support, privacy, and terms information.
|
|
362
|
+
|
|
363
|
+
## Pull-request CI
|
|
364
|
+
|
|
365
|
+
Every generated pull request runs four independent jobs:
|
|
366
|
+
|
|
367
|
+
1. formatting, linting, dependency audit, coverage-gated unit tests, production app web build,
|
|
368
|
+
and companion website build;
|
|
369
|
+
2. deterministic Playwright screenshot comparisons at phone and tablet sizes;
|
|
370
|
+
3. Android debug compilation on Linux with JDK 21; and
|
|
371
|
+
4. an unsigned iOS simulator build on macOS.
|
|
372
|
+
|
|
373
|
+
Successful Android jobs upload `android-debug-apk`, a downloadable debug APK in the Actions run.
|
|
374
|
+
The visual job uploads `playwright-report` with the HTML report and screenshot results. Playwright
|
|
375
|
+
also adds GitHub test annotations; a separate trusted workflow comments on a PR when screenshot
|
|
376
|
+
comparisons fail, naming the failures and linking to the downloadable report. This reports failures
|
|
377
|
+
without requiring a preview host or a custom token for inline image attachments.
|
|
378
|
+
|
|
379
|
+
CI installs the exact public `@meadow-studio/platform` version from npm using the committed lockfile. No
|
|
380
|
+
Meadow package secret or source-repository access is needed, including for fork pull requests. The
|
|
381
|
+
version must be published before a default `meadow init` install can run.
|
|
382
|
+
|
|
383
|
+
CI never updates screenshots implicitly. The visual comparison and baseline workflow both use the
|
|
384
|
+
same pinned macOS runner family as the local Meadow development environment. Use the manual **Generate
|
|
385
|
+
visual baselines** workflow to produce candidates, inspect the artifact, then commit intentional
|
|
386
|
+
changes. Generated visual test commands select an available local port for their Angular server, so
|
|
387
|
+
an unrelated process on Angular's default port 4200 does not block initialization or local screenshot
|
|
388
|
+
tests. Playwright never reuses an existing server for these checks.
|
|
389
|
+
When Playwright is invoked directly, its generated configuration defaults to port 4400.
|