openuispec 0.1.27 → 0.1.28
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/README.md +22 -19
- package/cli/init.ts +7 -7
- package/docs/implementation-notes.md +5 -1
- package/docs/release-notes-v0.1.28.md +25 -0
- package/docs/stress-test-maturity-report.md +1 -1
- package/drift/index.ts +21 -4
- package/examples/taskflow/AGENTS.md +112 -0
- package/examples/taskflow/CLAUDE.md +112 -0
- package/examples/taskflow/generated/android/TaskFlow/README.md +43 -0
- package/examples/taskflow/generated/android/TaskFlow/app/build.gradle.kts +76 -0
- package/examples/taskflow/generated/android/TaskFlow/app/proguard-rules.pro +1 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/AndroidManifest.xml +21 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/MainActivity.kt +19 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/TaskFlowApp.kt +283 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/model/DomainModels.kt +106 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/model/SampleData.kt +57 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/components/Common.kt +109 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/HomeScreen.kt +112 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/ProjectsScreen.kt +61 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/SettingsScreen.kt +82 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/TaskDetailScreen.kt +111 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/sheets/Sheets.kt +77 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/theme/Color.kt +30 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/theme/Theme.kt +86 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/theme/Type.kt +57 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/res/values/strings.xml +155 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/res/values/themes.xml +4 -0
- package/examples/taskflow/generated/android/TaskFlow/build.gradle.kts +5 -0
- package/examples/taskflow/generated/android/TaskFlow/gradle/gradle-daemon-jvm.properties +12 -0
- package/examples/taskflow/generated/android/TaskFlow/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/examples/taskflow/generated/android/TaskFlow/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/examples/taskflow/generated/android/TaskFlow/gradle.properties +4 -0
- package/examples/taskflow/generated/android/TaskFlow/gradlew +18 -0
- package/examples/taskflow/generated/android/TaskFlow/gradlew.bat +12 -0
- package/examples/taskflow/generated/android/TaskFlow/settings.gradle.kts +18 -0
- package/examples/taskflow/generated/ios/TaskFlow/README.md +21 -0
- package/examples/taskflow/generated/ios/TaskFlow/Resources/en.lproj/Localizable.strings +115 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/App/TaskFlowApp.swift +24 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Components/AppChrome.swift +150 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Flows/TaskEditorSheet.swift +220 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Models/DomainModels.swift +122 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/CalendarView.swift +21 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/HomeView.swift +201 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/ProfileEditView.swift +48 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/ProjectDetailView.swift +59 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/ProjectsView.swift +63 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/SettingsView.swift +85 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/TaskDetailView.swift +219 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Support/AppModel.swift +320 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Support/AppSupport.swift +41 -0
- package/examples/taskflow/generated/ios/TaskFlow/project.yml +26 -0
- package/examples/taskflow/generated/web/TaskFlow/README.md +19 -0
- package/examples/taskflow/generated/web/TaskFlow/index.html +12 -0
- package/examples/taskflow/generated/web/TaskFlow/package-lock.json +1908 -0
- package/examples/taskflow/generated/web/TaskFlow/package.json +24 -0
- package/examples/taskflow/generated/web/TaskFlow/src/App.tsx +58 -0
- package/examples/taskflow/generated/web/TaskFlow/src/AppShell.tsx +55 -0
- package/examples/taskflow/generated/web/TaskFlow/src/components/Common.tsx +82 -0
- package/examples/taskflow/generated/web/TaskFlow/src/components/Modals.tsx +191 -0
- package/examples/taskflow/generated/web/TaskFlow/src/components/Nav.tsx +41 -0
- package/examples/taskflow/generated/web/TaskFlow/src/generated/messages.ts +131 -0
- package/examples/taskflow/generated/web/TaskFlow/src/hooks.ts +25 -0
- package/examples/taskflow/generated/web/TaskFlow/src/i18n.ts +39 -0
- package/examples/taskflow/generated/web/TaskFlow/src/locales.en.json +111 -0
- package/examples/taskflow/generated/web/TaskFlow/src/main.tsx +13 -0
- package/examples/taskflow/generated/web/TaskFlow/src/screens/HomeScreen.tsx +111 -0
- package/examples/taskflow/generated/web/TaskFlow/src/screens/ProjectsScreen.tsx +82 -0
- package/examples/taskflow/generated/web/TaskFlow/src/screens/SettingsScreens.tsx +132 -0
- package/examples/taskflow/generated/web/TaskFlow/src/screens/TaskDetail.tsx +105 -0
- package/examples/taskflow/generated/web/TaskFlow/src/store.ts +216 -0
- package/examples/taskflow/generated/web/TaskFlow/src/styles.css +617 -0
- package/examples/taskflow/generated/web/TaskFlow/src/types.ts +64 -0
- package/examples/taskflow/generated/web/TaskFlow/src/utils.ts +78 -0
- package/examples/taskflow/generated/web/TaskFlow/tsconfig.json +21 -0
- package/examples/taskflow/generated/web/TaskFlow/vite.config.ts +6 -0
- package/examples/taskflow/openuispec/README.md +49 -0
- package/examples/todo-orbit/AGENTS.md +44 -19
- package/examples/todo-orbit/CLAUDE.md +44 -19
- package/examples/todo-orbit/openuispec/README.md +2 -2
- package/package.json +1 -1
- package/schema/validate.ts +9 -4
- package/status/index.ts +16 -3
- /package/examples/taskflow/{contracts → openuispec/contracts}/README.md +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/action_trigger.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/collection.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/data_display.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/feedback.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/input_field.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/nav_container.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/surface.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/x_media_player.yaml +0 -0
- /package/examples/taskflow/{flows → openuispec/flows}/create_task.yaml +0 -0
- /package/examples/taskflow/{flows → openuispec/flows}/edit_task.yaml +0 -0
- /package/examples/taskflow/{locales → openuispec/locales}/en.json +0 -0
- /package/examples/taskflow/{openuispec.yaml → openuispec/openuispec.yaml} +0 -0
- /package/examples/taskflow/{platform → openuispec/platform}/android.yaml +0 -0
- /package/examples/taskflow/{platform → openuispec/platform}/ios.yaml +0 -0
- /package/examples/taskflow/{platform → openuispec/platform}/web.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/calendar.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/home.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/profile_edit.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/project_detail.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/projects.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/settings.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/task_detail.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/color.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/elevation.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/icons.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/layout.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/motion.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/spacing.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/themes.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/typography.yaml +0 -0
package/README.md
CHANGED
|
@@ -68,7 +68,7 @@ For platform generation, treat these as hard output constraints:
|
|
|
68
68
|
|
|
69
69
|
See the examples for concrete reference projects:
|
|
70
70
|
|
|
71
|
-
- [TaskFlow](./examples/taskflow/) for a compact spec covering all 7 contract families
|
|
71
|
+
- [TaskFlow](./examples/taskflow/openuispec/) for a compact spec covering all 7 contract families
|
|
72
72
|
- [Todo Orbit](./examples/todo-orbit/openuispec/) for a bilingual task app with generated iOS, Android, and web targets under `examples/todo-orbit/generated/`
|
|
73
73
|
|
|
74
74
|
## Repository structure
|
|
@@ -154,21 +154,21 @@ Every file type has a corresponding JSON Schema in `schema/`. **Read the schema
|
|
|
154
154
|
|
|
155
155
|
| File | Schema | Root key | Example |
|
|
156
156
|
|------|--------|----------|---------|
|
|
157
|
-
| `openuispec.yaml` | `openuispec.schema.json` | `spec_version` | [openuispec.yaml](./examples/taskflow/openuispec.yaml) |
|
|
158
|
-
| `screens/*.yaml` | `screen.schema.json` | `<screen_id>` | [home.yaml](./examples/taskflow/screens/home.yaml) |
|
|
159
|
-
| `flows/*.yaml` | `flow.schema.json` | `<flow_id>` | [create_task.yaml](./examples/taskflow/flows/create_task.yaml) |
|
|
160
|
-
| `platform/*.yaml` | `platform.schema.json` | `platform` | [ios.yaml](./examples/taskflow/platform/ios.yaml) |
|
|
161
|
-
| `locales/*.json` | `locale.schema.json` | (object) | [en.json](./examples/taskflow/locales/en.json) |
|
|
162
|
-
| `contracts/<name>.yaml` | `contract.schema.json` | `<contract_name>` | [input_field.yaml](./examples/taskflow/contracts/input_field.yaml) |
|
|
163
|
-
| `contracts/x_*.yaml` | `custom-contract.schema.json` | `<x_name>` | [x_media_player.yaml](./examples/taskflow/contracts/x_media_player.yaml) |
|
|
164
|
-
| `tokens/color.yaml` | `tokens/color.schema.json` | `color` | [color.yaml](./examples/taskflow/tokens/color.yaml) |
|
|
165
|
-
| `tokens/typography.yaml` | `tokens/typography.schema.json` | `typography` | [typography.yaml](./examples/taskflow/tokens/typography.yaml) |
|
|
166
|
-
| `tokens/spacing.yaml` | `tokens/spacing.schema.json` | `spacing` | [spacing.yaml](./examples/taskflow/tokens/spacing.yaml) |
|
|
167
|
-
| `tokens/elevation.yaml` | `tokens/elevation.schema.json` | `elevation` | [elevation.yaml](./examples/taskflow/tokens/elevation.yaml) |
|
|
168
|
-
| `tokens/motion.yaml` | `tokens/motion.schema.json` | `motion` | [motion.yaml](./examples/taskflow/tokens/motion.yaml) |
|
|
169
|
-
| `tokens/layout.yaml` | `tokens/layout.schema.json` | `layout` | [layout.yaml](./examples/taskflow/tokens/layout.yaml) |
|
|
170
|
-
| `tokens/themes.yaml` | `tokens/themes.schema.json` | `themes` | [themes.yaml](./examples/taskflow/tokens/themes.yaml) |
|
|
171
|
-
| `tokens/icons.yaml` | `tokens/icons.schema.json` | `icons` | [icons.yaml](./examples/taskflow/tokens/icons.yaml) |
|
|
157
|
+
| `openuispec.yaml` | `openuispec.schema.json` | `spec_version` | [openuispec.yaml](./examples/taskflow/openuispec/openuispec.yaml) |
|
|
158
|
+
| `screens/*.yaml` | `screen.schema.json` | `<screen_id>` | [home.yaml](./examples/taskflow/openuispec/screens/home.yaml) |
|
|
159
|
+
| `flows/*.yaml` | `flow.schema.json` | `<flow_id>` | [create_task.yaml](./examples/taskflow/openuispec/flows/create_task.yaml) |
|
|
160
|
+
| `platform/*.yaml` | `platform.schema.json` | `platform` | [ios.yaml](./examples/taskflow/openuispec/platform/ios.yaml) |
|
|
161
|
+
| `locales/*.json` | `locale.schema.json` | (object) | [en.json](./examples/taskflow/openuispec/locales/en.json) |
|
|
162
|
+
| `contracts/<name>.yaml` | `contract.schema.json` | `<contract_name>` | [input_field.yaml](./examples/taskflow/openuispec/contracts/input_field.yaml) |
|
|
163
|
+
| `contracts/x_*.yaml` | `custom-contract.schema.json` | `<x_name>` | [x_media_player.yaml](./examples/taskflow/openuispec/contracts/x_media_player.yaml) |
|
|
164
|
+
| `tokens/color.yaml` | `tokens/color.schema.json` | `color` | [color.yaml](./examples/taskflow/openuispec/tokens/color.yaml) |
|
|
165
|
+
| `tokens/typography.yaml` | `tokens/typography.schema.json` | `typography` | [typography.yaml](./examples/taskflow/openuispec/tokens/typography.yaml) |
|
|
166
|
+
| `tokens/spacing.yaml` | `tokens/spacing.schema.json` | `spacing` | [spacing.yaml](./examples/taskflow/openuispec/tokens/spacing.yaml) |
|
|
167
|
+
| `tokens/elevation.yaml` | `tokens/elevation.schema.json` | `elevation` | [elevation.yaml](./examples/taskflow/openuispec/tokens/elevation.yaml) |
|
|
168
|
+
| `tokens/motion.yaml` | `tokens/motion.schema.json` | `motion` | [motion.yaml](./examples/taskflow/openuispec/tokens/motion.yaml) |
|
|
169
|
+
| `tokens/layout.yaml` | `tokens/layout.schema.json` | `layout` | [layout.yaml](./examples/taskflow/openuispec/tokens/layout.yaml) |
|
|
170
|
+
| `tokens/themes.yaml` | `tokens/themes.schema.json` | `themes` | [themes.yaml](./examples/taskflow/openuispec/tokens/themes.yaml) |
|
|
171
|
+
| `tokens/icons.yaml` | `tokens/icons.schema.json` | `icons` | [icons.yaml](./examples/taskflow/openuispec/tokens/icons.yaml) |
|
|
172
172
|
|
|
173
173
|
Every token file **must** have a single root wrapper key matching its type:
|
|
174
174
|
|
|
@@ -202,12 +202,14 @@ generation:
|
|
|
202
202
|
|
|
203
203
|
Paths are relative to `openuispec.yaml`. The `.openuispec-state.json` file is stored inside each output directory and records spec file hashes plus the git baseline commit metadata captured at snapshot time.
|
|
204
204
|
|
|
205
|
+
`openuispec drift --snapshot --target <target>` requires that target output directory to already exist. If it does not, generate the target code first, then snapshot the accepted baseline.
|
|
206
|
+
|
|
205
207
|
Use the commands like this:
|
|
206
208
|
- `openuispec validate` checks schema correctness
|
|
207
209
|
- `openuispec validate semantic` checks cross-references such as locale keys, formatters, mappers, contracts, icons, navigation targets, and API endpoints
|
|
208
210
|
- `openuispec drift --target <t> --explain` explains semantic spec changes since that target's accepted baseline
|
|
209
211
|
- `openuispec prepare --target <t>` turns those changes into an AI-ready target update bundle
|
|
210
|
-
- `openuispec status` shows every target's snapshot state, baseline commit, and whether that target is behind the current spec
|
|
212
|
+
- `openuispec status` shows every target's snapshot state, baseline commit, and whether that target is behind the current spec, still needs a baseline, or has not been generated yet
|
|
211
213
|
|
|
212
214
|
If a target snapshot was created before baseline metadata was added, `--explain` and `status` will tell you to re-run `openuispec drift --snapshot --target <target>` for that target.
|
|
213
215
|
|
|
@@ -220,6 +222,7 @@ openuispec validate
|
|
|
220
222
|
openuispec drift --target ios --explain
|
|
221
223
|
openuispec prepare --target ios
|
|
222
224
|
# update the ios implementation
|
|
225
|
+
# ensure the ios output directory already exists
|
|
223
226
|
openuispec drift --snapshot --target ios
|
|
224
227
|
```
|
|
225
228
|
|
|
@@ -228,7 +231,7 @@ Meaning:
|
|
|
228
231
|
- `validate semantic` checks cross-reference integrity
|
|
229
232
|
- `drift --explain` shows semantic spec changes since that target's accepted baseline
|
|
230
233
|
- `prepare` packages those changes into an AI/developer work bundle
|
|
231
|
-
- `drift --snapshot` accepts the updated state after the target UI has been updated
|
|
234
|
+
- `drift --snapshot` accepts the updated state after the target UI has been updated and the target output directory exists
|
|
232
235
|
|
|
233
236
|
Before picking the next platform to update, run:
|
|
234
237
|
|
|
@@ -238,7 +241,7 @@ openuispec status
|
|
|
238
241
|
|
|
239
242
|
to see which targets are already up to date and which ones still need to catch up with shared spec changes.
|
|
240
243
|
|
|
241
|
-
`drift --snapshot` is bookkeeping. It does not prove that the target code matches the spec.
|
|
244
|
+
`drift --snapshot` is bookkeeping. It does not prove that the target code matches the spec, and it will not create a missing target output directory for you.
|
|
242
245
|
|
|
243
246
|
## Spec at a glance
|
|
244
247
|
|
package/cli/init.ts
CHANGED
|
@@ -171,7 +171,7 @@ Do NOT guess the file format — skipping this step will produce invalid YAML th
|
|
|
171
171
|
**Reference files inside the package (read in this order):**
|
|
172
172
|
1. \`README.md\` — schema tables, file format reference, root keys
|
|
173
173
|
2. \`spec/openuispec-v0.1.md\` — full specification (contracts, layout, expressions, etc.)
|
|
174
|
-
3. \`examples/taskflow/\` — complete working example with all file types
|
|
174
|
+
3. \`examples/taskflow/openuispec/\` — complete working example with all file types
|
|
175
175
|
4. \`schema/\` — JSON Schemas for validation
|
|
176
176
|
|
|
177
177
|
## CLI commands
|
|
@@ -183,7 +183,7 @@ openuispec validate screens # Validate only screens
|
|
|
183
183
|
openuispec status # Show cross-target baseline/drift status
|
|
184
184
|
openuispec drift --target ${targets[0]} --explain # Explain semantic spec drift
|
|
185
185
|
openuispec prepare --target ${targets[0]} # Build an AI-ready target update bundle
|
|
186
|
-
openuispec drift --snapshot --target ${targets[0]} # Snapshot current state + git baseline
|
|
186
|
+
openuispec drift --snapshot --target ${targets[0]} # Snapshot current state + git baseline after target output exists
|
|
187
187
|
\`\`\`
|
|
188
188
|
|
|
189
189
|
## Learn more
|
|
@@ -218,7 +218,7 @@ Do NOT guess the file format — skipping this step will produce invalid YAML th
|
|
|
218
218
|
**Reference files inside the package (read in this order):**
|
|
219
219
|
1. \`README.md\` — schema tables, file format reference, root wrapper keys
|
|
220
220
|
2. \`spec/openuispec-v0.1.md\` — full specification (contracts, layout, expressions, adaptive, etc.)
|
|
221
|
-
3. \`examples/taskflow/\` — complete working example with all file types
|
|
221
|
+
3. \`examples/taskflow/openuispec/\` — complete working example with all file types
|
|
222
222
|
4. \`schema/\` — JSON Schemas for every file type
|
|
223
223
|
|
|
224
224
|
These files are updated with each package version. Always read from the installed package,
|
|
@@ -276,7 +276,7 @@ Spec-first workflow:
|
|
|
276
276
|
6. Run \`openuispec drift --target <target> --explain\` to inspect semantic changes since that target's baseline.
|
|
277
277
|
7. Run \`openuispec prepare --target <target>\` to build the AI/developer work bundle for that target.
|
|
278
278
|
8. Verify the affected UI targets build/run if possible.
|
|
279
|
-
9. Only then run \`openuispec drift --snapshot --target <target>\` for affected targets.
|
|
279
|
+
9. Only then run \`openuispec drift --snapshot --target <target>\` for affected targets, after that target output directory exists.
|
|
280
280
|
10. Run \`openuispec drift --target <target> --explain\` again to confirm no spec changes remain for that target.
|
|
281
281
|
11. Use \`openuispec status\` to see which other targets are still behind the updated spec.
|
|
282
282
|
|
|
@@ -302,7 +302,7 @@ Platform-first workflow:
|
|
|
302
302
|
- \`openuispec validate semantic\` — run semantic cross-reference linting
|
|
303
303
|
- \`openuispec drift --target <t>\` — check for spec drift
|
|
304
304
|
- \`openuispec drift --target <t> --explain\` — explain semantic spec drift since the target baseline
|
|
305
|
-
- \`openuispec drift --snapshot --target <t>\` — snapshot current state
|
|
305
|
+
- \`openuispec drift --snapshot --target <t>\` — snapshot current state after the target output exists
|
|
306
306
|
- \`openuispec prepare --target <t>\` — build an AI-ready target update bundle
|
|
307
307
|
- \`openuispec status\` — show cross-target baseline/drift status
|
|
308
308
|
- \`openuispec update-rules\` — update AI rules to match installed package version
|
|
@@ -511,7 +511,7 @@ Getting started (new project):
|
|
|
511
511
|
2. Create screens in ${specDir}/screens/ (one YAML per screen)
|
|
512
512
|
3. Create flows in ${specDir}/flows/ (multi-step navigation)
|
|
513
513
|
4. Ask AI to generate native code from the spec
|
|
514
|
-
5. Run \`openuispec drift --snapshot --target ${targets[0]}\` to baseline the first accepted target state
|
|
514
|
+
5. Run \`openuispec drift --snapshot --target ${targets[0]}\` to baseline the first accepted target state after that target output directory exists
|
|
515
515
|
|
|
516
516
|
Getting started (existing project):
|
|
517
517
|
1. Ask AI to read your existing UI code and generate spec files:
|
|
@@ -527,7 +527,7 @@ Commands:
|
|
|
527
527
|
openuispec status Show cross-target baseline/drift status
|
|
528
528
|
openuispec drift --target ios --explain Explain semantic spec changes
|
|
529
529
|
openuispec prepare --target ios Build an AI-ready target update bundle
|
|
530
|
-
openuispec drift --snapshot --target ios Save current state + git baseline
|
|
530
|
+
openuispec drift --snapshot --target ios Save current state + git baseline after target output exists
|
|
531
531
|
|
|
532
532
|
AI rules have been added to CLAUDE.md and AGENTS.md.
|
|
533
533
|
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
- `openuispec status` is the cross-target overview command.
|
|
87
87
|
- Current output includes, per target:
|
|
88
88
|
- output directory
|
|
89
|
+
- whether the output directory exists
|
|
89
90
|
- snapshot present or missing
|
|
90
91
|
- snapshot timestamp
|
|
91
92
|
- baseline kind / commit / branch
|
|
@@ -95,6 +96,7 @@
|
|
|
95
96
|
- note for missing or legacy snapshots
|
|
96
97
|
- Important positioning:
|
|
97
98
|
- `status` answers "which targets are behind shared spec changes?"
|
|
99
|
+
- `status` should distinguish "needs generation" from "needs baseline"
|
|
98
100
|
- `status` does not verify code alignment
|
|
99
101
|
- Real-world behavior to document:
|
|
100
102
|
- if `web` was re-snapshotted after the new baseline metadata was added, but `ios` and `android` still have older state files, `status` should show:
|
|
@@ -111,5 +113,7 @@
|
|
|
111
113
|
5. `openuispec prepare --target <target>`
|
|
112
114
|
6. update target UI code
|
|
113
115
|
7. build/run and review
|
|
114
|
-
8.
|
|
116
|
+
8. ensure the target output directory exists
|
|
117
|
+
9. `openuispec drift --snapshot --target <target>`
|
|
115
118
|
- `drift --snapshot` should continue to be described as bookkeeping/baselining, not as proof that the target implementation matches the spec.
|
|
119
|
+
- If the target output directory does not exist yet, the CLI should direct the user to run code generation first instead of implying that snapshot can initialize an empty target.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# OpenUISpec v0.1.28
|
|
2
|
+
|
|
3
|
+
This patch supersedes `v0.1.27`.
|
|
4
|
+
|
|
5
|
+
## Fixes
|
|
6
|
+
|
|
7
|
+
- Fixed the drift/prepare onboarding dead-end for targets that have not been generated yet.
|
|
8
|
+
- `drift --snapshot` now keeps the guard against baselining an empty target.
|
|
9
|
+
- Missing-snapshot guidance now tells users to generate the target output first when the output directory does not exist.
|
|
10
|
+
- Improved `status` to distinguish:
|
|
11
|
+
- targets that need generation
|
|
12
|
+
- targets that need a baseline snapshot
|
|
13
|
+
- Updated workflow docs and generated project templates to describe the generation-first requirement before snapshotting.
|
|
14
|
+
- Stabilized the affected CLI tests in this repo by invoking TypeScript entrypoints through the `tsx` loader path instead of the IPC-based binary wrapper.
|
|
15
|
+
|
|
16
|
+
## Recommended workflow
|
|
17
|
+
|
|
18
|
+
1. `openuispec validate`
|
|
19
|
+
2. `openuispec validate semantic`
|
|
20
|
+
3. `openuispec status`
|
|
21
|
+
4. `openuispec drift --target <target> --explain`
|
|
22
|
+
5. `openuispec prepare --target <target>`
|
|
23
|
+
6. update target UI
|
|
24
|
+
7. ensure the target output directory exists
|
|
25
|
+
8. `openuispec drift --snapshot --target <target>`
|
|
@@ -14,7 +14,7 @@ This assessment stress-tested the project at four layers:
|
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
npm ci
|
|
17
|
-
npm run validate # from examples/taskflow (workspace script)
|
|
17
|
+
npm run validate # from examples/taskflow/openuispec (workspace script)
|
|
18
18
|
npx tsx ../../../schema/validate.ts # from examples/todo-orbit/openuispec
|
|
19
19
|
npx tsc --noEmit
|
|
20
20
|
for t in ios android web; do
|
package/drift/index.ts
CHANGED
|
@@ -466,6 +466,26 @@ export function stateFilePath(projectDir: string, projectName: string, target: s
|
|
|
466
466
|
return join(resolveOutputDir(projectDir, projectName, target), STATE_FILE);
|
|
467
467
|
}
|
|
468
468
|
|
|
469
|
+
function missingSnapshotMessage(
|
|
470
|
+
cwd: string,
|
|
471
|
+
projectDir: string,
|
|
472
|
+
projectName: string,
|
|
473
|
+
target: string
|
|
474
|
+
): string {
|
|
475
|
+
const outDir = resolveOutputDir(projectDir, projectName, target);
|
|
476
|
+
if (!existsSync(outDir)) {
|
|
477
|
+
return (
|
|
478
|
+
`No snapshot found for target "${target}".\n` +
|
|
479
|
+
`Output directory not found: ${relative(cwd, outDir)}\n` +
|
|
480
|
+
`Run code generation for "${target}" first, then run: openuispec drift --snapshot --target ${target}`
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
return (
|
|
484
|
+
`No snapshot found for target "${target}".\n` +
|
|
485
|
+
`Run: openuispec drift --snapshot --target ${target}`
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
|
|
469
489
|
export function discoverTargets(projectDir: string, projectName: string): string[] {
|
|
470
490
|
const outputDirs = readOutputDirs(projectDir);
|
|
471
491
|
const targets: string[] = [];
|
|
@@ -626,10 +646,7 @@ export function loadTargetDrift(
|
|
|
626
646
|
const projectName = readProjectName(projectDir);
|
|
627
647
|
const statePath = stateFilePath(projectDir, projectName, target);
|
|
628
648
|
if (!existsSync(statePath)) {
|
|
629
|
-
console.error(
|
|
630
|
-
`No snapshot found for target "${target}".\n` +
|
|
631
|
-
`Run: openuispec drift --snapshot --target ${target}`
|
|
632
|
-
);
|
|
649
|
+
console.error(missingSnapshotMessage(cwd, projectDir, projectName, target));
|
|
633
650
|
process.exit(1);
|
|
634
651
|
}
|
|
635
652
|
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<!-- openuispec-rules-start -->
|
|
2
|
+
<!-- openuispec-rules-version: 0.1.28 -->
|
|
3
|
+
# OpenUISpec — AI Assistant Rules
|
|
4
|
+
# ================================
|
|
5
|
+
# This project uses OpenUISpec to define UI as a semantic spec.
|
|
6
|
+
# Spec files are the single source of truth for all UI across platforms.
|
|
7
|
+
# Targets: "ios", "android", "web"
|
|
8
|
+
|
|
9
|
+
## IMPORTANT — Read the specification before working with spec files
|
|
10
|
+
|
|
11
|
+
The spec format, file schemas, and generation rules are defined in the installed `openuispec` package.
|
|
12
|
+
You MUST read the reference files listed below before creating, editing, or generating from any spec file.
|
|
13
|
+
Do NOT guess the file format — skipping this step will produce invalid YAML that fails validation.
|
|
14
|
+
|
|
15
|
+
**Find the package in this order:**
|
|
16
|
+
1. `node_modules/openuispec/` (project dependency)
|
|
17
|
+
2. Run `npm root -g` → `<prefix>/openuispec/` (global install)
|
|
18
|
+
3. Online: `https://openuispec.rsteam.uz/llms-full.txt` (if not installed)
|
|
19
|
+
|
|
20
|
+
**Reference files inside the package (read in this order):**
|
|
21
|
+
1. `README.md` — schema tables, file format reference, root wrapper keys
|
|
22
|
+
2. `spec/openuispec-v0.1.md` — full specification (contracts, layout, expressions, adaptive, etc.)
|
|
23
|
+
3. `examples/taskflow/openuispec/` — complete working example with all file types
|
|
24
|
+
4. `schema/` — JSON Schemas for every file type
|
|
25
|
+
|
|
26
|
+
These files are updated with each package version. Always read from the installed package,
|
|
27
|
+
not from cached or memorized content, to ensure you use the latest spec.
|
|
28
|
+
|
|
29
|
+
## What is OpenUISpec
|
|
30
|
+
OpenUISpec is a YAML-based spec format that describes an app's UI semantically — tokens, screens, flows, and platform overrides. AI reads the spec and generates native code (SwiftUI, Compose, React). AI reads native code and updates the spec. The spec is the sync layer between platforms.
|
|
31
|
+
|
|
32
|
+
## Spec location
|
|
33
|
+
- Spec root: `openuispec/`
|
|
34
|
+
- Manifest: `openuispec/openuispec.yaml` — always read this first.
|
|
35
|
+
- Tokens: `openuispec/tokens/`
|
|
36
|
+
- Screens: `openuispec/screens/`
|
|
37
|
+
- Flows: `openuispec/flows/`
|
|
38
|
+
- Contracts: `openuispec/contracts/`
|
|
39
|
+
- Platform: `openuispec/platform/`
|
|
40
|
+
- Locales: `openuispec/locales/`
|
|
41
|
+
|
|
42
|
+
**Note:** These are the default paths. Actual paths are in `includes:` in `openuispec.yaml` and may use relative paths. Always read `openuispec.yaml` to find the real directories.
|
|
43
|
+
|
|
44
|
+
## If spec directories are empty (first-time setup)
|
|
45
|
+
This means the project has existing UI code but hasn't been specced yet. Your job:
|
|
46
|
+
|
|
47
|
+
1. **Read the spec first** — find and read `spec/openuispec-v0.1.md` from the installed package.
|
|
48
|
+
2. **Find existing screens** — scan the codebase for UI screen files.
|
|
49
|
+
3. **Create stubs** — for each screen, create `openuispec/screens/<name>.yaml` with:
|
|
50
|
+
```yaml
|
|
51
|
+
screen_name:
|
|
52
|
+
semantic: "Brief description of what this screen does"
|
|
53
|
+
status: stub
|
|
54
|
+
layout:
|
|
55
|
+
type: scroll_vertical
|
|
56
|
+
```
|
|
57
|
+
4. **Extract tokens** — scan for colors, fonts, spacing and create files in `openuispec/tokens/`.
|
|
58
|
+
5. **Update the manifest** — fill in `data_model` and `api.endpoints` in `openuispec/openuispec.yaml`.
|
|
59
|
+
|
|
60
|
+
## OpenUISpec Source Of Truth
|
|
61
|
+
|
|
62
|
+
OpenUISpec spec files are the primary source of truth for UI behavior across platforms.
|
|
63
|
+
|
|
64
|
+
### Start from spec when:
|
|
65
|
+
- the request changes screen structure
|
|
66
|
+
- the request changes navigation
|
|
67
|
+
- the request changes fields, actions, validation, or data binding
|
|
68
|
+
- the request changes tokens, variants, contracts, flows, or localization
|
|
69
|
+
- the request affects more than one platform
|
|
70
|
+
- the request is phrased in product/UI terms rather than platform-code terms
|
|
71
|
+
|
|
72
|
+
Spec-first workflow:
|
|
73
|
+
1. Read `openuispec/openuispec.yaml` and the relevant spec files first.
|
|
74
|
+
2. Update the spec first.
|
|
75
|
+
3. Update the affected generated/native UI code to match the spec.
|
|
76
|
+
4. Run `openuispec validate`.
|
|
77
|
+
5. Run `openuispec validate semantic`.
|
|
78
|
+
6. Run `openuispec drift --target <target> --explain` to inspect semantic changes since that target's baseline.
|
|
79
|
+
7. Run `openuispec prepare --target <target>` to build the AI/developer work bundle for that target.
|
|
80
|
+
8. Verify the affected UI targets build/run if possible.
|
|
81
|
+
9. Only then run `openuispec drift --snapshot --target <target>` for affected targets, after that target output directory exists.
|
|
82
|
+
10. Run `openuispec drift --target <target> --explain` again to confirm no spec changes remain for that target.
|
|
83
|
+
11. Use `openuispec status` to see which other targets are still behind the updated spec.
|
|
84
|
+
|
|
85
|
+
### Start from platform code when:
|
|
86
|
+
- the change is platform-specific polish
|
|
87
|
+
- the change is a local bug fix that does not alter shared semantic behavior
|
|
88
|
+
- the request explicitly asks for an iOS-only, Android-only, or web-only adjustment
|
|
89
|
+
|
|
90
|
+
Platform-first workflow:
|
|
91
|
+
1. Update native/platform code.
|
|
92
|
+
2. If the change affects shared semantics, sync the spec afterward.
|
|
93
|
+
3. If the change is intentionally platform-specific, document it in `platform/*.yaml` when appropriate.
|
|
94
|
+
|
|
95
|
+
### Never do this:
|
|
96
|
+
- Do not snapshot drift immediately after changing spec unless the UI code has also been updated.
|
|
97
|
+
- Do not treat `openuispec drift` as proof that generated UI matches the spec.
|
|
98
|
+
- Do not skip `--explain` / `prepare` when another platform needs to catch up with shared spec changes.
|
|
99
|
+
- Do not modify generated UI without checking whether the spec must change first.
|
|
100
|
+
|
|
101
|
+
## CLI commands
|
|
102
|
+
- `openuispec init` — scaffold a new spec project
|
|
103
|
+
- `openuispec validate [group...]` — validate spec files against schemas
|
|
104
|
+
- `openuispec validate semantic` — run semantic cross-reference linting
|
|
105
|
+
- `openuispec drift --target <t>` — check for spec drift
|
|
106
|
+
- `openuispec drift --target <t> --explain` — explain semantic spec drift since the target baseline
|
|
107
|
+
- `openuispec drift --snapshot --target <t>` — snapshot current state after the target output exists
|
|
108
|
+
- `openuispec prepare --target <t>` — build an AI-ready target update bundle
|
|
109
|
+
- `openuispec status` — show cross-target baseline/drift status
|
|
110
|
+
- `openuispec update-rules` — update AI rules to match installed package version
|
|
111
|
+
- `openuispec drift --all` — include stubs in drift check
|
|
112
|
+
<!-- openuispec-rules-end -->
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<!-- openuispec-rules-start -->
|
|
2
|
+
<!-- openuispec-rules-version: 0.1.28 -->
|
|
3
|
+
# OpenUISpec — AI Assistant Rules
|
|
4
|
+
# ================================
|
|
5
|
+
# This project uses OpenUISpec to define UI as a semantic spec.
|
|
6
|
+
# Spec files are the single source of truth for all UI across platforms.
|
|
7
|
+
# Targets: "ios", "android", "web"
|
|
8
|
+
|
|
9
|
+
## IMPORTANT — Read the specification before working with spec files
|
|
10
|
+
|
|
11
|
+
The spec format, file schemas, and generation rules are defined in the installed `openuispec` package.
|
|
12
|
+
You MUST read the reference files listed below before creating, editing, or generating from any spec file.
|
|
13
|
+
Do NOT guess the file format — skipping this step will produce invalid YAML that fails validation.
|
|
14
|
+
|
|
15
|
+
**Find the package in this order:**
|
|
16
|
+
1. `node_modules/openuispec/` (project dependency)
|
|
17
|
+
2. Run `npm root -g` → `<prefix>/openuispec/` (global install)
|
|
18
|
+
3. Online: `https://openuispec.rsteam.uz/llms-full.txt` (if not installed)
|
|
19
|
+
|
|
20
|
+
**Reference files inside the package (read in this order):**
|
|
21
|
+
1. `README.md` — schema tables, file format reference, root wrapper keys
|
|
22
|
+
2. `spec/openuispec-v0.1.md` — full specification (contracts, layout, expressions, adaptive, etc.)
|
|
23
|
+
3. `examples/taskflow/openuispec/` — complete working example with all file types
|
|
24
|
+
4. `schema/` — JSON Schemas for every file type
|
|
25
|
+
|
|
26
|
+
These files are updated with each package version. Always read from the installed package,
|
|
27
|
+
not from cached or memorized content, to ensure you use the latest spec.
|
|
28
|
+
|
|
29
|
+
## What is OpenUISpec
|
|
30
|
+
OpenUISpec is a YAML-based spec format that describes an app's UI semantically — tokens, screens, flows, and platform overrides. AI reads the spec and generates native code (SwiftUI, Compose, React). AI reads native code and updates the spec. The spec is the sync layer between platforms.
|
|
31
|
+
|
|
32
|
+
## Spec location
|
|
33
|
+
- Spec root: `openuispec/`
|
|
34
|
+
- Manifest: `openuispec/openuispec.yaml` — always read this first.
|
|
35
|
+
- Tokens: `openuispec/tokens/`
|
|
36
|
+
- Screens: `openuispec/screens/`
|
|
37
|
+
- Flows: `openuispec/flows/`
|
|
38
|
+
- Contracts: `openuispec/contracts/`
|
|
39
|
+
- Platform: `openuispec/platform/`
|
|
40
|
+
- Locales: `openuispec/locales/`
|
|
41
|
+
|
|
42
|
+
**Note:** These are the default paths. Actual paths are in `includes:` in `openuispec.yaml` and may use relative paths. Always read `openuispec.yaml` to find the real directories.
|
|
43
|
+
|
|
44
|
+
## If spec directories are empty (first-time setup)
|
|
45
|
+
This means the project has existing UI code but hasn't been specced yet. Your job:
|
|
46
|
+
|
|
47
|
+
1. **Read the spec first** — find and read `spec/openuispec-v0.1.md` from the installed package.
|
|
48
|
+
2. **Find existing screens** — scan the codebase for UI screen files.
|
|
49
|
+
3. **Create stubs** — for each screen, create `openuispec/screens/<name>.yaml` with:
|
|
50
|
+
```yaml
|
|
51
|
+
screen_name:
|
|
52
|
+
semantic: "Brief description of what this screen does"
|
|
53
|
+
status: stub
|
|
54
|
+
layout:
|
|
55
|
+
type: scroll_vertical
|
|
56
|
+
```
|
|
57
|
+
4. **Extract tokens** — scan for colors, fonts, spacing and create files in `openuispec/tokens/`.
|
|
58
|
+
5. **Update the manifest** — fill in `data_model` and `api.endpoints` in `openuispec/openuispec.yaml`.
|
|
59
|
+
|
|
60
|
+
## OpenUISpec Source Of Truth
|
|
61
|
+
|
|
62
|
+
OpenUISpec spec files are the primary source of truth for UI behavior across platforms.
|
|
63
|
+
|
|
64
|
+
### Start from spec when:
|
|
65
|
+
- the request changes screen structure
|
|
66
|
+
- the request changes navigation
|
|
67
|
+
- the request changes fields, actions, validation, or data binding
|
|
68
|
+
- the request changes tokens, variants, contracts, flows, or localization
|
|
69
|
+
- the request affects more than one platform
|
|
70
|
+
- the request is phrased in product/UI terms rather than platform-code terms
|
|
71
|
+
|
|
72
|
+
Spec-first workflow:
|
|
73
|
+
1. Read `openuispec/openuispec.yaml` and the relevant spec files first.
|
|
74
|
+
2. Update the spec first.
|
|
75
|
+
3. Update the affected generated/native UI code to match the spec.
|
|
76
|
+
4. Run `openuispec validate`.
|
|
77
|
+
5. Run `openuispec validate semantic`.
|
|
78
|
+
6. Run `openuispec drift --target <target> --explain` to inspect semantic changes since that target's baseline.
|
|
79
|
+
7. Run `openuispec prepare --target <target>` to build the AI/developer work bundle for that target.
|
|
80
|
+
8. Verify the affected UI targets build/run if possible.
|
|
81
|
+
9. Only then run `openuispec drift --snapshot --target <target>` for affected targets, after that target output directory exists.
|
|
82
|
+
10. Run `openuispec drift --target <target> --explain` again to confirm no spec changes remain for that target.
|
|
83
|
+
11. Use `openuispec status` to see which other targets are still behind the updated spec.
|
|
84
|
+
|
|
85
|
+
### Start from platform code when:
|
|
86
|
+
- the change is platform-specific polish
|
|
87
|
+
- the change is a local bug fix that does not alter shared semantic behavior
|
|
88
|
+
- the request explicitly asks for an iOS-only, Android-only, or web-only adjustment
|
|
89
|
+
|
|
90
|
+
Platform-first workflow:
|
|
91
|
+
1. Update native/platform code.
|
|
92
|
+
2. If the change affects shared semantics, sync the spec afterward.
|
|
93
|
+
3. If the change is intentionally platform-specific, document it in `platform/*.yaml` when appropriate.
|
|
94
|
+
|
|
95
|
+
### Never do this:
|
|
96
|
+
- Do not snapshot drift immediately after changing spec unless the UI code has also been updated.
|
|
97
|
+
- Do not treat `openuispec drift` as proof that generated UI matches the spec.
|
|
98
|
+
- Do not skip `--explain` / `prepare` when another platform needs to catch up with shared spec changes.
|
|
99
|
+
- Do not modify generated UI without checking whether the spec must change first.
|
|
100
|
+
|
|
101
|
+
## CLI commands
|
|
102
|
+
- `openuispec init` — scaffold a new spec project
|
|
103
|
+
- `openuispec validate [group...]` — validate spec files against schemas
|
|
104
|
+
- `openuispec validate semantic` — run semantic cross-reference linting
|
|
105
|
+
- `openuispec drift --target <t>` — check for spec drift
|
|
106
|
+
- `openuispec drift --target <t> --explain` — explain semantic spec drift since the target baseline
|
|
107
|
+
- `openuispec drift --snapshot --target <t>` — snapshot current state after the target output exists
|
|
108
|
+
- `openuispec prepare --target <t>` — build an AI-ready target update bundle
|
|
109
|
+
- `openuispec status` — show cross-target baseline/drift status
|
|
110
|
+
- `openuispec update-rules` — update AI rules to match installed package version
|
|
111
|
+
- `openuispec drift --all` — include stubs in drift check
|
|
112
|
+
<!-- openuispec-rules-end -->
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# TaskFlow Android Target
|
|
2
|
+
|
|
3
|
+
This Android target was generated directly from the local `openuispec/` TaskFlow specification, without copying another sample project's output.
|
|
4
|
+
|
|
5
|
+
## What is included
|
|
6
|
+
|
|
7
|
+
- A lean Jetpack Compose app scaffold under `app/`
|
|
8
|
+
- Adaptive navigation using spec breakpoints:
|
|
9
|
+
- `compact`: bottom navigation
|
|
10
|
+
- `regular` and `expanded`: navigation rail
|
|
11
|
+
- Spec-derived screens:
|
|
12
|
+
- Home
|
|
13
|
+
- Task detail
|
|
14
|
+
- Projects
|
|
15
|
+
- Project detail
|
|
16
|
+
- Calendar stub
|
|
17
|
+
- Settings
|
|
18
|
+
- Profile edit
|
|
19
|
+
- Spec-derived flows:
|
|
20
|
+
- Create task
|
|
21
|
+
- Edit task
|
|
22
|
+
- Assign task
|
|
23
|
+
- New project
|
|
24
|
+
- Local sample data matching the spec's data model
|
|
25
|
+
- English string resources derived from `openuispec/locales/en.json`
|
|
26
|
+
- Theme colors based on `openuispec/tokens/color.yaml` and `themes.yaml`
|
|
27
|
+
|
|
28
|
+
## Project notes
|
|
29
|
+
|
|
30
|
+
- This is intentionally lean. It favors clear generated structure over a fully productionized architecture.
|
|
31
|
+
- The app uses local Compose state instead of wiring real API clients.
|
|
32
|
+
- The media-player custom contract is acknowledged in the spec but not implemented here because no screen in this minimal target renders a concrete media attachment asset.
|
|
33
|
+
- No Gradle wrapper is checked in. Use a local Gradle installation or import the project into Android Studio and let it create the wrapper if needed.
|
|
34
|
+
|
|
35
|
+
## Suggested verification
|
|
36
|
+
|
|
37
|
+
From this directory:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
gradle :app:assembleDebug
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or open `generated/android/TaskFlow` in Android Studio and run the app on an emulator.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
plugins {
|
|
2
|
+
id("com.android.application")
|
|
3
|
+
id("org.jetbrains.kotlin.android")
|
|
4
|
+
id("org.jetbrains.kotlin.plugin.compose")
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|
8
|
+
|
|
9
|
+
android {
|
|
10
|
+
namespace = "uz.rsteam.taskflow"
|
|
11
|
+
compileSdk = 35
|
|
12
|
+
|
|
13
|
+
defaultConfig {
|
|
14
|
+
applicationId = "uz.rsteam.taskflow"
|
|
15
|
+
minSdk = 26
|
|
16
|
+
targetSdk = 35
|
|
17
|
+
versionCode = 1
|
|
18
|
+
versionName = "1.0.0"
|
|
19
|
+
|
|
20
|
+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
|
21
|
+
vectorDrawables {
|
|
22
|
+
useSupportLibrary = true
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
buildTypes {
|
|
27
|
+
release {
|
|
28
|
+
isMinifyEnabled = false
|
|
29
|
+
proguardFiles(
|
|
30
|
+
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
31
|
+
"proguard-rules.pro"
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
compileOptions {
|
|
37
|
+
sourceCompatibility = JavaVersion.VERSION_17
|
|
38
|
+
targetCompatibility = JavaVersion.VERSION_17
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
buildFeatures {
|
|
42
|
+
compose = true
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
packaging {
|
|
46
|
+
resources {
|
|
47
|
+
excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
kotlin {
|
|
53
|
+
compilerOptions {
|
|
54
|
+
jvmTarget.set(JvmTarget.JVM_17)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
dependencies {
|
|
59
|
+
val composeBom = platform("androidx.compose:compose-bom:2024.10.01")
|
|
60
|
+
|
|
61
|
+
implementation(composeBom)
|
|
62
|
+
androidTestImplementation(composeBom)
|
|
63
|
+
|
|
64
|
+
implementation("androidx.core:core-ktx:1.15.0")
|
|
65
|
+
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7")
|
|
66
|
+
implementation("androidx.activity:activity-compose:1.9.3")
|
|
67
|
+
implementation("androidx.compose.ui:ui")
|
|
68
|
+
implementation("androidx.compose.ui:ui-graphics")
|
|
69
|
+
implementation("androidx.compose.ui:ui-tooling-preview")
|
|
70
|
+
implementation("androidx.compose.material3:material3")
|
|
71
|
+
implementation("androidx.compose.material:material-icons-extended")
|
|
72
|
+
implementation("androidx.compose.foundation:foundation")
|
|
73
|
+
|
|
74
|
+
debugImplementation("androidx.compose.ui:ui-tooling")
|
|
75
|
+
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
|
76
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Generated sample app. No custom ProGuard rules required.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
3
|
+
|
|
4
|
+
<application
|
|
5
|
+
android:allowBackup="true"
|
|
6
|
+
android:label="@string/app_name"
|
|
7
|
+
android:supportsRtl="true"
|
|
8
|
+
android:theme="@style/Theme.TaskFlow">
|
|
9
|
+
<activity
|
|
10
|
+
android:name=".MainActivity"
|
|
11
|
+
android:exported="true"
|
|
12
|
+
android:theme="@style/Theme.TaskFlow">
|
|
13
|
+
<intent-filter>
|
|
14
|
+
<action android:name="android.intent.action.MAIN" />
|
|
15
|
+
|
|
16
|
+
<category android:name="android.intent.category.LAUNCHER" />
|
|
17
|
+
</intent-filter>
|
|
18
|
+
</activity>
|
|
19
|
+
</application>
|
|
20
|
+
|
|
21
|
+
</manifest>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package uz.rsteam.taskflow
|
|
2
|
+
|
|
3
|
+
import android.os.Bundle
|
|
4
|
+
import androidx.activity.ComponentActivity
|
|
5
|
+
import androidx.activity.compose.setContent
|
|
6
|
+
import androidx.activity.enableEdgeToEdge
|
|
7
|
+
import uz.rsteam.taskflow.ui.theme.TaskFlowTheme
|
|
8
|
+
|
|
9
|
+
class MainActivity : ComponentActivity() {
|
|
10
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
11
|
+
super.onCreate(savedInstanceState)
|
|
12
|
+
enableEdgeToEdge()
|
|
13
|
+
setContent {
|
|
14
|
+
TaskFlowTheme {
|
|
15
|
+
TaskFlowApp()
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|