Skip to content

Commit f3fea3c

Browse files
committed
Add AGENTS guide for app-platform contributors
Document the repo structure, architecture rules, authoritative docs, and platform-specific run/test commands for the sample, recipes, and starter apps. An AGENTS.md file gives contributors and coding agents a single entry point for understanding how this repository is organized, where the real documentation lives, and how to execute common workflows without rediscovering them from build files and CI.
1 parent 7f61184 commit f3fea3c

File tree

1 file changed

+283
-0
lines changed

1 file changed

+283
-0
lines changed

AGENTS.md

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
# AGENTS.md
2+
3+
## Purpose
4+
5+
This repository is the Amazon App Platform: a Kotlin Multiplatform application framework plus example applications and a starter blueprint. The core concepts are documented in [`docs/`](docs/) and implemented across reusable library modules plus a few app entrypoints.
6+
7+
Start here before changing code:
8+
9+
- `README.md`
10+
- `docs/index.md`
11+
- `docs/setup.md`
12+
- `docs/module-structure.md`
13+
- `docs/di.md`
14+
- `docs/presenter.md`
15+
- `docs/renderer.md`
16+
- `docs/template.md`
17+
- `docs/testing.md`
18+
- `settings.gradle`
19+
- `buildSrc/src/main/kotlin/software/amazon/app/platform/gradle/buildsrc/`
20+
21+
`mkdocs.yml` is the docs site manifest. The Pages workflow builds Wasm artifacts for `:sample:app` and `:recipes:app` and copies them into `docs/web/` before publishing.
22+
23+
## Repo Shape
24+
25+
Important top-level areas:
26+
27+
- `gradle-plugin/`: the published `software.amazon.app.platform` Gradle plugin.
28+
- `buildSrc/`: repo-local convention plugins used by this repository’s own modules. This is where platform targets, emulator config, desktop packaging, and Wasm defaults are defined.
29+
- `docs/`: framework documentation. Treat this as the authoritative product docs.
30+
- `sample/`: the main sample app. This is the best place to study end-to-end usage of scopes, DI, presenters, renderers, templates, fakes, and robots.
31+
- `recipes/`: a second example app plus reusable “recipe” patterns, including the separate `recipesIosApp` SwiftUI/Xcode wrapper.
32+
- `blueprints/starter/`: a standalone starter app template with its own Gradle wrapper, version catalog, and README.
33+
34+
Core framework module families:
35+
36+
- `scope`, `di-common`
37+
- `presenter`, `presenter-molecule`
38+
- `renderer`, `renderer-android-view`, `renderer-compose-multiplatform`
39+
- `robot`, `robot-compose-multiplatform`, `robot-internal`
40+
- `kotlin-inject`, `kotlin-inject-extensions`
41+
- `metro`, `metro-extensions`
42+
- `ksp-common`
43+
44+
## Architecture Rules
45+
46+
The most important repo rule is the module structure documented in `docs/module-structure.md`.
47+
48+
- `:public` modules expose reusable APIs and shared code.
49+
- `:impl` modules contain concrete implementations.
50+
- `:testing` modules hold shared fakes and test helpers.
51+
- `:*-robots` modules hold shared UI robots.
52+
- `:app` modules are the only modules allowed to depend on `:impl` modules.
53+
54+
Do not introduce a dependency from a non-`:app` module to an `:impl` module. The build enforces this via `checkModuleStructureDependencies`.
55+
56+
The framework’s architectural flow is:
57+
58+
1. `Scope` and DI assemble objects for a lifecycle boundary.
59+
2. `MoleculePresenter` implementations produce models.
60+
3. App-specific `Template` presenters wrap the root model tree.
61+
4. `RendererFactory` resolves platform renderers for those models.
62+
5. Thin platform entrypoints bootstrap the root scope and start rendering.
63+
64+
Representative entrypoints:
65+
66+
- Android: `sample/app/src/androidMain/.../AndroidApplication.kt`, `MainActivity.kt`
67+
- iOS: `sample/app/src/iosMain/.../MainViewController.kt`, `sample/iosApp/`
68+
- Desktop: `sample/app/src/desktopMain/.../Main.kt`, `DesktopApp.kt`
69+
- Wasm: `sample/app/src/wasmJsMain/.../Main.kt`
70+
71+
## Toolchain
72+
73+
Local development should match CI as closely as possible. These versions live in `gradle/libs.versions.toml`.
74+
75+
Expected warning: Gradle prints a warning that configuration-on-demand is not supported for Wasm targets. This is noisy but currently normal in this repo.
76+
77+
## Run The Apps
78+
79+
There are three app-style entrypoints to care about:
80+
81+
- `:sample:app`: main sample app inside the root build.
82+
- `:recipes:app`: recipe/demo app inside the root build.
83+
- `blueprints/starter`: standalone starter app; run commands from inside that directory or use its own `./gradlew`.
84+
85+
### Android
86+
87+
Install the debug APK onto a connected device or emulator:
88+
89+
```bash
90+
./gradlew :sample:app:installDebug
91+
./gradlew :recipes:app:installDebug
92+
```
93+
94+
For the standalone starter:
95+
96+
```bash
97+
cd blueprints/starter
98+
./gradlew :app:installDebug
99+
```
100+
101+
`buildSrc/.../BaseAndroidPlugin.kt` configures managed emulator tests with a local device named `emulator` using a Pixel 3 / API 30 `aosp-atd` image.
102+
103+
### iOS
104+
105+
Sample app:
106+
107+
```bash
108+
open sample/iosApp/iosApp.xcodeproj
109+
```
110+
111+
Recipe app:
112+
113+
```bash
114+
open recipes/recipesIosApp/recipesIosApp.xcodeproj
115+
```
116+
117+
The Xcode projects include a shell build phase that calls Gradle:
118+
119+
- `:sample:app:embedAndSignAppleFrameworkForXcode`
120+
- `:recipes:app:embedAndSignAppleFrameworkForXcode`
121+
122+
If you only want to build the Kotlin framework without opening Xcode:
123+
124+
```bash
125+
./gradlew :sample:app:linkDebugFrameworkIosSimulatorArm64
126+
./gradlew :recipes:app:linkDebugFrameworkIosSimulatorArm64
127+
```
128+
129+
CI builds the sample iOS wrapper with `xcodebuild -project sample/iosApp/iosApp.xcodeproj -scheme iosApp ... -destination id=<simulator-id>`. Use `xcrun simctl list devices` to pick a simulator if you need a pure CLI invocation.
130+
131+
### Desktop
132+
133+
Run the desktop Compose app:
134+
135+
```bash
136+
./gradlew :sample:app:run
137+
./gradlew :recipes:app:run
138+
```
139+
140+
Starter blueprint:
141+
142+
```bash
143+
cd blueprints/starter
144+
./gradlew :app:run
145+
```
146+
147+
Desktop packaging tasks such as `packageDmg`, `packageDeb`, and `packageMsi` are available on app modules.
148+
149+
### Wasm
150+
151+
Development server:
152+
153+
```bash
154+
./gradlew :sample:app:wasmJsBrowserDevelopmentRun
155+
./gradlew :recipes:app:wasmJsBrowserDevelopmentRun
156+
```
157+
158+
Production bundle:
159+
160+
```bash
161+
./gradlew :sample:app:wasmJsBrowserDistribution
162+
./gradlew :recipes:app:wasmJsBrowserDistribution
163+
```
164+
165+
Starter blueprint:
166+
167+
```bash
168+
cd blueprints/starter
169+
./gradlew :app:wasmJsBrowserDevelopmentRun
170+
```
171+
172+
After a production Wasm build, serve the generated files from:
173+
174+
- `sample/app/build/dist/wasmJs/productionExecutable/`
175+
- `recipes/app/build/dist/wasmJs/productionExecutable/`
176+
177+
The starter README suggests `npx http-server` from the production output directory.
178+
179+
## Run The Tests
180+
181+
### Repo-wide CI-style checks
182+
183+
These are the main root-level quality gates used by GitHub Actions:
184+
185+
```bash
186+
./gradlew testDebugUnitTest
187+
./gradlew iosSimulatorArm64Test -Pkotlin.incremental.native=true
188+
./gradlew desktopTest
189+
./gradlew linuxX64Test
190+
./gradlew wasmJsTest
191+
./gradlew apiCheck
192+
./gradlew ktfmtCheck
193+
./gradlew detekt
194+
./gradlew lint
195+
./gradlew checkModuleStructureDependencies
196+
```
197+
198+
### Sample app tests by platform
199+
200+
Android instrumented UI tests:
201+
202+
```bash
203+
./gradlew :sample:app:emulatorCheck
204+
```
205+
206+
Or against a manually started device:
207+
208+
```bash
209+
./gradlew :sample:app:connectedDebugAndroidTest
210+
```
211+
212+
Desktop UI tests:
213+
214+
```bash
215+
./gradlew :sample:app:desktopTest
216+
```
217+
218+
Android unit tests:
219+
220+
```bash
221+
./gradlew :sample:app:testDebugUnitTest
222+
```
223+
224+
iOS simulator tests:
225+
226+
```bash
227+
./gradlew :sample:app:iosSimulatorArm64Test -Pkotlin.incremental.native=true
228+
```
229+
230+
All sample app target tests:
231+
232+
```bash
233+
./gradlew :sample:app:allTests
234+
```
235+
236+
### Where tests live
237+
238+
- Android UI tests: `sample/app/src/androidInstrumentedTest/`
239+
- Desktop UI tests: `sample/app/src/desktopTest/`
240+
- Shared unit tests: `sample/*/src/commonTest/`
241+
- Shared fakes: `sample/user/testing/`
242+
- Shared robots: `sample/login/impl-robots/`, `sample/user/impl-robots/`
243+
244+
## Current Test Reality
245+
246+
As of this checkout:
247+
248+
- `:sample:app:desktopTest` runs successfully.
249+
- `:sample:app:testDebugUnitTest` succeeds but currently has `NO-SOURCE`.
250+
- `:sample:app:iosSimulatorArm64Test -Pkotlin.incremental.native=true` succeeds but is currently skipped because `sample/app` has no iOS test sources.
251+
- Android UI coverage for the sample app is in `androidInstrumentedTest` and is exercised through `emulatorCheck`/`connectedDebugAndroidTest`.
252+
253+
## Wasm Lockfile Caveat
254+
255+
Wasm tasks are currently strict about the committed Yarn lockfile under `kotlin-js-store/wasm/yarn.lock`.
256+
257+
If a Wasm task fails with:
258+
259+
```text
260+
Execution failed for task ':kotlinWasmStoreYarnLock'.
261+
Lock file was changed. Run the `kotlinWasmUpgradeYarnLock` task to actualize lock file
262+
```
263+
264+
then the generated `build/wasm/yarn.lock` does not match the committed lock. In this checkout, both `:sample:app:wasmJsTest` and `:sample:app:wasmJsBrowserDistribution` hit that failure.
265+
266+
Treat `kotlinWasmUpgradeYarnLock` as an intentional dependency update step, not a routine run command. If you change Wasm/npm dependencies on purpose, update and review `kotlin-js-store/wasm/yarn.lock` in the same change.
267+
268+
## Docs Workflow
269+
270+
To work on docs locally:
271+
272+
```bash
273+
cp CHANGELOG.md docs/changelog.md
274+
pip install mkdocs-material "mkdocs-material[imaging]"
275+
mkdocs serve
276+
```
277+
278+
When changing framework behavior, update both:
279+
280+
- the relevant `docs/*.md` page
281+
- the sample and/or starter code that demonstrates that behavior
282+
283+
If a change affects how consumers start a new project, also update `blueprints/starter/README.md`.

0 commit comments

Comments
 (0)