openuispec 0.2.8 → 0.2.9

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 CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  > A single source of truth design language for AI-native, platform-native app development.
4
4
 
5
- OpenUISpec is a **semantic UI specification format** that replaces cross-platform frameworks with a declarative design language. Instead of sharing runtime code across platforms, you share the *spec* — and AI generates native SwiftUI, Jetpack Compose, and React code from it.
6
-
7
- OpenUISpec is a shared UI sync language for native products, optimized for solo developers but equally usable by teams. It is not a pixel-perfect design format like Figma and it is not a shared runtime like Flutter or React Native. Its job is to keep product intent, interaction contracts, flows, tokens, and platform outputs aligned while still allowing bounded native variation on iOS, Android, and web.
5
+ OpenUISpec is a **semantic UI specification format** that replaces cross-platform frameworks with a declarative design language.
6
+ Instead of sharing runtime code across platforms, you share the *spec* — and AI generates native SwiftUI, Jetpack Compose, and React code from it.
8
7
 
9
8
  ## Why
10
9
 
11
- Cross-platform frameworks (Flutter, React Native, KMP/CMP) solve code duplication by sharing a runtime. OpenUISpec solves it by sharing **intent**:
10
+ Cross-platform frameworks (Flutter, React Native, KMP/CMP) solve code duplication by sharing a runtime.
11
+ OpenUISpec solves it by sharing **intent**:
12
12
 
13
13
  | Approach | Shares | Runs |
14
14
  |----------|--------|------|
@@ -33,17 +33,6 @@ The result: each platform feels native, but every app stays semantically consist
33
33
  <img alt="OpenUISpec workflows" src="https://raw.githubusercontent.com/rsktash/openuispec/main/docs/images/workflows-light.png">
34
34
  </picture>
35
35
 
36
- ## Key concepts
37
-
38
- - **Tokens**: Design values (color, typography, spacing, elevation, motion) with semantic names and constrained ranges
39
- - **Contracts**: 7 behavioral component families defined by role, props, state machines, and accessibility
40
- - **Screens**: Compositions of contracts with data bindings, adaptive layout, and conditional rendering
41
- - **Flows**: Multi-screen navigation journeys, intent-based and platform-agnostic
42
- - **Actions**: 13 typed action types with composition, error handling, and optimistic updates
43
- - **Data binding**: Reactive state, format expressions, caching, and loading/error/empty states
44
- - **Adaptive layout**: Size classes (compact/regular/expanded) with per-section overrides
45
- - **Platform adaptation**: Per-target overrides for iOS, Android, and Web behaviors
46
-
47
36
  ## Quick start
48
37
 
49
38
  ```bash
@@ -52,399 +41,75 @@ cd your-project
52
41
  openuispec init
53
42
  ```
54
43
 
55
- This scaffolds a spec directory, starter tokens, and **configures the MCP server** for your AI coding agent (Claude Code, VS Code/Copilot, Codex). Use `openuispec init --no-configure-targets` to scaffold first and choose target stacks later.
56
-
57
- ## AI integration (MCP)
58
-
59
- OpenUISpec is designed to be used by AI coding agents. The package includes an **MCP server** that exposes tools AI assistants call automatically during UI work — no manual prompting needed.
60
-
61
- ### How it works
62
-
63
- ```
64
- openuispec init → configures MCP for your agent → AI calls tools automatically
65
- ```
66
-
67
- When you ask your AI to "add a settings page" or "update the home feed," the MCP server:
68
-
69
- 1. **Schema reference** — `openuispec_spec_types` and `openuispec_spec_schema` give the AI the exact format for any spec file it needs to create or edit
70
- 2. **Before generation** — `openuispec_prepare` gives the AI your spec context, platform config, and constraints
71
- 3. **During generation** — `openuispec_read_specs` feeds the AI the actual spec file contents as the authoritative source
72
- 4. **After generation** — `openuispec_check` returns a concrete audit checklist derived from your spec (every contract `must_handle` item, every screen section, every locale key) and the AI verifies its code matches
73
-
74
- This replaces the old approach of writing instructions in CLAUDE.md and hoping the AI follows them. MCP tools are called reliably because they're part of the AI's tool-calling loop, not a text instruction it can skip.
75
-
76
- ### Setup
77
-
78
- `openuispec init` and `openuispec update-rules` automatically configure MCP for all supported agents:
79
-
80
- | Agent | Config file | Created automatically |
81
- |-------|------------|----------------------|
82
- | **Claude Code** | `.mcp.json` | Always |
83
- | **Codex** | `.codex/config.toml` | Always |
84
- | **VS Code / Copilot** | `.vscode/mcp.json` | If `.vscode/` exists |
85
- | **Gemini CLI** | `.gemini/settings.json` | If `.gemini/` exists |
86
-
87
- Manual setup (if needed):
88
-
89
- **Claude Code** (`.mcp.json`), **VS Code / Copilot** (`.vscode/mcp.json`), **Gemini CLI** (`.gemini/settings.json`):
90
- ```json
91
- {
92
- "mcpServers": {
93
- "openuispec": {
94
- "command": "openuispec",
95
- "args": ["mcp"]
96
- }
97
- }
98
- }
99
- ```
100
-
101
- **Codex** (`.codex/config.toml`):
102
- ```toml
103
- [mcp_servers.openuispec]
104
- command = "openuispec"
105
- args = ["mcp"]
106
- ```
107
-
108
- Or run directly: `openuispec mcp`
109
-
110
- ### Tools
111
-
112
- | Tool | When | What it does |
113
- |------|------|-------------|
114
- | `openuispec_spec_types` | Before creating spec files | Lists all available spec types with descriptions — discover what kinds of spec files exist |
115
- | `openuispec_spec_schema` | Before creating/editing spec files | Returns the full JSON schema for a specific spec type — exact structure, required fields, allowed values |
116
- | `openuispec_prepare` | Before UI code generation | Returns spec context, platform config, generation constraints |
117
- | `openuispec_read_specs` | Before and after generation | Loads spec file contents — the authoritative source for tokens, screens, contracts |
118
- | `openuispec_check` | After generation | Schema validation + concrete audit checklist from your spec. Optional `screens`/`contracts` params scope the audit |
119
- | `openuispec_validate` | After spec edits | Schema-only validation, optionally filtered by group |
120
- | `openuispec_drift` | Before updates | Detect spec drift since last snapshot, with semantic explanation |
121
- | `openuispec_status` | Anytime | Cross-target summary: baselines, drift, next steps |
122
- | `openuispec_get_screen` | Incremental edits | Get a single screen spec by name — faster than `read_specs` for targeted work |
123
- | `openuispec_get_contract` | Incremental edits | Get a single contract spec, optionally filtered to one variant |
124
- | `openuispec_get_tokens` | Incremental edits | Get tokens for a specific category (color, typography, spacing, etc.) |
125
- | `openuispec_get_locale` | Incremental edits | Get a single locale file, optionally filtered to specific keys |
126
- | `openuispec_screenshot` | Visual verification | Screenshot the web app at a route via headless browser (requires `puppeteer`) |
127
- | `openuispec_screenshot_android` | Visual verification | Screenshot Android app on emulator — builds APK, installs, captures via adb. Works with any Android project via `project_dir` param |
128
- | `openuispec_screenshot_ios` | Visual verification | Screenshot iOS app on Simulator — builds with xcodebuild, captures via XCUITest. Works with any iOS project via `project_dir` param |
129
-
130
- The server includes **protocol-level instructions** that trigger on UI-related requests independently of CLAUDE.md rules — so even if CLAUDE.md is buried under other project rules, the MCP enforcement still works.
131
-
132
- ### Visual verification
133
-
134
- The screenshot tools work with **any** Android/iOS/web project — they don't require an OpenUISpec manifest. Use `project_dir` to point directly at a project root:
135
-
136
- ```
137
- # With OpenUISpec manifest (auto-discovers generated app)
138
- openuispec_screenshot_android(screen: "home")
139
-
140
- # Standalone — any Android project
141
- openuispec_screenshot_android(project_dir: "/path/to/android/project", screen: "home")
142
-
143
- # Standalone — any iOS project
144
- openuispec_screenshot_ios(project_dir: "/path/to/ios/project", scheme: "MyApp")
145
- ```
146
-
147
- Additional override params:
44
+ This scaffolds a spec directory, starter tokens, and **configures the MCP server** for your AI coding agent (Claude Code, VS Code/Copilot, Codex, Gemini CLI).
148
45
 
