openuispec 0.1.44 → 0.1.46
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 +79 -55
- package/cli/init.ts +14 -3
- package/examples/social-app/.mcp.json +10 -0
- package/examples/social-app/AGENTS.md +105 -0
- package/examples/social-app/CLAUDE.md +105 -0
- package/examples/social-app/README.md +19 -0
- package/examples/social-app/backend/.gitkeep +1 -0
- package/examples/social-app/generated/android/social-app/app/build.gradle.kts +92 -0
- package/examples/social-app/generated/android/social-app/app/src/main/AndroidManifest.xml +26 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/AppContainer.kt +20 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/MainActivity.kt +35 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/SocialAppApplication.kt +13 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/data/MockData.kt +98 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/data/preferences/AppPreferences.kt +19 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/data/preferences/DataStorePreferencesRepository.kt +68 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/data/preferences/PreferencesRepository.kt +15 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/model/Models.kt +34 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/MainShell.kt +390 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/components/Components.kt +234 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/components/ContractPrimitives.kt +641 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/navigation/RootComponent.kt +113 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/ChatDetailScreen.kt +212 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/CreatePostScreen.kt +113 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/DiscoverScreen.kt +137 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/EditProfileScreen.kt +180 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/HomeFeedScreen.kt +157 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/MessagesInboxScreen.kt +85 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/NotificationsScreen.kt +74 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/PostDetailScreen.kt +293 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/ProfileSelfScreen.kt +116 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/SearchResultsScreen.kt +161 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/SettingsScreen.kt +162 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/SettingsStore.kt +95 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/UserProfileScreen.kt +123 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Color.kt +33 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Shape.kt +41 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Spacing.kt +20 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Theme.kt +82 -0
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Type.kt +60 -0
- package/examples/social-app/generated/android/social-app/app/src/main/res/drawable/ic_launcher_foreground.xml +9 -0
- package/examples/social-app/generated/android/social-app/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/examples/social-app/generated/android/social-app/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
- package/examples/social-app/generated/android/social-app/app/src/main/res/values/strings.xml +91 -0
- package/examples/social-app/generated/android/social-app/app/src/main/res/values/themes.xml +10 -0
- package/examples/social-app/generated/android/social-app/app/src/main/res/values-ru/strings.xml +79 -0
- package/examples/social-app/generated/android/social-app/app/src/main/res/values-uz/strings.xml +79 -0
- package/examples/social-app/generated/android/social-app/app/src/main/xml/AndroidManifest.xml +23 -0
- package/examples/social-app/generated/android/social-app/build.gradle.kts +6 -0
- package/examples/social-app/generated/android/social-app/gradle/libs.versions.toml +48 -0
- package/examples/social-app/generated/android/social-app/gradle/wrapper/gradle-wrapper.properties +8 -0
- package/examples/social-app/generated/android/social-app/gradle.properties +11 -0
- package/examples/social-app/generated/android/social-app/gradlew +25 -0
- package/examples/social-app/generated/android/social-app/settings.gradle.kts +23 -0
- package/examples/social-app/generated/web/social-app/index.html +12 -0
- package/examples/social-app/generated/web/social-app/package-lock.json +2517 -0
- package/examples/social-app/generated/web/social-app/package.json +27 -0
- package/examples/social-app/generated/web/social-app/src/app/App.tsx +58 -0
- package/examples/social-app/generated/web/social-app/src/components/Shell.tsx +247 -0
- package/examples/social-app/generated/web/social-app/src/components/cards.tsx +317 -0
- package/examples/social-app/generated/web/social-app/src/components/ui.tsx +328 -0
- package/examples/social-app/generated/web/social-app/src/flows/CreatePostFlow.tsx +86 -0
- package/examples/social-app/generated/web/social-app/src/i18n.tsx +59 -0
- package/examples/social-app/generated/web/social-app/src/lib/icons.tsx +85 -0
- package/examples/social-app/generated/web/social-app/src/lib/tokens.ts +70 -0
- package/examples/social-app/generated/web/social-app/src/lib/utils.ts +97 -0
- package/examples/social-app/generated/web/social-app/src/locales/en.json +67 -0
- package/examples/social-app/generated/web/social-app/src/locales/ru.json +67 -0
- package/examples/social-app/generated/web/social-app/src/locales/uz.json +67 -0
- package/examples/social-app/generated/web/social-app/src/main.tsx +16 -0
- package/examples/social-app/generated/web/social-app/src/screens/ChatDetailScreen.tsx +90 -0
- package/examples/social-app/generated/web/social-app/src/screens/DiscoverScreen.tsx +86 -0
- package/examples/social-app/generated/web/social-app/src/screens/EditProfileScreen.tsx +57 -0
- package/examples/social-app/generated/web/social-app/src/screens/HomeFeedScreen.tsx +113 -0
- package/examples/social-app/generated/web/social-app/src/screens/MessagesInboxScreen.tsx +52 -0
- package/examples/social-app/generated/web/social-app/src/screens/NotificationsScreen.tsx +41 -0
- package/examples/social-app/generated/web/social-app/src/screens/PostDetailScreen.tsx +115 -0
- package/examples/social-app/generated/web/social-app/src/screens/ProfileSelfScreen.tsx +57 -0
- package/examples/social-app/generated/web/social-app/src/screens/ProfileUserScreen.tsx +76 -0
- package/examples/social-app/generated/web/social-app/src/screens/SearchResultsScreen.tsx +96 -0
- package/examples/social-app/generated/web/social-app/src/screens/SettingsScreen.tsx +77 -0
- package/examples/social-app/generated/web/social-app/src/state/store.ts +592 -0
- package/examples/social-app/generated/web/social-app/src/styles.css +124 -0
- package/examples/social-app/generated/web/social-app/src/vite-env.d.ts +1 -0
- package/examples/social-app/generated/web/social-app/tsconfig.json +22 -0
- package/examples/social-app/generated/web/social-app/tsconfig.node.json +13 -0
- package/examples/social-app/generated/web/social-app/tsconfig.node.tsbuildinfo +1 -0
- package/examples/social-app/generated/web/social-app/tsconfig.tsbuildinfo +1 -0
- package/examples/social-app/generated/web/social-app/vite.config.d.ts +2 -0
- package/examples/social-app/generated/web/social-app/vite.config.js +6 -0
- package/examples/social-app/generated/web/social-app/vite.config.ts +7 -0
- package/examples/social-app/openuispec/README.md +56 -0
- package/examples/social-app/openuispec/contracts/.gitkeep +0 -0
- package/examples/social-app/openuispec/contracts/action_trigger.yaml +73 -0
- package/examples/social-app/openuispec/contracts/collection.yaml +43 -0
- package/examples/social-app/openuispec/contracts/data_display.yaml +47 -0
- package/examples/social-app/openuispec/contracts/feedback.yaml +49 -0
- package/examples/social-app/openuispec/contracts/input_field.yaml +41 -0
- package/examples/social-app/openuispec/contracts/nav_container.yaml +34 -0
- package/examples/social-app/openuispec/contracts/surface.yaml +41 -0
- package/examples/social-app/openuispec/flows/.gitkeep +0 -0
- package/examples/social-app/openuispec/flows/create_post.yaml +66 -0
- package/examples/social-app/openuispec/locales/.gitkeep +0 -0
- package/examples/social-app/openuispec/locales/en.json +67 -0
- package/examples/social-app/openuispec/locales/ru.json +67 -0
- package/examples/social-app/openuispec/locales/uz.json +67 -0
- package/examples/social-app/openuispec/openuispec.yaml +214 -0
- package/examples/social-app/openuispec/platform/.gitkeep +0 -0
- package/examples/social-app/openuispec/platform/android.yaml +30 -0
- package/examples/social-app/openuispec/platform/ios.yaml +19 -0
- package/examples/social-app/openuispec/platform/web.yaml +23 -0
- package/examples/social-app/openuispec/screens/.gitkeep +0 -0
- package/examples/social-app/openuispec/screens/chat_detail.yaml +53 -0
- package/examples/social-app/openuispec/screens/discover.yaml +78 -0
- package/examples/social-app/openuispec/screens/edit_profile.yaml +78 -0
- package/examples/social-app/openuispec/screens/home_feed.yaml +123 -0
- package/examples/social-app/openuispec/screens/messages_inbox.yaml +43 -0
- package/examples/social-app/openuispec/screens/notifications.yaml +29 -0
- package/examples/social-app/openuispec/screens/post_detail.yaml +86 -0
- package/examples/social-app/openuispec/screens/profile_self.yaml +53 -0
- package/examples/social-app/openuispec/screens/profile_user.yaml +60 -0
- package/examples/social-app/openuispec/screens/search_results.yaml +62 -0
- package/examples/social-app/openuispec/screens/settings.yaml +94 -0
- package/examples/social-app/openuispec/tokens/.gitkeep +0 -0
- package/examples/social-app/openuispec/tokens/color.yaml +76 -0
- package/examples/social-app/openuispec/tokens/elevation.yaml +31 -0
- package/examples/social-app/openuispec/tokens/icons.yaml +147 -0
- package/examples/social-app/openuispec/tokens/layout.yaml +37 -0
- package/examples/social-app/openuispec/tokens/motion.yaml +28 -0
- package/examples/social-app/openuispec/tokens/spacing.yaml +19 -0
- package/examples/social-app/openuispec/tokens/themes.yaml +31 -0
- package/examples/social-app/openuispec/tokens/typography.yaml +50 -0
- package/examples/social-app/package.json +12 -0
- package/mcp-server/index.ts +69 -0
- package/package.json +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
settings:
|
|
2
|
+
semantic: "App settings for theme, notifications, privacy, and account preferences"
|
|
3
|
+
status: draft
|
|
4
|
+
|
|
5
|
+
data:
|
|
6
|
+
preferences:
|
|
7
|
+
source: "api.preferences.get"
|
|
8
|
+
|
|
9
|
+
layout:
|
|
10
|
+
type: scroll_vertical
|
|
11
|
+
sections:
|
|
12
|
+
- id: appearance
|
|
13
|
+
header: "$t:settings.appearance"
|
|
14
|
+
children:
|
|
15
|
+
- contract: input_field
|
|
16
|
+
input_type: select
|
|
17
|
+
props:
|
|
18
|
+
label: "$t:settings.theme"
|
|
19
|
+
value: "{preferences.theme}"
|
|
20
|
+
options:
|
|
21
|
+
- { value: "system", label: "$t:settings.theme_system" }
|
|
22
|
+
- { value: "light", label: "$t:settings.theme_light" }
|
|
23
|
+
- { value: "dark", label: "$t:settings.theme_dark" }
|
|
24
|
+
action:
|
|
25
|
+
type: api_call
|
|
26
|
+
endpoint: "api.preferences.update"
|
|
27
|
+
body: { key: "theme", value: "{selected}" }
|
|
28
|
+
|
|
29
|
+
- id: notifications_section
|
|
30
|
+
header: "$t:settings.notifications"
|
|
31
|
+
children:
|
|
32
|
+
- contract: input_field
|
|
33
|
+
input_type: toggle
|
|
34
|
+
props:
|
|
35
|
+
label: "$t:settings.push_notifications"
|
|
36
|
+
value: "{preferences.push_notifications}"
|
|
37
|
+
action:
|
|
38
|
+
type: api_call
|
|
39
|
+
endpoint: "api.preferences.update"
|
|
40
|
+
body: { key: "push_notifications", value: "{toggled}" }
|
|
41
|
+
|
|
42
|
+
- contract: input_field
|
|
43
|
+
input_type: toggle
|
|
44
|
+
props:
|
|
45
|
+
label: "$t:settings.message_previews"
|
|
46
|
+
value: "{preferences.message_previews}"
|
|
47
|
+
action:
|
|
48
|
+
type: api_call
|
|
49
|
+
endpoint: "api.preferences.update"
|
|
50
|
+
body: { key: "message_previews", value: "{toggled}" }
|
|
51
|
+
|
|
52
|
+
- id: language
|
|
53
|
+
header: "$t:settings.language"
|
|
54
|
+
children:
|
|
55
|
+
- contract: input_field
|
|
56
|
+
input_type: toggle
|
|
57
|
+
props:
|
|
58
|
+
label: "$t:settings.auto_translate"
|
|
59
|
+
value: "{preferences.auto_translate}"
|
|
60
|
+
action:
|
|
61
|
+
type: api_call
|
|
62
|
+
endpoint: "api.preferences.update"
|
|
63
|
+
body: { key: "auto_translate", value: "{toggled}" }
|
|
64
|
+
|
|
65
|
+
- id: account
|
|
66
|
+
header: "$t:settings.account"
|
|
67
|
+
children:
|
|
68
|
+
- contract: action_trigger
|
|
69
|
+
variant: secondary
|
|
70
|
+
props:
|
|
71
|
+
label: "$t:settings.edit_profile"
|
|
72
|
+
icon: "edit"
|
|
73
|
+
action:
|
|
74
|
+
type: navigate
|
|
75
|
+
destination: "screens/edit_profile"
|
|
76
|
+
|
|
77
|
+
- contract: action_trigger
|
|
78
|
+
variant: destructive
|
|
79
|
+
props:
|
|
80
|
+
label: "$t:settings.logout"
|
|
81
|
+
action:
|
|
82
|
+
type: confirm
|
|
83
|
+
confirmation:
|
|
84
|
+
contract: feedback
|
|
85
|
+
variant: dialog
|
|
86
|
+
props:
|
|
87
|
+
title: "$t:settings.logout"
|
|
88
|
+
message: "$t:settings.logout_confirm"
|
|
89
|
+
actions:
|
|
90
|
+
- label: "$t:common.cancel"
|
|
91
|
+
action: { type: dismiss }
|
|
92
|
+
- label: "$t:settings.logout"
|
|
93
|
+
variant: destructive
|
|
94
|
+
action: { type: dismiss }
|
|
File without changes
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
color:
|
|
2
|
+
brand:
|
|
3
|
+
primary:
|
|
4
|
+
semantic: "Main brand identity — warm ink tone"
|
|
5
|
+
reference: "#1C1B1A"
|
|
6
|
+
range:
|
|
7
|
+
hue: [30, 40]
|
|
8
|
+
saturation: [5, 15]
|
|
9
|
+
lightness: [8, 14]
|
|
10
|
+
on_color:
|
|
11
|
+
reference: "#FFFFFF"
|
|
12
|
+
contrast_min: 7.0
|
|
13
|
+
accent:
|
|
14
|
+
semantic: "Accent highlights — muted indigo"
|
|
15
|
+
reference: "#5B52A3"
|
|
16
|
+
range:
|
|
17
|
+
hue: [250, 260]
|
|
18
|
+
saturation: [30, 45]
|
|
19
|
+
lightness: [45, 55]
|
|
20
|
+
on_color:
|
|
21
|
+
reference: "#FFFFFF"
|
|
22
|
+
contrast_min: 4.5
|
|
23
|
+
|
|
24
|
+
surface:
|
|
25
|
+
primary:
|
|
26
|
+
semantic: "Main content background — warm off-white"
|
|
27
|
+
reference: "#FAF8F5"
|
|
28
|
+
secondary:
|
|
29
|
+
semantic: "Card and grouped backgrounds — warm cream"
|
|
30
|
+
reference: "#F3F0EB"
|
|
31
|
+
tertiary:
|
|
32
|
+
semantic: "Elevated surfaces — soft beige"
|
|
33
|
+
reference: "#EBE7E0"
|
|
34
|
+
|
|
35
|
+
text:
|
|
36
|
+
primary:
|
|
37
|
+
semantic: "Headings, body text"
|
|
38
|
+
reference: "#1C1B1A"
|
|
39
|
+
contrast_min: 7.0
|
|
40
|
+
secondary:
|
|
41
|
+
semantic: "Supporting text, captions"
|
|
42
|
+
reference: "#6B6966"
|
|
43
|
+
contrast_min: 4.5
|
|
44
|
+
tertiary:
|
|
45
|
+
semantic: "Placeholder text, disabled labels"
|
|
46
|
+
reference: "#9E9A95"
|
|
47
|
+
|
|
48
|
+
semantic:
|
|
49
|
+
success:
|
|
50
|
+
reference: "#2D9D5E"
|
|
51
|
+
on_color:
|
|
52
|
+
reference: "#FFFFFF"
|
|
53
|
+
contrast_min: 4.5
|
|
54
|
+
warning:
|
|
55
|
+
reference: "#D4920E"
|
|
56
|
+
on_color:
|
|
57
|
+
reference: "#1C1B1A"
|
|
58
|
+
contrast_min: 4.5
|
|
59
|
+
danger:
|
|
60
|
+
reference: "#D43B3B"
|
|
61
|
+
on_color:
|
|
62
|
+
reference: "#FFFFFF"
|
|
63
|
+
contrast_min: 4.5
|
|
64
|
+
info:
|
|
65
|
+
reference: "#3B82D4"
|
|
66
|
+
on_color:
|
|
67
|
+
reference: "#FFFFFF"
|
|
68
|
+
contrast_min: 4.5
|
|
69
|
+
|
|
70
|
+
border:
|
|
71
|
+
default:
|
|
72
|
+
semantic: "Default borders and dividers"
|
|
73
|
+
reference: "#E0DCD6"
|
|
74
|
+
strong:
|
|
75
|
+
semantic: "Emphasized borders"
|
|
76
|
+
reference: "#C5C0B8"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
elevation:
|
|
2
|
+
sm:
|
|
3
|
+
semantic: "Cards, subtle lift"
|
|
4
|
+
value: "sm"
|
|
5
|
+
platform:
|
|
6
|
+
ios:
|
|
7
|
+
shadow: { color: "#1C1B1A", opacity: 0.08, radius: 3, x: 0, y: 1 }
|
|
8
|
+
android:
|
|
9
|
+
elevation: 2
|
|
10
|
+
web:
|
|
11
|
+
box_shadow: "0 1px 3px rgba(28,27,26,0.08)"
|
|
12
|
+
md:
|
|
13
|
+
semantic: "Floating elements, dropdowns"
|
|
14
|
+
value: "md"
|
|
15
|
+
platform:
|
|
16
|
+
ios:
|
|
17
|
+
shadow: { color: "#1C1B1A", opacity: 0.12, radius: 12, x: 0, y: 4 }
|
|
18
|
+
android:
|
|
19
|
+
elevation: 6
|
|
20
|
+
web:
|
|
21
|
+
box_shadow: "0 4px 12px rgba(28,27,26,0.12)"
|
|
22
|
+
lg:
|
|
23
|
+
semantic: "Modals, sheets"
|
|
24
|
+
value: "lg"
|
|
25
|
+
platform:
|
|
26
|
+
ios:
|
|
27
|
+
shadow: { color: "#1C1B1A", opacity: 0.16, radius: 24, x: 0, y: 8 }
|
|
28
|
+
android:
|
|
29
|
+
elevation: 12
|
|
30
|
+
web:
|
|
31
|
+
box_shadow: "0 8px 24px rgba(28,27,26,0.16)"
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
icons:
|
|
2
|
+
sizes:
|
|
3
|
+
sm:
|
|
4
|
+
semantic: "Small icons — tab bar, inline"
|
|
5
|
+
value: 20
|
|
6
|
+
md:
|
|
7
|
+
semantic: "Default icon size"
|
|
8
|
+
value: 24
|
|
9
|
+
lg:
|
|
10
|
+
semantic: "Large icons — hero, empty state"
|
|
11
|
+
value: 32
|
|
12
|
+
|
|
13
|
+
variants:
|
|
14
|
+
default: "outline"
|
|
15
|
+
suffixes:
|
|
16
|
+
_fill: "filled"
|
|
17
|
+
|
|
18
|
+
fallback:
|
|
19
|
+
strategy: "name_passthrough"
|
|
20
|
+
missing_icon: "questionmark.circle"
|
|
21
|
+
|
|
22
|
+
registry:
|
|
23
|
+
navigation:
|
|
24
|
+
home:
|
|
25
|
+
semantic: "Home feed tab"
|
|
26
|
+
platform:
|
|
27
|
+
ios: "house"
|
|
28
|
+
android: "home"
|
|
29
|
+
web: "home"
|
|
30
|
+
discover:
|
|
31
|
+
semantic: "Discover tab"
|
|
32
|
+
platform:
|
|
33
|
+
ios: "compass"
|
|
34
|
+
android: "explore"
|
|
35
|
+
web: "explore"
|
|
36
|
+
notifications:
|
|
37
|
+
semantic: "Notifications tab"
|
|
38
|
+
platform:
|
|
39
|
+
ios: "bell"
|
|
40
|
+
android: "notifications"
|
|
41
|
+
web: "notifications"
|
|
42
|
+
messages:
|
|
43
|
+
semantic: "Messages tab"
|
|
44
|
+
platform:
|
|
45
|
+
ios: "message"
|
|
46
|
+
android: "chat"
|
|
47
|
+
web: "chat"
|
|
48
|
+
profile:
|
|
49
|
+
semantic: "Profile tab"
|
|
50
|
+
platform:
|
|
51
|
+
ios: "person.circle"
|
|
52
|
+
android: "account_circle"
|
|
53
|
+
web: "account_circle"
|
|
54
|
+
actions:
|
|
55
|
+
search:
|
|
56
|
+
semantic: "Search action"
|
|
57
|
+
platform:
|
|
58
|
+
ios: "magnifyingglass"
|
|
59
|
+
android: "search"
|
|
60
|
+
web: "search"
|
|
61
|
+
create_post:
|
|
62
|
+
semantic: "Create new post"
|
|
63
|
+
platform:
|
|
64
|
+
ios: "plus.circle.fill"
|
|
65
|
+
android: "add_circle"
|
|
66
|
+
web: "add_circle"
|
|
67
|
+
like:
|
|
68
|
+
semantic: "Like action"
|
|
69
|
+
variants: [_fill]
|
|
70
|
+
platform:
|
|
71
|
+
ios: "heart"
|
|
72
|
+
android: "favorite_border"
|
|
73
|
+
web: "favorite_border"
|
|
74
|
+
comment:
|
|
75
|
+
semantic: "Comment action"
|
|
76
|
+
platform:
|
|
77
|
+
ios: "bubble.right"
|
|
78
|
+
android: "chat_bubble_outline"
|
|
79
|
+
web: "chat_bubble_outline"
|
|
80
|
+
share:
|
|
81
|
+
semantic: "Share action"
|
|
82
|
+
platform:
|
|
83
|
+
ios: "square.and.arrow.up"
|
|
84
|
+
android: "share"
|
|
85
|
+
web: "share"
|
|
86
|
+
bookmark:
|
|
87
|
+
semantic: "Save/bookmark"
|
|
88
|
+
variants: [_fill]
|
|
89
|
+
platform:
|
|
90
|
+
ios: "bookmark"
|
|
91
|
+
android: "bookmark_border"
|
|
92
|
+
web: "bookmark_border"
|
|
93
|
+
more:
|
|
94
|
+
semantic: "More options"
|
|
95
|
+
platform:
|
|
96
|
+
ios: "ellipsis"
|
|
97
|
+
android: "more_vert"
|
|
98
|
+
web: "more_vert"
|
|
99
|
+
send:
|
|
100
|
+
semantic: "Send message"
|
|
101
|
+
platform:
|
|
102
|
+
ios: "paperplane.fill"
|
|
103
|
+
android: "send"
|
|
104
|
+
web: "send"
|
|
105
|
+
camera:
|
|
106
|
+
semantic: "Camera/photo"
|
|
107
|
+
platform:
|
|
108
|
+
ios: "camera"
|
|
109
|
+
android: "photo_camera"
|
|
110
|
+
web: "photo_camera"
|
|
111
|
+
image:
|
|
112
|
+
semantic: "Image attachment"
|
|
113
|
+
platform:
|
|
114
|
+
ios: "photo"
|
|
115
|
+
android: "image"
|
|
116
|
+
web: "image"
|
|
117
|
+
edit:
|
|
118
|
+
semantic: "Edit action"
|
|
119
|
+
platform:
|
|
120
|
+
ios: "pencil"
|
|
121
|
+
android: "edit"
|
|
122
|
+
web: "edit"
|
|
123
|
+
check:
|
|
124
|
+
semantic: "Confirm/done"
|
|
125
|
+
platform:
|
|
126
|
+
ios: "checkmark"
|
|
127
|
+
android: "check"
|
|
128
|
+
web: "check"
|
|
129
|
+
chrome:
|
|
130
|
+
back:
|
|
131
|
+
semantic: "Navigate back"
|
|
132
|
+
platform:
|
|
133
|
+
ios: "chevron.left"
|
|
134
|
+
android: "arrow_back"
|
|
135
|
+
web: "arrow_back"
|
|
136
|
+
close:
|
|
137
|
+
semantic: "Close/dismiss"
|
|
138
|
+
platform:
|
|
139
|
+
ios: "xmark"
|
|
140
|
+
android: "close"
|
|
141
|
+
web: "close"
|
|
142
|
+
settings:
|
|
143
|
+
semantic: "Settings"
|
|
144
|
+
platform:
|
|
145
|
+
ios: "gearshape"
|
|
146
|
+
android: "settings"
|
|
147
|
+
web: "settings"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
layout:
|
|
2
|
+
size_classes:
|
|
3
|
+
compact:
|
|
4
|
+
semantic: "Phones in portrait"
|
|
5
|
+
width:
|
|
6
|
+
max: 600
|
|
7
|
+
columns: 4
|
|
8
|
+
margin: "md"
|
|
9
|
+
regular:
|
|
10
|
+
semantic: "Tablets, phones in landscape"
|
|
11
|
+
width:
|
|
12
|
+
min: 601
|
|
13
|
+
max: 1024
|
|
14
|
+
columns: 8
|
|
15
|
+
margin: "lg"
|
|
16
|
+
expanded:
|
|
17
|
+
semantic: "Desktops, large tablets"
|
|
18
|
+
width:
|
|
19
|
+
min: 1025
|
|
20
|
+
columns: 12
|
|
21
|
+
margin: "xl"
|
|
22
|
+
|
|
23
|
+
platform_mapping:
|
|
24
|
+
ios:
|
|
25
|
+
uses: "UITraitCollection"
|
|
26
|
+
compact: "compact"
|
|
27
|
+
regular: "regular"
|
|
28
|
+
android:
|
|
29
|
+
uses: "WindowSizeClass"
|
|
30
|
+
compact: "Compact"
|
|
31
|
+
regular: "Medium"
|
|
32
|
+
expanded: "Expanded"
|
|
33
|
+
web:
|
|
34
|
+
uses: "media-query"
|
|
35
|
+
compact: "max-width: 600px"
|
|
36
|
+
regular: "min-width: 601px and max-width: 1024px"
|
|
37
|
+
expanded: "min-width: 1025px"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
motion:
|
|
2
|
+
duration:
|
|
3
|
+
instant: 100
|
|
4
|
+
quick: 200
|
|
5
|
+
normal: 300
|
|
6
|
+
slow: 500
|
|
7
|
+
|
|
8
|
+
easing:
|
|
9
|
+
default: "ease-out"
|
|
10
|
+
enter: "ease-out"
|
|
11
|
+
exit: "ease-in"
|
|
12
|
+
emphasis: "cubic-bezier(0.2, 0, 0, 1)"
|
|
13
|
+
|
|
14
|
+
reduced_motion: "respect-system"
|
|
15
|
+
|
|
16
|
+
patterns:
|
|
17
|
+
press_feedback:
|
|
18
|
+
duration: "instant"
|
|
19
|
+
easing: "default"
|
|
20
|
+
property: "transform"
|
|
21
|
+
slide_up:
|
|
22
|
+
duration: "normal"
|
|
23
|
+
easing: "enter"
|
|
24
|
+
property: "transform"
|
|
25
|
+
fade:
|
|
26
|
+
duration: "quick"
|
|
27
|
+
easing: "default"
|
|
28
|
+
property: "opacity"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
spacing:
|
|
2
|
+
base_unit: 4
|
|
3
|
+
platform_flex: 0.15
|
|
4
|
+
|
|
5
|
+
scale:
|
|
6
|
+
none: 0
|
|
7
|
+
xxs: 2
|
|
8
|
+
xs: 4
|
|
9
|
+
sm: 8
|
|
10
|
+
md: { base: 16, range: [12, 16] }
|
|
11
|
+
lg: { base: 24, range: [20, 24] }
|
|
12
|
+
xl: 32
|
|
13
|
+
xxl: 48
|
|
14
|
+
|
|
15
|
+
aliases:
|
|
16
|
+
page_margin: { horizontal: md, vertical: md }
|
|
17
|
+
card_padding: { all: md }
|
|
18
|
+
section_gap: lg
|
|
19
|
+
list_item_gap: sm
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
themes:
|
|
2
|
+
default: "light"
|
|
3
|
+
|
|
4
|
+
variants:
|
|
5
|
+
light:
|
|
6
|
+
color.surface.primary: { lightness: 98 }
|
|
7
|
+
color.surface.secondary: { lightness: 95 }
|
|
8
|
+
color.surface.tertiary: { lightness: 91 }
|
|
9
|
+
color.text.primary: { lightness: 10 }
|
|
10
|
+
color.text.secondary: { lightness: 42 }
|
|
11
|
+
color.text.tertiary: { lightness: 62 }
|
|
12
|
+
|
|
13
|
+
dark:
|
|
14
|
+
extends: "light"
|
|
15
|
+
color.surface.primary: { lightness: 10 }
|
|
16
|
+
color.surface.secondary: { lightness: 15 }
|
|
17
|
+
color.surface.tertiary: { lightness: 21 }
|
|
18
|
+
color.text.primary: { lightness: 98 }
|
|
19
|
+
color.text.secondary: { lightness: 65 }
|
|
20
|
+
color.text.tertiary: { lightness: 42 }
|
|
21
|
+
|
|
22
|
+
platform:
|
|
23
|
+
ios:
|
|
24
|
+
supports_dynamic: true
|
|
25
|
+
system_materials: true
|
|
26
|
+
android:
|
|
27
|
+
material_you: false
|
|
28
|
+
dynamic_color: false
|
|
29
|
+
web:
|
|
30
|
+
prefers_color_scheme: true
|
|
31
|
+
css_custom_properties: true
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
typography:
|
|
2
|
+
font_family:
|
|
3
|
+
primary:
|
|
4
|
+
semantic: "All UI text"
|
|
5
|
+
value: "DM Sans"
|
|
6
|
+
platform:
|
|
7
|
+
ios: { system_alternative: "SF Pro" }
|
|
8
|
+
android: { system_alternative: "Google Sans" }
|
|
9
|
+
|
|
10
|
+
scale:
|
|
11
|
+
display:
|
|
12
|
+
semantic: "Hero text, onboarding"
|
|
13
|
+
size: { base: 32, range: [28, 36] }
|
|
14
|
+
weight: 700
|
|
15
|
+
line_height: 1.2
|
|
16
|
+
heading_lg:
|
|
17
|
+
semantic: "Screen titles"
|
|
18
|
+
size: { base: 24, range: [22, 26] }
|
|
19
|
+
weight: 600
|
|
20
|
+
line_height: 1.3
|
|
21
|
+
heading_md:
|
|
22
|
+
semantic: "Section titles"
|
|
23
|
+
size: { base: 20, range: [18, 22] }
|
|
24
|
+
weight: 600
|
|
25
|
+
line_height: 1.3
|
|
26
|
+
heading_sm:
|
|
27
|
+
semantic: "Card titles, list headings"
|
|
28
|
+
size: { base: 16, range: [15, 17] }
|
|
29
|
+
weight: 600
|
|
30
|
+
line_height: 1.4
|
|
31
|
+
body:
|
|
32
|
+
semantic: "Primary readable text"
|
|
33
|
+
size: { base: 16, range: [14, 16] }
|
|
34
|
+
weight: 400
|
|
35
|
+
line_height: 1.5
|
|
36
|
+
body_sm:
|
|
37
|
+
semantic: "Secondary body text"
|
|
38
|
+
size: { base: 14, range: [13, 15] }
|
|
39
|
+
weight: 400
|
|
40
|
+
line_height: 1.5
|
|
41
|
+
caption:
|
|
42
|
+
semantic: "Labels, timestamps, metadata"
|
|
43
|
+
size: { base: 12, range: [11, 13] }
|
|
44
|
+
weight: 400
|
|
45
|
+
line_height: 1.4
|
|
46
|
+
button:
|
|
47
|
+
semantic: "Button labels"
|
|
48
|
+
size: { base: 16, range: [14, 16] }
|
|
49
|
+
weight: 600
|
|
50
|
+
line_height: 1.0
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "social-app",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"description": "OpenUISpec test project wired to the local ../openuispec checkout",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"openuispec": "node --import ./../openuispec/node_modules/tsx/dist/loader.mjs ./../openuispec/cli/index.ts",
|
|
8
|
+
"validate": "node --import ./../openuispec/node_modules/tsx/dist/loader.mjs ./../openuispec/cli/index.ts validate",
|
|
9
|
+
"validate:semantic": "node --import ./../openuispec/node_modules/tsx/dist/loader.mjs ./../openuispec/cli/index.ts validate semantic",
|
|
10
|
+
"status": "node --import ./../openuispec/node_modules/tsx/dist/loader.mjs ./../openuispec/cli/index.ts status"
|
|
11
|
+
}
|
|
12
|
+
}
|
package/mcp-server/index.ts
CHANGED
|
@@ -91,6 +91,12 @@ POST-GENERATION (do this EVERY TIME after writing UI code):
|
|
|
91
91
|
- Navigation targets match flow definitions
|
|
92
92
|
Report any real gaps found and fix them before finishing.
|
|
93
93
|
|
|
94
|
+
CREATING NEW SPEC FILES:
|
|
95
|
+
When you need to create or edit spec files and are unsure of the format:
|
|
96
|
+
1. Call openuispec_spec_types to discover available spec types.
|
|
97
|
+
2. Call openuispec_spec_schema with the specific type to get the full JSON schema.
|
|
98
|
+
3. Write the spec file following the schema exactly.
|
|
99
|
+
|
|
94
100
|
Skip these tools ONLY when the request is purely non-UI (API logic, database, infrastructure, etc.)
|
|
95
101
|
or explicitly platform-specific polish that doesn't affect shared UI semantics.`,
|
|
96
102
|
}
|
|
@@ -363,6 +369,69 @@ server.registerTool(
|
|
|
363
369
|
}
|
|
364
370
|
);
|
|
365
371
|
|
|
372
|
+
// ── schema type catalog ─────────────────────────────────────────
|
|
373
|
+
|
|
374
|
+
const SCHEMA_CATALOG: Record<string, { file: string; title: string; description: string }> = {
|
|
375
|
+
manifest: { file: "openuispec.schema.json", title: "Root Manifest", description: "Root manifest (openuispec.yaml): project info, includes, generation targets, data model, API endpoints, formatters, mappers" },
|
|
376
|
+
screen: { file: "screen.schema.json", title: "Screen", description: "Screen composition: layout, sections, navigation, surfaces, data/state bindings, adaptive breakpoints" },
|
|
377
|
+
flow: { file: "flow.schema.json", title: "Flow", description: "Navigation flow definitions: steps, transitions, guards, and entry points" },
|
|
378
|
+
platform: { file: "platform.schema.json", title: "Platform", description: "Platform-specific generation config: architecture, naming, CSS framework, component mapping" },
|
|
379
|
+
contract: { file: "contract.schema.json", title: "Contract", description: "Built-in UI contract definitions: variants, props, must_handle states, generation hints" },
|
|
380
|
+
"custom-contract":{ file: "custom-contract.schema.json", title: "Custom Contract", description: "User-defined UI contract definitions (x_ prefixed)" },
|
|
381
|
+
locale: { file: "locale.schema.json", title: "Locale", description: "Locale translation files: flat key-value string maps" },
|
|
382
|
+
"tokens/color": { file: "tokens/color.schema.json", title: "Color Tokens", description: "Color tokens: brand, surface, text, semantic, border groups with HSL ranges and contrast" },
|
|
383
|
+
"tokens/typography": { file: "tokens/typography.schema.json", title: "Typography Tokens", description: "Typography tokens: font families, sizes, weights, line heights, letter spacing" },
|
|
384
|
+
"tokens/spacing": { file: "tokens/spacing.schema.json", title: "Spacing Tokens", description: "Spacing tokens: named spacing scale values" },
|
|
385
|
+
"tokens/elevation": { file: "tokens/elevation.schema.json", title: "Elevation Tokens", description: "Elevation tokens: shadow definitions per level" },
|
|
386
|
+
"tokens/motion": { file: "tokens/motion.schema.json", title: "Motion Tokens", description: "Motion tokens: animation duration and easing curves" },
|
|
387
|
+
"tokens/layout": { file: "tokens/layout.schema.json", title: "Layout Tokens", description: "Layout tokens: radii, breakpoints, max widths, grid columns" },
|
|
388
|
+
"tokens/themes": { file: "tokens/themes.schema.json", title: "Theme Tokens", description: "Theme definitions: token overrides per theme (e.g. dark mode)" },
|
|
389
|
+
"tokens/icons": { file: "tokens/icons.schema.json", title: "Icon Tokens", description: "Icon tokens: icon set, size scale, default size" },
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
// ── tool: openuispec_spec_types ──────────────────────────────────
|
|
393
|
+
|
|
394
|
+
server.registerTool(
|
|
395
|
+
"openuispec_spec_types",
|
|
396
|
+
{
|
|
397
|
+
description: "List all available OpenUISpec spec types with brief descriptions. Use this to discover what kinds of spec files can be created and what schema format each one follows. Call openuispec_spec_schema with a specific type to get the full JSON schema.",
|
|
398
|
+
},
|
|
399
|
+
async () => {
|
|
400
|
+
const types = Object.entries(SCHEMA_CATALOG).map(([type, info]) => ({
|
|
401
|
+
type,
|
|
402
|
+
title: info.title,
|
|
403
|
+
description: info.description,
|
|
404
|
+
}));
|
|
405
|
+
return toolResult(types);
|
|
406
|
+
}
|
|
407
|
+
);
|
|
408
|
+
|
|
409
|
+
// ── tool: openuispec_spec_schema ─────────────────────────────────
|
|
410
|
+
|
|
411
|
+
server.registerTool(
|
|
412
|
+
"openuispec_spec_schema",
|
|
413
|
+
{
|
|
414
|
+
description: "Get the full JSON schema for a specific OpenUISpec spec type. Returns the complete schema definition so you know the exact format when creating or editing spec files. Call openuispec_spec_types first to see available types.",
|
|
415
|
+
inputSchema: {
|
|
416
|
+
type: z.string().describe("Spec type to get schema for (e.g. 'screen', 'tokens/color', 'contract'). Use openuispec_spec_types to list all available types."),
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
async ({ type }) => {
|
|
420
|
+
const entry = SCHEMA_CATALOG[type];
|
|
421
|
+
if (!entry) {
|
|
422
|
+
return toolError(`Unknown spec type "${type}". Call openuispec_spec_types to see available types.`);
|
|
423
|
+
}
|
|
424
|
+
try {
|
|
425
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
426
|
+
const schemaPath = join(__dirname, "..", "schema", entry.file);
|
|
427
|
+
const schema = JSON.parse(readFileSync(schemaPath, "utf-8"));
|
|
428
|
+
return toolResult({ type, title: entry.title, schema });
|
|
429
|
+
} catch (err) {
|
|
430
|
+
return toolError(err);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
);
|
|
434
|
+
|
|
366
435
|
// ── start server ─────────────────────────────────────────────────────
|
|
367
436
|
|
|
368
437
|
export async function startMcpServer() {
|