openuispec 0.2.13 → 0.2.15
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 +6 -5
- package/cli/index.ts +18 -12
- package/cli/init.ts +79 -13
- package/docs/cli.md +134 -27
- package/docs/file-formats.md +51 -1
- package/drift/index.ts +7 -2
- package/examples/social-app/openuispec/README.md +2 -1
- package/examples/social-app/openuispec/mock/chat_detail.yaml +25 -0
- package/examples/social-app/openuispec/mock/discover.yaml +17 -0
- package/examples/social-app/openuispec/mock/edit_profile.yaml +9 -0
- package/examples/social-app/openuispec/mock/home_feed.yaml +32 -0
- package/examples/social-app/openuispec/mock/messages_inbox.yaml +15 -0
- package/examples/social-app/openuispec/mock/notifications.yaml +30 -0
- package/examples/social-app/openuispec/mock/post_detail.yaml +26 -0
- package/examples/social-app/openuispec/mock/profile_self.yaml +28 -0
- package/examples/social-app/openuispec/mock/profile_user.yaml +32 -0
- package/examples/social-app/openuispec/mock/search_results.yaml +17 -0
- package/examples/social-app/openuispec/mock/settings.yaml +7 -0
- package/examples/social-app/openuispec/openuispec.yaml +3 -2
- package/examples/taskflow/README.md +4 -2
- package/examples/taskflow/openuispec/README.md +2 -1
- package/examples/taskflow/openuispec/components/media_player.yaml +92 -0
- package/examples/taskflow/openuispec/contracts/README.md +2 -2
- package/examples/taskflow/openuispec/locales/en.json +1 -0
- package/examples/taskflow/openuispec/mock/home.yaml +64 -0
- package/examples/taskflow/openuispec/mock/profile_edit.yaml +6 -0
- package/examples/taskflow/openuispec/mock/project_detail.yaml +33 -0
- package/examples/taskflow/openuispec/mock/settings.yaml +13 -0
- package/examples/taskflow/openuispec/mock/task_detail.yaml +18 -0
- package/examples/taskflow/openuispec/openuispec.yaml +3 -4
- package/examples/taskflow/openuispec/platform/ios.yaml +0 -4
- package/examples/taskflow/openuispec/screens/task_detail.yaml +5 -8
- package/examples/taskflow/openuispec/tokens/icons.yaml +16 -0
- package/examples/todo-orbit/README.md +3 -2
- package/examples/todo-orbit/openuispec/README.md +2 -1
- package/examples/todo-orbit/openuispec/components/task_trend_chart.yaml +85 -0
- package/examples/todo-orbit/openuispec/locales/en.json +3 -0
- package/examples/todo-orbit/openuispec/locales/ru.json +3 -0
- package/examples/todo-orbit/openuispec/mock/analytics.yaml +26 -0
- package/examples/todo-orbit/openuispec/mock/home.yaml +33 -0
- package/examples/todo-orbit/openuispec/mock/settings.yaml +7 -0
- package/examples/todo-orbit/openuispec/mock/task_detail.yaml +14 -0
- package/examples/todo-orbit/openuispec/openuispec.yaml +3 -3
- package/examples/todo-orbit/openuispec/platform/android.yaml +0 -3
- package/examples/todo-orbit/openuispec/platform/ios.yaml +0 -3
- package/examples/todo-orbit/openuispec/platform/web.yaml +0 -3
- package/examples/todo-orbit/openuispec/screens/analytics.yaml +1 -4
- package/mcp-server/index.ts +87 -6
- package/mcp-server/preview-render.ts +1922 -0
- package/mcp-server/preview.ts +292 -0
- package/mcp-server/screenshot-shared.ts +41 -4
- package/mcp-server/screenshot.ts +283 -97
- package/package.json +1 -1
- package/prepare/index.ts +1 -1
- package/schema/component.schema.json +278 -0
- package/schema/openuispec.schema.json +5 -1
- package/schema/screen.schema.json +12 -1
- package/schema/semantic-lint.ts +29 -5
- package/schema/validate.ts +21 -0
- package/scripts/regenerate-previews.ts +136 -0
- package/spec/{openuispec-v0.1.md → openuispec-v0.2.md} +266 -8
- package/examples/taskflow/openuispec/contracts/x_media_player.yaml +0 -185
- package/examples/todo-orbit/openuispec/contracts/x_task_trend_chart.yaml +0 -139
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Mock data for the chat_detail screen
|
|
2
|
+
data:
|
|
3
|
+
conversation:
|
|
4
|
+
id: "c1"
|
|
5
|
+
participant: { id: "u2", display_name: "Sara Kim", avatar_url: null }
|
|
6
|
+
|
|
7
|
+
messages:
|
|
8
|
+
- id: "m1"
|
|
9
|
+
sender: { display_name: "Sara Kim" }
|
|
10
|
+
body: "Hey! Are you coming to the meetup tomorrow?"
|
|
11
|
+
created_at: "2026-03-18T10:30:00Z"
|
|
12
|
+
is_mine: false
|
|
13
|
+
- id: "m2"
|
|
14
|
+
sender: { display_name: "Jamie Taylor" }
|
|
15
|
+
body: "Yes, definitely! What time does it start?"
|
|
16
|
+
created_at: "2026-03-18T10:35:00Z"
|
|
17
|
+
is_mine: true
|
|
18
|
+
- id: "m3"
|
|
19
|
+
sender: { display_name: "Sara Kim" }
|
|
20
|
+
body: "6 PM at the usual place. See you there!"
|
|
21
|
+
created_at: "2026-03-18T10:45:00Z"
|
|
22
|
+
is_mine: false
|
|
23
|
+
|
|
24
|
+
params:
|
|
25
|
+
conversation_id: "c1"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Mock data for the discover screen
|
|
2
|
+
data:
|
|
3
|
+
creators:
|
|
4
|
+
- { id: "u5", display_name: "Alex Rivera", handle: "alexr", bio: "Tech writer & developer", followers_count: 12400, avatar_url: null }
|
|
5
|
+
- { id: "u6", display_name: "Jordan Lee", handle: "jordanlee", bio: "Photographer & traveler", followers_count: 8900, avatar_url: null }
|
|
6
|
+
- { id: "u7", display_name: "Priya Patel", handle: "priyap", bio: "Food blogger & chef", followers_count: 23100, avatar_url: null }
|
|
7
|
+
|
|
8
|
+
trends:
|
|
9
|
+
- { id: "tr1", label: "#TechTuesday", post_count: 1240 }
|
|
10
|
+
- { id: "tr2", label: "#MorningRoutine", post_count: 890 }
|
|
11
|
+
- { id: "tr3", label: "#BookClub", post_count: 567 }
|
|
12
|
+
- { id: "tr4", label: "#FitnessGoals", post_count: 2100 }
|
|
13
|
+
|
|
14
|
+
tags:
|
|
15
|
+
- { id: "tg1", name: "Technology", post_count: 45200 }
|
|
16
|
+
- { id: "tg2", name: "Photography", post_count: 32100 }
|
|
17
|
+
- { id: "tg3", name: "Food", post_count: 28900 }
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Mock data for the home_feed screen
|
|
2
|
+
data:
|
|
3
|
+
stories:
|
|
4
|
+
- { id: "s1", author: { display_name: "Sara" }, preview_url: null, has_new: true }
|
|
5
|
+
- { id: "s2", author: { display_name: "Mike" }, preview_url: null, has_new: true }
|
|
6
|
+
- { id: "s3", author: { display_name: "Lena" }, preview_url: null, has_new: false }
|
|
7
|
+
|
|
8
|
+
feed:
|
|
9
|
+
- id: "p1"
|
|
10
|
+
author: { id: "u2", display_name: "Sara Kim", handle: "sarakim", avatar_url: null }
|
|
11
|
+
body: "Just shipped a new feature! The team worked incredibly hard on this one. So proud of everyone involved."
|
|
12
|
+
media_url: null
|
|
13
|
+
like_count: 42
|
|
14
|
+
comment_count: 7
|
|
15
|
+
is_liked: false
|
|
16
|
+
published_at: "2026-03-18T10:30:00Z"
|
|
17
|
+
- id: "p2"
|
|
18
|
+
author: { id: "u3", display_name: "Mike Chen", handle: "mikechen", avatar_url: null }
|
|
19
|
+
body: "Beautiful morning for a run. Hit a new personal best today!"
|
|
20
|
+
media_url: null
|
|
21
|
+
like_count: 128
|
|
22
|
+
comment_count: 23
|
|
23
|
+
is_liked: true
|
|
24
|
+
published_at: "2026-03-18T08:15:00Z"
|
|
25
|
+
- id: "p3"
|
|
26
|
+
author: { id: "u4", display_name: "Lena Park", handle: "lenapark", avatar_url: null }
|
|
27
|
+
body: "Reading recommendations for the weekend? I just finished 'Project Hail Mary' and need something new."
|
|
28
|
+
media_url: null
|
|
29
|
+
like_count: 15
|
|
30
|
+
comment_count: 31
|
|
31
|
+
is_liked: false
|
|
32
|
+
published_at: "2026-03-17T22:00:00Z"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Mock data for the messages_inbox screen
|
|
2
|
+
data:
|
|
3
|
+
conversations:
|
|
4
|
+
- id: "c1"
|
|
5
|
+
participant: { id: "u2", display_name: "Sara Kim", avatar_url: null }
|
|
6
|
+
last_message: { body: "See you tomorrow at the meetup!", created_at: "2026-03-18T10:45:00Z" }
|
|
7
|
+
unread_count: 2
|
|
8
|
+
- id: "c2"
|
|
9
|
+
participant: { id: "u3", display_name: "Mike Chen", avatar_url: null }
|
|
10
|
+
last_message: { body: "Thanks for sharing that article", created_at: "2026-03-17T20:30:00Z" }
|
|
11
|
+
unread_count: 0
|
|
12
|
+
- id: "c3"
|
|
13
|
+
participant: { id: "u5", display_name: "Alex Rivera", avatar_url: null }
|
|
14
|
+
last_message: { body: "Let me check and get back to you", created_at: "2026-03-16T15:00:00Z" }
|
|
15
|
+
unread_count: 0
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Mock data for the notifications screen
|
|
2
|
+
data:
|
|
3
|
+
notifications:
|
|
4
|
+
- id: "n1"
|
|
5
|
+
type: like
|
|
6
|
+
actor: { id: "u2", display_name: "Sara Kim", avatar_url: null }
|
|
7
|
+
message: "liked your post"
|
|
8
|
+
post: { id: "p10", title: "My weekend project" }
|
|
9
|
+
created_at: "2026-03-18T11:00:00Z"
|
|
10
|
+
is_read: false
|
|
11
|
+
- id: "n2"
|
|
12
|
+
type: comment
|
|
13
|
+
actor: { id: "u3", display_name: "Mike Chen", avatar_url: null }
|
|
14
|
+
message: "commented: This looks amazing!"
|
|
15
|
+
post: { id: "p10", title: "My weekend project" }
|
|
16
|
+
created_at: "2026-03-18T09:30:00Z"
|
|
17
|
+
is_read: false
|
|
18
|
+
- id: "n3"
|
|
19
|
+
type: follow
|
|
20
|
+
actor: { id: "u5", display_name: "Alex Rivera", avatar_url: null }
|
|
21
|
+
message: "started following you"
|
|
22
|
+
created_at: "2026-03-17T18:00:00Z"
|
|
23
|
+
is_read: true
|
|
24
|
+
- id: "n4"
|
|
25
|
+
type: mention
|
|
26
|
+
actor: { id: "u4", display_name: "Lena Park", avatar_url: null }
|
|
27
|
+
message: "mentioned you in a post"
|
|
28
|
+
post: { id: "p8", title: "Team outing photos" }
|
|
29
|
+
created_at: "2026-03-17T14:00:00Z"
|
|
30
|
+
is_read: true
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Mock data for the post_detail screen
|
|
2
|
+
data:
|
|
3
|
+
post:
|
|
4
|
+
id: "p1"
|
|
5
|
+
author: { id: "u2", display_name: "Sara Kim", handle: "sarakim", avatar_url: null }
|
|
6
|
+
body: "Just shipped a new feature! The team worked incredibly hard on this one. So proud of everyone involved."
|
|
7
|
+
media_url: null
|
|
8
|
+
like_count: 42
|
|
9
|
+
comment_count: 7
|
|
10
|
+
is_liked: false
|
|
11
|
+
published_at: "2026-03-18T10:30:00Z"
|
|
12
|
+
|
|
13
|
+
comments:
|
|
14
|
+
- id: "cm1"
|
|
15
|
+
author: { id: "u3", display_name: "Mike Chen", handle: "mikechen", avatar_url: null }
|
|
16
|
+
body: "Congrats! What was the hardest part?"
|
|
17
|
+
created_at: "2026-03-18T11:00:00Z"
|
|
18
|
+
like_count: 5
|
|
19
|
+
- id: "cm2"
|
|
20
|
+
author: { id: "u4", display_name: "Lena Park", handle: "lenapark", avatar_url: null }
|
|
21
|
+
body: "Amazing work, well deserved!"
|
|
22
|
+
created_at: "2026-03-18T11:30:00Z"
|
|
23
|
+
like_count: 3
|
|
24
|
+
|
|
25
|
+
params:
|
|
26
|
+
post_id: "p1"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Mock data for the profile_self screen
|
|
2
|
+
data:
|
|
3
|
+
profile:
|
|
4
|
+
id: "u1"
|
|
5
|
+
display_name: "Jamie Taylor"
|
|
6
|
+
handle: "jamiet"
|
|
7
|
+
bio: "Designer & developer. Building things that matter."
|
|
8
|
+
website: "https://jamietaylor.dev"
|
|
9
|
+
avatar_url: null
|
|
10
|
+
followers_count: 1240
|
|
11
|
+
following_count: 380
|
|
12
|
+
posts_count: 86
|
|
13
|
+
|
|
14
|
+
posts:
|
|
15
|
+
- id: "p10"
|
|
16
|
+
author: { display_name: "Jamie Taylor" }
|
|
17
|
+
body: "My weekend project — a mini weather station with Raspberry Pi"
|
|
18
|
+
media_url: null
|
|
19
|
+
like_count: 28
|
|
20
|
+
comment_count: 12
|
|
21
|
+
published_at: "2026-03-17T16:00:00Z"
|
|
22
|
+
- id: "p11"
|
|
23
|
+
author: { display_name: "Jamie Taylor" }
|
|
24
|
+
body: "New blog post about design tokens and how they simplify theming across platforms"
|
|
25
|
+
media_url: null
|
|
26
|
+
like_count: 64
|
|
27
|
+
comment_count: 8
|
|
28
|
+
published_at: "2026-03-15T09:00:00Z"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Mock data for the profile_user screen
|
|
2
|
+
data:
|
|
3
|
+
profile:
|
|
4
|
+
id: "u2"
|
|
5
|
+
display_name: "Sara Kim"
|
|
6
|
+
handle: "sarakim"
|
|
7
|
+
bio: "Product engineer at Acme. Coffee enthusiast."
|
|
8
|
+
website: "https://sarakim.io"
|
|
9
|
+
avatar_url: null
|
|
10
|
+
followers_count: 3200
|
|
11
|
+
following_count: 560
|
|
12
|
+
posts_count: 142
|
|
13
|
+
is_following: true
|
|
14
|
+
|
|
15
|
+
posts:
|
|
16
|
+
- id: "p1"
|
|
17
|
+
author: { id: "u2", display_name: "Sara Kim", handle: "sarakim" }
|
|
18
|
+
body: "Just shipped a new feature! The team worked incredibly hard on this one."
|
|
19
|
+
media_url: null
|
|
20
|
+
like_count: 42
|
|
21
|
+
comment_count: 7
|
|
22
|
+
published_at: "2026-03-18T10:30:00Z"
|
|
23
|
+
- id: "p12"
|
|
24
|
+
author: { id: "u2", display_name: "Sara Kim", handle: "sarakim" }
|
|
25
|
+
body: "Coffee shop recommendations in SF anyone?"
|
|
26
|
+
media_url: null
|
|
27
|
+
like_count: 19
|
|
28
|
+
comment_count: 15
|
|
29
|
+
published_at: "2026-03-16T14:00:00Z"
|
|
30
|
+
|
|
31
|
+
params:
|
|
32
|
+
user_id: "u2"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Mock data for the search_results screen
|
|
2
|
+
data:
|
|
3
|
+
results:
|
|
4
|
+
- id: "p20"
|
|
5
|
+
title: "Mike Chen"
|
|
6
|
+
subtitle: "@mikechen"
|
|
7
|
+
body: "Best running apps for 2026 — a comprehensive review"
|
|
8
|
+
avatar_url: null
|
|
9
|
+
- id: "u8"
|
|
10
|
+
title: "Taylor Swift"
|
|
11
|
+
subtitle: "@taylorswift"
|
|
12
|
+
body: "Singer-songwriter"
|
|
13
|
+
avatar_url: null
|
|
14
|
+
|
|
15
|
+
params:
|
|
16
|
+
query: "running"
|
|
17
|
+
tab: "posts"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
# social-app — OpenUISpec v0.
|
|
2
|
-
spec_version: "0.
|
|
1
|
+
# social-app — OpenUISpec v0.2
|
|
2
|
+
spec_version: "0.2"
|
|
3
3
|
|
|
4
4
|
project:
|
|
5
5
|
name: "social-app"
|
|
@@ -8,6 +8,7 @@ project:
|
|
|
8
8
|
includes:
|
|
9
9
|
tokens: "./tokens/"
|
|
10
10
|
contracts: "./contracts/"
|
|
11
|
+
components: "./components/"
|
|
11
12
|
screens: "./screens/"
|
|
12
13
|
flows: "./flows/"
|
|
13
14
|
platform: "./platform/"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# TaskFlow — OpenUISpec Example Application
|
|
2
2
|
|
|
3
|
-
A complete task management app defined entirely in OpenUISpec v0.
|
|
3
|
+
A complete task management app defined entirely in OpenUISpec v0.2, demonstrating how a single source of truth generates native iOS, Android, and Web applications.
|
|
4
4
|
|
|
5
5
|
## What this demonstrates
|
|
6
6
|
|
|
@@ -68,6 +68,8 @@ taskflow/
|
|
|
68
68
|
│ ├── layout.yaml # Size classes, primitives, reflow rules
|
|
69
69
|
│ └── themes.yaml # Light, dark, warm variants
|
|
70
70
|
├── contracts/ # 7 contract family stubs (see spec Section 4)
|
|
71
|
+
├── components/
|
|
72
|
+
│ └── media_player.yaml # Media player component with slots and states
|
|
71
73
|
├── screens/
|
|
72
74
|
│ ├── home.yaml # Task list with search, filters, FAB, adaptive nav
|
|
73
75
|
│ ├── task_detail.yaml # Full task view with actions + assignee sheet
|
|
@@ -100,4 +102,4 @@ The AI should produce:
|
|
|
100
102
|
|
|
101
103
|
---
|
|
102
104
|
|
|
103
|
-
*TaskFlow is a reference implementation of OpenUISpec v0.
|
|
105
|
+
*TaskFlow is a reference implementation of OpenUISpec v0.2, not a production application.*
|
|
@@ -12,6 +12,7 @@ This directory contains the **OpenUISpec** semantic UI specification for **TaskF
|
|
|
12
12
|
| `screens/` | Screen definitions — one YAML file per screen |
|
|
13
13
|
| `flows/` | Navigation flows — multi-step user journeys |
|
|
14
14
|
| `contracts/` | Component contracts — standard extensions and custom (`x_` prefixed) |
|
|
15
|
+
| `components/` | Reusable compositions — contract slot compositions with states and variants |
|
|
15
16
|
| `platform/` | Platform overrides — per-target (iOS, Android, Web) behaviors |
|
|
16
17
|
| `locales/` | Localization — i18n strings (JSON, ICU MessageFormat) |
|
|
17
18
|
|
|
@@ -28,7 +29,7 @@ Do NOT guess the file format — skipping this step will produce invalid YAML th
|
|
|
28
29
|
|
|
29
30
|
**Reference files inside the package (read in this order):**
|
|
30
31
|
1. `README.md` — schema tables, file format reference, root wrapper keys
|
|
31
|
-
2. `spec/openuispec-v0.
|
|
32
|
+
2. `spec/openuispec-v0.2.md` — full specification (contracts, layout, expressions, etc.)
|
|
32
33
|
3. `examples/taskflow/openuispec/` — complete working example with all file types
|
|
33
34
|
4. `schema/` — JSON Schemas for validation
|
|
34
35
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# Component: media_player
|
|
3
|
+
# ============================================================
|
|
4
|
+
# Reusable media playback component composed from base contracts.
|
|
5
|
+
# Demonstrates the component spec type with slots, states,
|
|
6
|
+
# variants, and layout.
|
|
7
|
+
# ============================================================
|
|
8
|
+
|
|
9
|
+
media_player:
|
|
10
|
+
semantic: "Plays audio and video media with transport controls"
|
|
11
|
+
|
|
12
|
+
props:
|
|
13
|
+
source: { type: string, required: true }
|
|
14
|
+
media_type: { type: enum, values: [audio, video], required: true }
|
|
15
|
+
title: { type: string }
|
|
16
|
+
|
|
17
|
+
slots:
|
|
18
|
+
play_button:
|
|
19
|
+
contract: action_trigger
|
|
20
|
+
variant: icon
|
|
21
|
+
props: { label: "$t:media_player.play", icon: play }
|
|
22
|
+
hideable: true
|
|
23
|
+
scrubber:
|
|
24
|
+
contract: input_field
|
|
25
|
+
input_type: slider
|
|
26
|
+
props: { label: "$t:media_player.progress" }
|
|
27
|
+
hideable: true
|
|
28
|
+
time_label:
|
|
29
|
+
contract: data_display
|
|
30
|
+
variant: caption
|
|
31
|
+
hideable: true
|
|
32
|
+
volume_control:
|
|
33
|
+
contract: input_field
|
|
34
|
+
input_type: slider
|
|
35
|
+
hideable: true
|
|
36
|
+
|
|
37
|
+
layout:
|
|
38
|
+
type: stack
|
|
39
|
+
spacing: "spacing.sm"
|
|
40
|
+
sections:
|
|
41
|
+
- slot: play_button
|
|
42
|
+
- slot: scrubber
|
|
43
|
+
- layout:
|
|
44
|
+
type: row
|
|
45
|
+
sections:
|
|
46
|
+
- slot: time_label
|
|
47
|
+
- slot: volume_control
|
|
48
|
+
|
|
49
|
+
states:
|
|
50
|
+
idle: { semantic: "No media loaded" }
|
|
51
|
+
loading:
|
|
52
|
+
semantic: "Buffering"
|
|
53
|
+
hide_slots: [scrubber, volume_control]
|
|
54
|
+
playing:
|
|
55
|
+
semantic: "Actively playing"
|
|
56
|
+
slot_overrides:
|
|
57
|
+
play_button: { props: { icon: pause } }
|
|
58
|
+
paused:
|
|
59
|
+
semantic: "Paused at position"
|
|
60
|
+
slot_overrides:
|
|
61
|
+
play_button: { props: { icon: play } }
|
|
62
|
+
|
|
63
|
+
variants:
|
|
64
|
+
mini:
|
|
65
|
+
semantic: "Compact player for persistent bottom bar"
|
|
66
|
+
hide_slots: [volume_control]
|
|
67
|
+
layout:
|
|
68
|
+
type: row
|
|
69
|
+
sections:
|
|
70
|
+
- slot: play_button
|
|
71
|
+
- slot: scrubber
|
|
72
|
+
- slot: time_label
|
|
73
|
+
fullscreen:
|
|
74
|
+
semantic: "Full-screen immersive player"
|
|
75
|
+
tokens: { background: "#000000" }
|
|
76
|
+
|
|
77
|
+
tokens:
|
|
78
|
+
background: "color.surface.secondary"
|
|
79
|
+
radius: "spacing.md"
|
|
80
|
+
padding: "spacing.md"
|
|
81
|
+
|
|
82
|
+
a11y:
|
|
83
|
+
role: "group"
|
|
84
|
+
label: "props.title"
|
|
85
|
+
|
|
86
|
+
platform_mapping:
|
|
87
|
+
ios: { component: "VideoPlayer", framework: "AVKit" }
|
|
88
|
+
android: { component: "PlayerView", library: "androidx.media3" }
|
|
89
|
+
web: { element: "div", role: "region" }
|
|
90
|
+
|
|
91
|
+
generation:
|
|
92
|
+
must_handle: ["All slots must render with correct contract types"]
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# TaskFlow — Contract Files
|
|
2
2
|
|
|
3
3
|
These files define the 7 standard OpenUISpec contract families used by TaskFlow.
|
|
4
|
-
They are extracted from the OpenUISpec v0.
|
|
4
|
+
They are extracted from the OpenUISpec v0.2 specification (Section 4) for use as
|
|
5
5
|
standalone, machine-readable contract definitions.
|
|
6
6
|
|
|
7
7
|
For the full specification of each contract including generation hints and test cases,
|
|
8
|
-
see `spec/openuispec-v0.
|
|
8
|
+
see `spec/openuispec-v0.2.md` Section 4.
|
|
9
9
|
|
|
10
10
|
| File | Contract | Section |
|
|
11
11
|
|------|----------|---------|
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Mock data for the home screen
|
|
2
|
+
data:
|
|
3
|
+
user:
|
|
4
|
+
id: "u1"
|
|
5
|
+
name: "Alex Chen"
|
|
6
|
+
first_name: "Alex"
|
|
7
|
+
email: "alex@example.com"
|
|
8
|
+
|
|
9
|
+
tasks:
|
|
10
|
+
- id: "task-1"
|
|
11
|
+
title: "Review Q4 roadmap"
|
|
12
|
+
status: in_progress
|
|
13
|
+
priority: high
|
|
14
|
+
due_date: "2026-03-20"
|
|
15
|
+
project: { id: "p1", name: "Platform" }
|
|
16
|
+
tags: ["planning", "q4"]
|
|
17
|
+
created_at: "2026-03-10"
|
|
18
|
+
|
|
19
|
+
- id: "task-2"
|
|
20
|
+
title: "Fix login bug on mobile"
|
|
21
|
+
status: todo
|
|
22
|
+
priority: urgent
|
|
23
|
+
due_date: "2026-03-19"
|
|
24
|
+
project: { id: "p2", name: "Mobile App" }
|
|
25
|
+
tags: ["bug"]
|
|
26
|
+
created_at: "2026-03-15"
|
|
27
|
+
|
|
28
|
+
- id: "task-3"
|
|
29
|
+
title: "Write API documentation"
|
|
30
|
+
status: todo
|
|
31
|
+
priority: medium
|
|
32
|
+
due_date: "2026-03-22"
|
|
33
|
+
project: { id: "p1", name: "Platform" }
|
|
34
|
+
tags: ["docs"]
|
|
35
|
+
created_at: "2026-03-12"
|
|
36
|
+
|
|
37
|
+
- id: "task-4"
|
|
38
|
+
title: "Design onboarding flow"
|
|
39
|
+
status: done
|
|
40
|
+
priority: high
|
|
41
|
+
due_date: "2026-03-18"
|
|
42
|
+
project: { id: "p3", name: "Design System" }
|
|
43
|
+
tags: ["design", "ux"]
|
|
44
|
+
created_at: "2026-03-08"
|
|
45
|
+
|
|
46
|
+
- id: "task-5"
|
|
47
|
+
title: "Update dependencies"
|
|
48
|
+
status: todo
|
|
49
|
+
priority: low
|
|
50
|
+
due_date: "2026-03-25"
|
|
51
|
+
project: { id: "p1", name: "Platform" }
|
|
52
|
+
tags: ["maintenance"]
|
|
53
|
+
created_at: "2026-03-16"
|
|
54
|
+
|
|
55
|
+
task_counts:
|
|
56
|
+
all: 24
|
|
57
|
+
today: 3
|
|
58
|
+
upcoming: 12
|
|
59
|
+
done: 9
|
|
60
|
+
|
|
61
|
+
projects:
|
|
62
|
+
- { id: "p1", name: "Platform", color: "#5B4FE8", icon: "server", task_count: 12 }
|
|
63
|
+
- { id: "p2", name: "Mobile App", color: "#E8634F", icon: "phone", task_count: 8 }
|
|
64
|
+
- { id: "p3", name: "Design System", color: "#2D9D5E", icon: "palette", task_count: 4 }
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Mock data for the project_detail screen
|
|
2
|
+
data:
|
|
3
|
+
project:
|
|
4
|
+
id: "proj-1"
|
|
5
|
+
name: "Website Redesign"
|
|
6
|
+
icon: "folder"
|
|
7
|
+
color: "#4A90D9"
|
|
8
|
+
task_count: 5
|
|
9
|
+
|
|
10
|
+
tasks:
|
|
11
|
+
- id: "t1"
|
|
12
|
+
title: "Design homepage layout"
|
|
13
|
+
due_date: "2026-03-25T00:00:00Z"
|
|
14
|
+
priority: high
|
|
15
|
+
- id: "t2"
|
|
16
|
+
title: "Set up CI pipeline"
|
|
17
|
+
due_date: "2026-04-01T00:00:00Z"
|
|
18
|
+
priority: medium
|
|
19
|
+
- id: "t3"
|
|
20
|
+
title: "Implement auth flow"
|
|
21
|
+
due_date: "2026-03-28T00:00:00Z"
|
|
22
|
+
priority: high
|
|
23
|
+
- id: "t4"
|
|
24
|
+
title: "Write API documentation"
|
|
25
|
+
due_date: "2026-04-05T00:00:00Z"
|
|
26
|
+
priority: low
|
|
27
|
+
- id: "t5"
|
|
28
|
+
title: "Performance audit"
|
|
29
|
+
due_date: "2026-04-10T00:00:00Z"
|
|
30
|
+
priority: medium
|
|
31
|
+
|
|
32
|
+
params:
|
|
33
|
+
project_id: "proj-1"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Mock data for the task_detail screen
|
|
2
|
+
data:
|
|
3
|
+
task:
|
|
4
|
+
id: "task-1"
|
|
5
|
+
title: "Review Q4 roadmap"
|
|
6
|
+
description: "Go through the Q4 roadmap document and identify any gaps in the timeline. Focus on the platform team deliverables and cross-team dependencies."
|
|
7
|
+
status: in_progress
|
|
8
|
+
priority: high
|
|
9
|
+
due_date: "2026-03-20"
|
|
10
|
+
project_id: "p1"
|
|
11
|
+
project: { id: "p1", name: "Platform" }
|
|
12
|
+
assignee: { id: "u1", name: "Alex Chen", email: "alex@example.com" }
|
|
13
|
+
tags: ["planning", "q4"]
|
|
14
|
+
created_at: "2026-03-10"
|
|
15
|
+
updated_at: "2026-03-17"
|
|
16
|
+
|
|
17
|
+
params:
|
|
18
|
+
task_id: "task-1"
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# ============================================================
|
|
2
|
-
# TaskFlow — OpenUISpec v0.
|
|
2
|
+
# TaskFlow — OpenUISpec v0.2 Example Application
|
|
3
3
|
# ============================================================
|
|
4
4
|
# A task management app demonstrating all 7 contract families,
|
|
5
5
|
# theming, navigation flows, adaptive layout, and the formal
|
|
6
6
|
# action system and data binding model.
|
|
7
7
|
# ============================================================
|
|
8
8
|
|
|
9
|
-
spec_version: "0.
|
|
9
|
+
spec_version: "0.2"
|
|
10
10
|
|
|
11
11
|
project:
|
|
12
12
|
name: "TaskFlow"
|
|
@@ -16,13 +16,12 @@ project:
|
|
|
16
16
|
includes:
|
|
17
17
|
tokens: "./tokens/"
|
|
18
18
|
contracts: "./contracts/"
|
|
19
|
+
components: "./components/"
|
|
19
20
|
screens: "./screens/"
|
|
20
21
|
flows: "./flows/"
|
|
21
22
|
platform: "./platform/"
|
|
22
23
|
locales: "./locales/"
|
|
23
24
|
|
|
24
|
-
custom_contracts:
|
|
25
|
-
- "./contracts/x_media_player.yaml"
|
|
26
25
|
|
|
27
26
|
i18n:
|
|
28
27
|
default_locale: "en"
|
|
@@ -105,19 +105,16 @@ task_detail:
|
|
|
105
105
|
padding_h: "spacing.page_margin"
|
|
106
106
|
margin_top: "spacing.md"
|
|
107
107
|
children:
|
|
108
|
-
-
|
|
109
|
-
variant: inline
|
|
108
|
+
- component: media_player
|
|
110
109
|
props:
|
|
111
110
|
source: "{task.attachment.url}"
|
|
112
111
|
media_type: "{task.attachment.media_type}"
|
|
113
112
|
title: "{task.attachment.filename}"
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
tokens_override:
|
|
117
|
-
radius: "spacing.md"
|
|
113
|
+
slots:
|
|
114
|
+
volume_control: { hidden: true }
|
|
118
115
|
adaptive:
|
|
119
|
-
compact: {
|
|
120
|
-
expanded: {
|
|
116
|
+
compact: {}
|
|
117
|
+
expanded: { max_width: 640 }
|
|
121
118
|
|
|
122
119
|
# ---------- Details section ----------
|
|
123
120
|
- id: details
|
|
@@ -45,6 +45,22 @@ icons:
|
|
|
45
45
|
android: "undo"
|
|
46
46
|
web: "undo-2"
|
|
47
47
|
|
|
48
|
+
media:
|
|
49
|
+
play:
|
|
50
|
+
semantic: "Play media"
|
|
51
|
+
variants: ["fill"]
|
|
52
|
+
platform:
|
|
53
|
+
ios: "play"
|
|
54
|
+
android: "play_arrow"
|
|
55
|
+
web: "play"
|
|
56
|
+
pause:
|
|
57
|
+
semantic: "Pause media"
|
|
58
|
+
variants: ["fill"]
|
|
59
|
+
platform:
|
|
60
|
+
ios: "pause"
|
|
61
|
+
android: "pause"
|
|
62
|
+
web: "pause"
|
|
63
|
+
|
|
48
64
|
actions:
|
|
49
65
|
plus:
|
|
50
66
|
semantic: "Create new item"
|