149
- | Param | Android | iOS | Purpose |
150
- |-------|---------|-----|---------|
151
- | `project_dir` | yes | yes | Skip manifest, point directly at project root |
152
- | `module` | yes | — | Override app module name (default: auto-detect from `settings.gradle`) |
153
- | `scheme` | — | yes | Override Xcode scheme (default: auto-detect) |
154
- | `bundle_id` | — | yes | Override bundle ID (default: auto-detect from `project.pbxproj`) |
155
-
156
- Auto-detection features:
157
- - **Android**: Scans `settings.gradle.kts`/`.gradle` to find the module with `com.android.application` plugin. Supports both Kotlin DSL and Groovy DSL.
158
- - **iOS**: Reads deployment target from `project.pbxproj`. For navigation screenshots, generates an XCUITest project via xcodegen — works with both xcodegen-managed and standalone Xcode projects.
159
-
160
- ## Using without MCP
161
-
162
- You can also use OpenUISpec with any AI by providing context manually:
163
-
164
- > Generate a native iOS app from this OpenUISpec. Follow all contract state machines, apply token ranges for iOS, and implement navigation flows as defined. Use `platform/ios.yaml` for SwiftUI-specific overrides.
165
-
166
- For platform generation, treat these as hard output constraints:
46
+ ## Key concepts
167
47
 
168
- - Generate a valid native project that bundles every required runtime resource
169
- - Do not ship unresolved resource identifiers (raw locale keys, token refs, placeholder paths)
170
- - Define behavior for every supported size class and form factor
48
+ - **Tokens** design values (color, typography, spacing, elevation, motion) with semantic names and constrained ranges
49
+ - **Contracts** 7 behavioral component families defined by role, props, state machines, and accessibility
50
+ - **Screens** compositions of contracts with data bindings, adaptive layout, and conditional rendering
51
+ - **Flows** — multi-screen navigation journeys, intent-based and platform-agnostic
52
+ - **Actions** — 13 typed action types with composition, error handling, and optimistic updates
53
+ - **Data binding** — reactive state, format expressions, caching, and loading/error/empty states
54
+ - **Adaptive layout** — size classes (compact/regular/expanded) with per-section overrides
55
+ - **Platform adaptation** — per-target overrides for iOS, Android, and Web behaviors
171
56
 
172
- See the examples for reference:
57
+ ## The 7 contract families
173
58
 
174
- - [TaskFlow](./examples/taskflow/openuispec/) compact reference spec covering all 7 contract families
175
- - [Todo Orbit](./examples/todo-orbit/openuispec/) — bilingual task app with localization, custom contracts, and generated native/web targets
176
- - [Social App](./examples/social-app/openuispec/) trilingual social app with feeds, messaging, profiles, and generated Android/web targets
59
+ | Contract | Role | Maps to |
60
+ |----------|------|---------|
61
+ | `action_trigger` | Initiates actions | Button, FAB, link |
62
+ | `data_display` | Shows read-only info | Card, list item, stat |
63
+ | `input_field` | Captures user input | TextField, toggle, picker |
64
+ | `nav_container` | Persistent navigation | Tab bar, sidebar, drawer |
65
+ | `feedback` | System status messages | Toast, dialog, banner |
66
+ | `surface` | Contains other components | Sheet, modal, popover |
67
+ | `collection` | Repeating data sets | List, grid, table |
177
68
 
178
- ## Repository structure
69
+ ## AI integration (MCP)
179
70
 
180
- ```
181
- openuispec/
182
- ├── spec/
183
- │ └── openuispec-v0.1.md # Full specification (14 sections)
184
- ├── schema/ # JSON Schema for validation (draft 2020-12)
185
- │ ├── openuispec.schema.json # Root manifest schema
186
- │ ├── screen.schema.json # Screen composition schema
187
- │ ├── flow.schema.json # Navigation flow schema
188
- │ ├── platform.schema.json # Platform adaptation schema
189
- │ ├── locale.schema.json # Locale file schema
190
- │ ├── contract.schema.json # Standard contract extension schema
191
- │ ├── custom-contract.schema.json # Custom contract extension schema (x_ prefixed)
192
- │ ├── tokens/
193
- │ │ ├── color.schema.json # Color token schema
194
- │ │ ├── typography.schema.json # Typography token schema
195
- │ │ ├── spacing.schema.json # Spacing token schema
196
- │ │ ├── elevation.schema.json # Elevation token schema
197
- │ │ ├── motion.schema.json # Motion token schema
198
- │ │ ├── layout.schema.json # Layout token schema
199
- │ │ ├── themes.schema.json # Theme token schema
200
- │ │ └── icons.schema.json # Icon token schema
201
- │ ├── defs/
202
- │ │ ├── common.schema.json # Shared types (icons, badges, etc.)
203
- │ │ ├── action.schema.json # 14 action types (discriminated union)
204
- │ │ ├── data-binding.schema.json # Data sources, state, params
205
- │ │ ├── adaptive.schema.json # Adaptive override pattern
206
- │ │ └── validation.schema.json # Validation rule definitions
207
- │ └── validate.ts # Validation script (npm run validate)
208
- ├── examples/
209
- │ ├── taskflow/ # Compact reference sample
210
- │ │ ├── openuispec/ # Source OpenUISpec project
211
- │ │ ├── generated/ # Generated iOS, Android, and web apps
212
- │ │ ├── README.md # Sample overview and structure
213
- │ │ └── AGENTS.md / CLAUDE.md # AI rules generated from the package
214
- │ ├── social-app/ # Social app sample (trilingual, Android + Web)
215
- │ └── todo-orbit/ # Full showcase sample
216
- │ ├── openuispec/ # Source OpenUISpec project
217
- │ ├── generated/ # Generated iOS, Android, and web apps
218
- │ ├── README.md # Sample overview and structure
219
- │ └── AGENTS.md / CLAUDE.md # AI rules generated from the package
220
- ├── cli/ # CLI tool (openuispec init, drift, prepare, validate)
221
- │ ├── index.ts # Entry point
222
- │ └── init.ts # Project scaffolding + AI rules
223
- ├── mcp-server/ # MCP server (openuispec-mcp)
224
- │ ├── index.ts # Stdio transport, 15 tools
225
- │ ├── screenshot.ts # Dev server + headless browser screenshot (web)
226
- │ ├── screenshot-shared.ts # Shared utilities for platform screenshot tools
227
- │ ├── screenshot-android.ts # Android screenshot via emulator (adb screencap)
228
- │ └── screenshot-ios.ts # iOS screenshot via Simulator (xcodebuild + XCUITest)
229
- ├── scripts/
230
- │ └── take-all-screenshots.ts # Batch screenshot capture for all example projects
231
- ├── artifacts/ # Screenshot artifacts from generated apps
232
- │ ├── social-app/screenshots/ # Web + Android screenshots
233
- │ ├── todo-orbit/screenshots/ # Web + Android + iOS screenshots
234
- │ └── taskflow/screenshots/ # Web + Android + iOS screenshots
235
- ├── check/ # Composite validation command
236
- │ └── index.ts # Schema + semantic + readiness
237
- ├── drift/ # Drift detection (spec change tracking)
238
- │ └── index.ts # Hash-based drift checker
239
- ├── prepare/ # Target work bundle generation
240
- │ └── index.ts # Baseline-aware target preparation
241
- ├── status/ # Cross-target status summary
242
- │ └── index.ts # Baseline/drift overview
243
- ├── LICENSE
244
- └── README.md
245
- ```
71
+ OpenUISpec includes an **MCP server** that AI assistants call automatically during UI work — no manual prompting needed.
246
72
 
247
- ## File formats and schemas
248
-
249
- Every file type has a corresponding JSON Schema in `schema/`. **Read the schema before creating or editing a file** — do not guess the structure.
250
-
251
- | File | Schema | Root key | Example |
252
- |------|--------|----------|---------|
253
- | `openuispec.yaml` | `openuispec.schema.json` | `spec_version` | [openuispec.yaml](./examples/taskflow/openuispec/openuispec.yaml) |
254
- | `screens/*.yaml` | `screen.schema.json` | `<screen_id>` | [home.yaml](./examples/taskflow/openuispec/screens/home.yaml) |
255
- | `flows/*.yaml` | `flow.schema.json` | `<flow_id>` | [create_task.yaml](./examples/taskflow/openuispec/flows/create_task.yaml) |
256
- | `platform/*.yaml` | `platform.schema.json` | `platform` | [ios.yaml](./examples/taskflow/openuispec/platform/ios.yaml) |
257
- | `locales/*.json` | `locale.schema.json` | (object) | [en.json](./examples/taskflow/openuispec/locales/en.json) |
258
- | `contracts/<name>.yaml` | `contract.schema.json` | `<contract_name>` | [input_field.yaml](./examples/taskflow/openuispec/contracts/input_field.yaml) |
259
- | `contracts/x_*.yaml` | `custom-contract.schema.json` | `<x_name>` | [x_media_player.yaml](./examples/taskflow/openuispec/contracts/x_media_player.yaml) |
260
- | `tokens/color.yaml` | `tokens/color.schema.json` | `color` | [color.yaml](./examples/taskflow/openuispec/tokens/color.yaml) |
261
- | `tokens/typography.yaml` | `tokens/typography.schema.json` | `typography` | [typography.yaml](./examples/taskflow/openuispec/tokens/typography.yaml) |
262
- | `tokens/spacing.yaml` | `tokens/spacing.schema.json` | `spacing` | [spacing.yaml](./examples/taskflow/openuispec/tokens/spacing.yaml) |
263
- | `tokens/elevation.yaml` | `tokens/elevation.schema.json` | `elevation` | [elevation.yaml](./examples/taskflow/openuispec/tokens/elevation.yaml) |
264
- | `tokens/motion.yaml` | `tokens/motion.schema.json` | `motion` | [motion.yaml](./examples/taskflow/openuispec/tokens/motion.yaml) |
265
- | `tokens/layout.yaml` | `tokens/layout.schema.json` | `layout` | [layout.yaml](./examples/taskflow/openuispec/tokens/layout.yaml) |
266
- | `tokens/themes.yaml` | `tokens/themes.schema.json` | `themes` | [themes.yaml](./examples/taskflow/openuispec/tokens/themes.yaml) |
267
- | `tokens/icons.yaml` | `tokens/icons.schema.json` | `icons` | [icons.yaml](./examples/taskflow/openuispec/tokens/icons.yaml) |
268
-
269
- Every token file **must** have a single root wrapper key matching its type:
270
-
271
- ```yaml
272
- # Correct — tokens/color.yaml
273
- color:
274
- brand:
275
- primary: ...
276
-
277
- # Wrong — missing root key
278
- brand:
279
- primary: ...
280
73
  ```
281
-
282
- Validate with: `openuispec validate`
283
-
284
- Use `openuispec validate semantic` to run cross-reference linting for locale keys, formatter refs, mapper refs, contracts, icons, navigation targets, and API endpoint references.
285
-
286
- ### Shared interactive state roles
287
-
288
- Interactive contracts may optionally express state-specific visual roles inside their token maps with a nested `states:` object. This lets generators use explicit foreground/background/icon/border roles for `default`, `active`, `selected`, `pressed`, `focused`, `disabled`, `loading`, and `error` states instead of inferring them from container colors or platform defaults.
289
-
290
- Allowed visual role keys (no others are permitted):
291
-
292
- - `background`
293
- - `text`
294
- - `icon`
295
- - `border`
296
- - `badge_background`
297
- - `badge_text`
298
-
299
- When `states:` is omitted, generators fall back to the token values defined at that level plus the base contract semantics.
300
-
301
- ## Output directories
302
-
303
- By default, drift stores state in `generated/<target>/<project>/`. To point targets to your actual code directories, add `output_dir` to `openuispec.yaml`:
304
-
305
- ```yaml
306
- generation:
307
- targets: [ios, android, web]
308
- extra_rules:
309
- - "Generation hint strings may start with [common], [ios], [android], or [web] to indicate scope."
310
- output_dir:
311
- web: "../web-ui/"
312
- android: "../kmp-ui/"
313
- ios: "../kmp-ui/iosApp/"
314
- code_roots:
315
- backend: "../api/"
74
+ openuispec init → configures MCP for your agent → AI calls tools automatically
316
75
  ```
317
76
 
318
- 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.
319
-
320
- If `api.endpoints` are declared, `generation.code_roots.backend` is required. It should point at the backend folder the AI must inspect when generating API clients or wiring request/response behavior.
321
-
322
- `generation.extra_rules` can hold project-wide generation conventions for AI and humans. For example, projects may declare that generation hint strings use prefixes such as `[common]`, `[ios]`, `[android]`, and `[web]` to indicate scope.
323
-
324
- `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.
325
-
326
- Use the commands like this:
327
- - `openuispec validate` checks schema correctness
328
- - `openuispec validate semantic` checks cross-references such as locale keys, formatters, mappers, contracts, icons, navigation targets, and API endpoints
329
- - `openuispec init --no-configure-targets` scaffolds the spec project without running the target-stack wizard
330
- - `openuispec configure-target <t>` records and confirms target stack choices in `platform/<target>.yaml`, while still allowing custom framework/library values when the project uses something outside the catalog
331
- - `openuispec drift --target <t> --explain` explains semantic spec changes since that target's accepted baseline
332
- - `openuispec prepare --target <t>` builds the target work bundle for either first-time generation or drift-based updates
333
- - `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
77
+ When you ask your AI to "add a settings page" or "update the home feed," the MCP server provides spec context before generation, feeds authoritative spec contents during generation, and returns a concrete audit checklist after generation.
334
78
 
335
- Spec access commands (also available as MCP tools):
336
- - `openuispec read-specs [paths...]` reads spec file contents as JSON
337
- - `openuispec get-screen <name>` gets a single screen spec
338
- - `openuispec get-contract <name> [--variant v]` gets a contract spec, optionally one variant
339
- - `openuispec get-tokens <category>` gets tokens for a category (color, typography, spacing, etc.)
340
- - `openuispec get-locale <locale> [--keys k1,k2]` gets a locale file, optionally filtered keys
341
- - `openuispec spec-types` lists all available spec types with descriptions
342
- - `openuispec spec-schema <type>` gets the full JSON schema for a spec type
79
+ 15 tools are available as both MCP tools and CLI commands — see the [full reference](./docs/cli.md).
343
80
 
344
- Screenshot commands (also available as MCP tools):
345
- - `openuispec screenshot --route /path [--theme dark] [--output-dir dir]` screenshots the web app
346
- - `openuispec screenshot-android [--project-dir path] [--screen name] [--module name]` screenshots the Android app on an emulator
347
- - `openuispec screenshot-ios [--project-dir path] [--screen name] [--scheme name]` screenshots the iOS app on a Simulator
81
+ **Using without MCP?** You can provide spec context to any AI manually:
348
82
 
349
- In first-time generation mode, `prepare` also carries target-specific generation constraints such as native localization requirements, multi-file output rules, target folder layout expectations, and a requirement to refresh current platform/framework setup knowledge before code generation.
83
+ > Generate a native iOS app from this OpenUISpec. Follow all contract state machines, apply token ranges for iOS, and implement navigation flows as defined.
350
84
 
351
- If stack choices were auto-applied via `configure-target --defaults` or `init --defaults`, they remain unconfirmed. `prepare` will block implementation readiness until the user explicitly confirms the target stack, and AI agents should ask the user to confirm or change those choices instead of silently proceeding to code generation.
85
+ ## Examples
352
86
 
353
- When target stack choices come from the preset catalog, `prepare --json` also exposes install-oriented refs for the selected options:
354
- - Android: Gradle plugin ids and library coordinates
355
- - Web: npm package specs
356
- - iOS: package identifiers plus docs links
87
+ | Example | Targets | What it demonstrates |
88
+ |---------|---------|---------------------|
89
+ | [TaskFlow](./examples/taskflow/openuispec/) | iOS, Android, Web | Compact reference covering all 7 contract families |
90
+ | [Todo Orbit](./examples/todo-orbit/openuispec/) | iOS, Android, Web | Bilingual task app with localization, custom contracts |
91
+ | [Social App](./examples/social-app/openuispec/) | Android, Web | Trilingual social app with feeds, messaging, profiles |
357
92
 
358
- Those refs are anchors, not a full dependency manifest. The AI is expected to add any supporting build, plugin, repository, annotation-processing, runtime, dev, and test dependencies required by the current platform setup.
93
+ ## Documentation
359
94
 
360
- 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.
361
-
362
- ## Target update workflow
363
-
364
- When a shared spec change needs to be applied to a target:
365
-
366
- ```bash
367
- openuispec validate
368
- openuispec validate semantic
369
- openuispec status
370
- openuispec drift --target ios --explain
371
- openuispec prepare --target ios
372
- # update the ios implementation
373
- # ensure the ios output directory already exists
374
- openuispec drift --snapshot --target ios
375
- ```
376
-
377
- Meaning:
378
- - `validate` checks schema correctness
379
- - `validate semantic` checks cross-reference integrity
380
- - `status` shows which targets are up to date, need a baseline, or still need generation
381
- - `drift --explain` shows semantic spec changes since that target's accepted baseline
382
- - `prepare` packages the target work bundle for AI/developers. It runs in `bootstrap` mode for first-time generation and `update` mode after a target snapshot exists.
383
- - `drift --snapshot` accepts the updated state after the target UI has been updated and the target output directory exists
384
-
385
- Before picking the next platform to update, run:
386
-
387
- ```bash
388
- openuispec status
389
- ```
390
-
391
- to see which targets are already up to date and which ones still need to catch up with shared spec changes.
392
-
393
- `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.
394
-
395
- ## Spec at a glance
396
-
397
- | Section | What it defines |
398
- |---------|----------------|
399
- | 1. Philosophy | Core principles: semantic, constrained, contract-driven, AI-first |
400
- | 2. Document structure | Project layout and root manifest |
401
- | 3. Token layer | Color, typography, spacing, elevation, motion, layout, themes, icons |
402
- | 4. Component contracts | 7 behavioral families (action_trigger, data_display, input_field, nav_container, feedback, surface, collection) |
403
- | 5. Screen composition | Contract-based layouts, screen-level keys, adaptive layout system |
404
- | 6. Navigation flows | Multi-screen journeys with transitions and progress |
405
- | 7. Platform adaptation | Per-target overrides for iOS, Android, Web |
406
- | 8. AI generation contract | Compliance levels (MUST/SHOULD/MAY), validation, drift detection |
407
- | 9. Action system | 14 action types, composition, optimistic updates |
408
- | 10. Data binding & state | Sources, paths, format expressions, reactivity, caching |
409
- | 11. Internationalization | Locale files, `$t:` references, ICU MessageFormat, RTL, platform mapping |
410
- | 12. Custom contract extensions | `x_` prefixed domain-specific contracts, registration, dependencies |
411
- | 13. Form validation & field dependencies | Validation rules, field dependencies, cross-field checks, async validation |
412
- | 14. Development workflow | Dual-workflow model, drift detection, spec as sync layer |
413
-
414
- ## The 7 contract families
415
-
416
- | Contract | Role | Maps to |
417
- |----------|------|---------|
418
- | `action_trigger` | Initiates actions | Button, FAB, link |
419
- | `data_display` | Shows read-only info | Card, list item, stat |
420
- | `input_field` | Captures user input | TextField, toggle, picker |
421
- | `nav_container` | Persistent navigation | Tab bar, sidebar, drawer |
422
- | `feedback` | System status messages | Toast, dialog, banner |
423
- | `surface` | Contains other components | Sheet, modal, popover |
424
- | `collection` | Repeating data sets | List, grid, table |
95
+ | Doc | What's in it |
96
+ |-----|-------------|
97
+ | [CLI & MCP Tools](./docs/cli.md) | All CLI commands, MCP tools, screenshot params, target workflow |
98
+ | [File Formats & Schemas](./docs/file-formats.md) | File types, JSON schemas, output directories, spec sections |
99
+ | [Full Specification](./spec/openuispec-v0.1.md) | Complete v0.1 spec (14 sections) |
100
+ | [llms-full.txt](https://openuispec.rsteam.uz/llms-full.txt) | Spec + all schemas in one file (for AI consumption) |
425
101
 
426
102
  ## Status
427
103
 
428
- **v0.1 — Draft**. The spec covers all foundational layers. TaskFlow provides a compact reference app, Todo Orbit extends coverage with localization, recurring-rule flows, custom contracts, and generated native/web targets, and Social App demonstrates a trilingual social feed app with generated Android and web targets.
104
+ **v0.1 — Draft**. The spec covers all foundational layers with three example apps demonstrating generation across iOS, Android, and Web.
429
105
 
430
106
  ### Roadmap
431
107
 
432
- - [x] Token system with constrained ranges
433
- - [x] 7 component contract families
434
- - [x] Adaptive layout system (size classes + reflow rules)
435
- - [x] Action system (13 types, composition, optimistic updates)
436
- - [x] Data binding & state management (sources, expressions, caching)
437
- - [x] Format expression grammar with computed expressions
438
- - [x] Internationalization (i18n) with ICU MessageFormat and `$t:` references
439
- - [x] JSON Schema for spec validation
440
- - [x] Custom contract extension mechanism
441
- - [x] Icon system definition
442
- - [x] Form system (validation rules, field dependencies)
443
- - [x] Drift detection (spec change tracking per platform)
444
- - [x] CLI tool (`openuispec init` for project scaffolding + AI rules)
445
- - [x] MCP server for AI tool integration (`openuispec-mcp`)
446
- - [x] Multi-platform showcase app (`examples/todo-orbit/`)
447
- - [x] Social app example (`examples/social-app/`)
108
+ - [x] Token system, 7 contract families, adaptive layout, action system
109
+ - [x] Data binding, i18n, form validation, custom contract extensions
110
+ - [x] JSON Schema validation, CLI tool, MCP server
111
+ - [x] Drift detection, visual verification (screenshots)
112
+ - [x] Example apps: TaskFlow, Todo Orbit, Social App
448
113
  - [ ] More example apps (e-commerce, dashboard)
449
114
 
450
115
  ## Contributing
package/cli/init.ts CHANGED
@@ -558,7 +558,7 @@ const JSON_MCP_PATHS = [
558
558
  const CODEX_CONFIG_PATH = join(".codex", "config.toml");
559
559
  const CODEX_MCP_BLOCK = `\n[mcp_servers.openuispec]\ncommand = "openuispec"\nargs = ["mcp"]\n`;
560
560
 
561
- function configureCodexMcp(cwd: string, quiet: boolean): void {
561
+ function configureCodexMcp(cwd: string, quiet: boolean): boolean {
562
562
  const codexDir = join(cwd, ".codex");
563
563
 
564
564
  const configPath = join(codexDir, "config.toml");
@@ -572,18 +572,22 @@ function configureCodexMcp(cwd: string, quiet: boolean): void {
572
572
 
573
573
  if (content.includes("[mcp_servers.openuispec]")) {
574
574
  if (!quiet) console.log(` skip ${CODEX_CONFIG_PATH} (openuispec MCP already configured)`);
575
- return;
575
+ return false;
576
576
  }
577
577
 
578
578
  if (!existsSync(codexDir)) mkdirSync(codexDir);
579
579
  writeFileSync(configPath, content + CODEX_MCP_BLOCK);
580
580
  if (!quiet) console.log(` ${content ? "update" : "create"} ${CODEX_CONFIG_PATH} (MCP server configured)`);
581
+ return true;
581
582
  } catch {
582
583
  if (!quiet) console.log(` skip ${CODEX_CONFIG_PATH} (could not configure MCP server)`);
584
+ return false;
583
585
  }
584
586
  }
585
587
 
586
588
  function configureMcp(cwd: string, showRestart: boolean, quiet: boolean = false): void {
589
+ let changed = false;
590
+
587
591
  for (const relPath of JSON_MCP_PATHS) {
588
592
  const configPath = join(cwd, relPath);
589
593
 
@@ -611,6 +615,7 @@ function configureMcp(cwd: string, showRestart: boolean, quiet: boolean = false)
611
615
  config.mcpServers.openuispec = { ...EXPECTED_MCP_CONFIG };
612
616
  writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
613
617
  if (!quiet) console.log(` ${existing ? "update" : "create"} ${relPath} (MCP server configured)`);
618
+ changed = true;
614
619
  } else {
615
620
  if (!quiet) console.log(` skip ${relPath} (openuispec MCP already configured)`);
616
621
  }
@@ -620,9 +625,9 @@ function configureMcp(cwd: string, showRestart: boolean, quiet: boolean = false)
620
625
  }
621
626
 
622
627
  // Codex: .codex/config.toml (TOML format)
623
- configureCodexMcp(cwd, quiet);
628
+ if (configureCodexMcp(cwd, quiet)) changed = true;
624
629
 
625
- if (showRestart) console.log(`\n Restart your AI coding agent to activate the MCP server.`);
630
+ if (showRestart && changed) console.log(`\n Restart your AI coding agent to activate the MCP server.`);
626
631
 
627
632
  // Clean up stale .claude.json MCP config from older versions
628
633
  const claudeJsonPath = join(cwd, ".claude.json");
package/docs/cli.md ADDED
@@ -0,0 +1,130 @@
1
+ # CLI & MCP Tools Reference
2
+
3
+ All MCP tools have equivalent CLI commands. The MCP server is used by AI coding agents automatically; the CLI is for manual use and scripts.
4
+
5
+ ## Setup
6
+
7
+ `openuispec init` and `openuispec update-rules` automatically configure MCP for all supported agents:
8
+
9
+ | Agent | Config file | Created automatically |
10
+ |-------|------------|----------------------|
11
+ | **Claude Code** | `.mcp.json` | Always |
12
+ | **Codex** | `.codex/config.toml` | Always |
13
+ | **VS Code / Copilot** | `.vscode/mcp.json` | If `.vscode/` exists |
14
+ | **Gemini CLI** | `.gemini/settings.json` | If `.gemini/` exists |
15
+
16
+ Manual setup (if needed):
17
+
18
+ **Claude Code** (`.mcp.json`), **VS Code / Copilot** (`.vscode/mcp.json`), **Gemini CLI** (`.gemini/settings.json`):
19
+ ```json
20
+ {
21
+ "mcpServers": {
22
+ "openuispec": {
23
+ "command": "openuispec",
24
+ "args": ["mcp"]
25
+ }
26
+ }
27
+ }
28
+ ```
29
+
30
+ **Codex** (`.codex/config.toml`):
31
+ ```toml
32
+ [mcp_servers.openuispec]
33
+ command = "openuispec"
34
+ args = ["mcp"]
35
+ ```
36
+
37
+ Or run directly: `openuispec mcp`
38
+
39
+ ## MCP Tools
40
+
41
+ | Tool | When | What it does |
42
+ |------|------|-------------|
43
+ | `openuispec_spec_types` | Before creating spec files | Lists all available spec types with descriptions |
44
+ | `openuispec_spec_schema` | Before creating/editing spec files | Returns the full JSON schema for a specific spec type |
45
+ | `openuispec_prepare` | Before UI code generation | Returns spec context, platform config, generation constraints |
46
+ | `openuispec_read_specs` | Before and after generation | Loads spec file contents — the authoritative source |
47
+ | `openuispec_check` | After generation | Schema validation + concrete audit checklist. Optional `screens`/`contracts` params scope the audit |
48
+ | `openuispec_validate` | After spec edits | Schema-only validation, optionally filtered by group |
49
+ | `openuispec_drift` | Before updates | Detect spec drift since last snapshot, with semantic explanation |
50
+ | `openuispec_status` | Anytime | Cross-target summary: baselines, drift, next steps |
51
+ | `openuispec_get_screen` | Incremental edits | Get a single screen spec by name |
52
+ | `openuispec_get_contract` | Incremental edits | Get a single contract spec, optionally filtered to one variant |
53
+ | `openuispec_get_tokens` | Incremental edits | Get tokens for a specific category |
54
+ | `openuispec_get_locale` | Incremental edits | Get a single locale file, optionally filtered to specific keys |
55
+ | `openuispec_screenshot` | Visual verification | Screenshot the web app at a route via headless browser |
56
+ | `openuispec_screenshot_android` | Visual verification | Screenshot Android app on emulator. Works with any project via `project_dir` |
57
+ | `openuispec_screenshot_ios` | Visual verification | Screenshot iOS app on Simulator via XCUITest. Works with any project via `project_dir` |
58
+
59
+ The server includes **protocol-level instructions** that trigger on UI-related requests independently of CLAUDE.md rules.
60
+
61
+ ## CLI Commands
62
+
63
+ ### Workflow
64
+
65
+ ```bash
66
+ openuispec init # Scaffold a new spec project
67
+ openuispec init --defaults # Non-interactive with unconfirmed defaults
68
+ openuispec init --no-configure-targets # Skip target stack setup
69
+ openuispec update-rules # Update AI rules to match installed version
70
+ openuispec configure-target <t> [--defaults] # Configure target stack
71
+ openuispec validate [group...] [--json] # Validate spec files
72
+ openuispec validate semantic # Semantic cross-reference linting
73
+ openuispec status [--json] # Cross-target baseline/drift status
74
+ openuispec drift --target <t> --explain # Explain semantic spec drift
75
+ openuispec prepare --target <t> [--json] # Build the target work bundle
76
+ openuispec check --target <t> [--json] # Composite validation + prepare readiness
77
+ openuispec drift --snapshot --target <t> # Snapshot current state + git baseline
78
+ ```
79
+
80
+ ### Spec access
81
+
82
+ ```bash
83
+ openuispec read-specs [paths...] # Read spec file contents as JSON
84
+ openuispec get-screen <name> # Get a single screen spec (YAML)
85
+ openuispec get-contract <name> [--variant v] # Get a contract spec
86
+ openuispec get-tokens <category> # Get tokens for a category (YAML)
87
+ openuispec get-locale <locale> [--keys k1,k2] # Get a locale file (JSON)
88
+ openuispec spec-types # List available spec types
89
+ openuispec spec-schema <type> # Get JSON schema for a spec type
90
+ ```
91
+
92
+ ### Screenshots
93
+
94
+ ```bash
95
+ openuispec screenshot --route /home [--theme dark] [--output-dir dir]
96
+ openuispec screenshot-android [--project-dir path] [--screen name] [--module name] [--route deeplink]
97
+ openuispec screenshot-ios [--project-dir path] [--screen name] [--scheme name] [--bundle-id id]
98
+ ```
99
+
100
+ Screenshot tools work with **any** project — use `--project-dir` to skip manifest lookup.
101
+
102
+ | Param | Android | iOS | Purpose |
103
+ |-------|---------|-----|---------|
104
+ | `--project-dir` | yes | yes | Point directly at project root |
105
+ | `--module` | yes | -- | Override app module name (default: auto-detect) |
106
+ | `--scheme` | -- | yes | Override Xcode scheme (default: auto-detect) |
107
+ | `--bundle-id` | -- | yes | Override bundle ID (default: auto-detect) |
108
+ | `--route` | yes | -- | Deep link URI for navigation |
109
+ | `--nav` | yes | yes | UI tap steps, comma-separated |
110
+ | `--theme` | yes | yes | Force light or dark mode |
111
+ | `--device` | -- | yes | Simulator device name |
112
+ | `--output-dir` | yes | yes | Save screenshot to directory |
113
+
114
+ ## Target Update Workflow
115
+
116
+ When a shared spec change needs to be applied to a target:
117
+
118
+ ```bash
119
+ openuispec validate
120
+ openuispec validate semantic
121
+ openuispec status
122
+ openuispec drift --target ios --explain
123
+ openuispec prepare --target ios
124
+ # update the ios implementation
125
+ openuispec drift --snapshot --target ios
126
+ ```
127
+
128
+ - `prepare` runs in `bootstrap` mode for first-time generation and `update` mode after a snapshot exists
129
+ - `drift --snapshot` is bookkeeping — it does not prove code matches the spec, and requires the output directory to exist
130
+ - Run `openuispec status` between targets to see what still needs updating
@@ -0,0 +1,84 @@
1
+ # File Formats & Schemas
2
+
3
+ Every file type has a corresponding JSON Schema in `schema/`. **Read the schema before creating or editing a file** — do not guess the structure.
4
+
5
+ ## File type reference
6
+
7
+ | File | Schema | Root key | Example |
8
+ |------|--------|----------|---------|
9
+ | `openuispec.yaml` | `openuispec.schema.json` | `spec_version` | [openuispec.yaml](../examples/taskflow/openuispec/openuispec.yaml) |
10
+ | `screens/*.yaml` | `screen.schema.json` | `<screen_id>` | [home.yaml](../examples/taskflow/openuispec/screens/home.yaml) |
11
+ | `flows/*.yaml` | `flow.schema.json` | `<flow_id>` | [create_task.yaml](../examples/taskflow/openuispec/flows/create_task.yaml) |
12
+ | `platform/*.yaml` | `platform.schema.json` | `platform` | [ios.yaml](../examples/taskflow/openuispec/platform/ios.yaml) |
13
+ | `locales/*.json` | `locale.schema.json` | (object) | [en.json](../examples/taskflow/openuispec/locales/en.json) |
14
+ | `contracts/<name>.yaml` | `contract.schema.json` | `<contract_name>` | [input_field.yaml](../examples/taskflow/openuispec/contracts/input_field.yaml) |
15
+ | `contracts/x_*.yaml` | `custom-contract.schema.json` | `<x_name>` | [x_media_player.yaml](../examples/taskflow/openuispec/contracts/x_media_player.yaml) |
16
+ | `tokens/color.yaml` | `tokens/color.schema.json` | `color` | [color.yaml](../examples/taskflow/openuispec/tokens/color.yaml) |
17
+ | `tokens/typography.yaml` | `tokens/typography.schema.json` | `typography` | [typography.yaml](../examples/taskflow/openuispec/tokens/typography.yaml) |
18
+ | `tokens/spacing.yaml` | `tokens/spacing.schema.json` | `spacing` | [spacing.yaml](../examples/taskflow/openuispec/tokens/spacing.yaml) |
19
+ | `tokens/elevation.yaml` | `tokens/elevation.schema.json` | `elevation` | [elevation.yaml](../examples/taskflow/openuispec/tokens/elevation.yaml) |
20
+ | `tokens/motion.yaml` | `tokens/motion.schema.json` | `motion` | [motion.yaml](../examples/taskflow/openuispec/tokens/motion.yaml) |
21
+ | `tokens/layout.yaml` | `tokens/layout.schema.json` | `layout` | [layout.yaml](../examples/taskflow/openuispec/tokens/layout.yaml) |
22
+ | `tokens/themes.yaml` | `tokens/themes.schema.json` | `themes` | [themes.yaml](../examples/taskflow/openuispec/tokens/themes.yaml) |
23
+ | `tokens/icons.yaml` | `tokens/icons.schema.json` | `icons` | [icons.yaml](../examples/taskflow/openuispec/tokens/icons.yaml) |
24
+
25
+ Every token file **must** have a single root wrapper key matching its type:
26
+
27
+ ```yaml
28
+ # Correct — tokens/color.yaml
29
+ color:
30
+ brand:
31
+ primary: ...
32
+
33
+ # Wrong — missing root key
34
+ brand:
35
+ primary: ...
36
+ ```
37
+
38
+ ## Shared interactive state roles
39
+
40
+ Interactive contracts may optionally express state-specific visual roles inside their token maps with a nested `states:` object. This lets generators use explicit roles for `default`, `active`, `selected`, `pressed`, `focused`, `disabled`, `loading`, and `error` states.
41
+
42
+ Allowed visual role keys: `background`, `text`, `icon`, `border`, `badge_background`, `badge_text`.
43
+
44
+ When `states:` is omitted, generators fall back to the token values defined at that level plus the base contract semantics.
45
+
46
+ ## Output directories
47
+
48
+ By default, drift stores state in `generated/<target>/<project>/`. To point targets to your actual code directories:
49
+
50
+ ```yaml
51
+ generation:
52
+ targets: [ios, android, web]
53
+ output_dir:
54
+ web: "../web-ui/"
55
+ android: "../kmp-ui/"
56
+ ios: "../kmp-ui/iosApp/"
57
+ code_roots:
58
+ backend: "../api/"
59
+ ```
60
+
61
+ Paths are relative to `openuispec.yaml`. The `.openuispec-state.json` file records spec file hashes plus the git baseline commit metadata.
62
+
63
+ - If `api.endpoints` are declared, `generation.code_roots.backend` is required
64
+ - `generation.extra_rules` can hold project-wide generation conventions
65
+ - `drift --snapshot` requires that target output directory to already exist
66
+
67
+ ## Spec sections overview
68
+
69
+ | Section | What it defines |
70
+ |---------|----------------|
71
+ | 1. Philosophy | Core principles: semantic, constrained, contract-driven, AI-first |
72
+ | 2. Document structure | Project layout and root manifest |
73
+ | 3. Token layer | Color, typography, spacing, elevation, motion, layout, themes, icons |
74
+ | 4. Component contracts | 7 behavioral families |
75
+ | 5. Screen composition | Contract-based layouts, adaptive layout system |
76
+ | 6. Navigation flows | Multi-screen journeys with transitions and progress |
77
+ | 7. Platform adaptation | Per-target overrides for iOS, Android, Web |
78
+ | 8. AI generation contract | Compliance levels (MUST/SHOULD/MAY), validation, drift detection |
79
+ | 9. Action system | 14 action types, composition, optimistic updates |
80
+ | 10. Data binding & state | Sources, paths, format expressions, reactivity, caching |
81
+ | 11. Internationalization | Locale files, `$t:` references, ICU MessageFormat, RTL |
82
+ | 12. Custom contract extensions | `x_` prefixed domain-specific contracts |
83
+ | 13. Form validation | Validation rules, field dependencies, cross-field checks |
84
+ | 14. Development workflow | Dual-workflow model, drift detection, spec as sync layer |
@@ -213,18 +213,14 @@ export async function adbExec(adb: string, serial: string, args: string): Promis
213
213
  // ── emulator storage cleanup ─────────────────────────────────────────
214
214
 
215
215
  export async function cleanEmulatorStorage(adb: string, serial: string): Promise<void> {
216
- try {
217
- // Clear package manager cache
218
- await adbShell(adb, serial, `pm trim-caches 512M`);
219
- } catch { /* may require root, skip */ }
220
- try {
221
- // Remove leftover screenshot/temp files
222
- await adbShell(adb, serial, `rm -f /sdcard/openuispec_screenshot.png /sdcard/ui_dump.xml /sdcard/screenshot.png`);
223
- } catch { /* ignore */ }
224
- try {
225
- // Clear temp files
226
- await adbShell(adb, serial, `rm -rf /data/local/tmp/*.apk`);
227
- } catch { /* ignore */ }
216
+ const cmds = [
217
+ `pm trim-caches 2G`, // aggressively trim package cache
218
+ `rm -rf /data/local/tmp/*.apk`, // leftover APKs from previous installs
219
+ `rm -f /sdcard/openuispec_screenshot.png /sdcard/ui_dump.xml /sdcard/screenshot.png`,
220
+ ];
221
+ for (const cmd of cmds) {
222
+ try { await adbShell(adb, serial, cmd); } catch { /* ignore */ }
223
+ }
228
224
  }
229
225
 
230
226
  // ── build APK ───────────────────────────────────────────────────────
@@ -269,23 +265,20 @@ export async function installAndLaunch(
269
265
  appInfo: AppInfo,
270
266
  route?: string,
271
267
  ): Promise<void> {
272
- // Install (replace existing)
273
- await adbExec(adb, serial, `install -r "${apkPath}"`);
274
-
275
- // Force-stop and clear saved navigation state
268
+ // Force-stop and uninstall to free storage + wipe saved nav state
276
269
  await adbShell(adb, serial, `am force-stop ${appInfo.applicationId}`);
270
+ try { await adbShell(adb, serial, `pm uninstall ${appInfo.applicationId}`); } catch { /* not installed */ }
277
271
 
278
- // FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK = 0x10008000
279
- // Clears saved navigation state so deep links route correctly
280
- const clearFlags = `-f 0x10008000`;
272
+ // Install fresh (not -r replace, since we uninstalled)
273
+ await adbExec(adb, serial, `install "${apkPath}"`);
281
274
 
282
275
  if (route) {
283
276
  await adbShell(adb, serial,
284
- `am start -W -a android.intent.action.VIEW -d "${route}" ${clearFlags} ` +
277
+ `am start -W -a android.intent.action.VIEW -d '${route}' ` +
285
278
  `${appInfo.applicationId}/${appInfo.launchActivity}`);
286
279
  } else {
287
280
  await adbShell(adb, serial,
288
- `am start -W ${clearFlags} -n ${appInfo.applicationId}/${appInfo.launchActivity}`);
281
+ `am start -W -n ${appInfo.applicationId}/${appInfo.launchActivity}`);
289
282
  }
290
283
  }
291
284
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openuispec",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "A semantic UI specification format for AI-native, platform-native app development",