openuispec 0.2.10 → 0.2.11

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.
Files changed (231) hide show
  1. package/README.md +3 -1
  2. package/cli/index.ts +4 -2
  3. package/cli/init.ts +23 -8
  4. package/docs/cli.md +13 -8
  5. package/drift/index.ts +41 -15
  6. package/mcp-server/index.ts +155 -116
  7. package/mcp-server/screenshot.ts +19 -4
  8. package/package.json +5 -2
  9. package/prepare/index.ts +16 -0
  10. package/scripts/take-all-screenshots.ts +507 -0
  11. package/status/index.ts +2 -2
  12. package/examples/social-app/.mcp.json +0 -10
  13. package/examples/social-app/AGENTS.md +0 -124
  14. package/examples/social-app/CLAUDE.md +0 -124
  15. package/examples/social-app/backend/.gitkeep +0 -1
  16. package/examples/social-app/generated/android/social-app/app/.paparazzi-hashes.json +0 -3
  17. package/examples/social-app/generated/android/social-app/app/build.gradle.kts +0 -94
  18. package/examples/social-app/generated/android/social-app/app/src/main/AndroidManifest.xml +0 -26
  19. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/AppContainer.kt +0 -20
  20. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/MainActivity.kt +0 -35
  21. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/SocialAppApplication.kt +0 -13
  22. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/data/MockData.kt +0 -98
  23. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/data/preferences/AppPreferences.kt +0 -19
  24. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/data/preferences/DataStorePreferencesRepository.kt +0 -68
  25. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/data/preferences/PreferencesRepository.kt +0 -15
  26. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/model/Models.kt +0 -34
  27. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/MainShell.kt +0 -390
  28. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/components/Components.kt +0 -234
  29. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/components/ContractPrimitives.kt +0 -641
  30. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/navigation/RootComponent.kt +0 -113
  31. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/ChatDetailScreen.kt +0 -212
  32. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/CreatePostScreen.kt +0 -113
  33. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/DiscoverScreen.kt +0 -137
  34. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/EditProfileScreen.kt +0 -180
  35. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/HomeFeedScreen.kt +0 -169
  36. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/MessagesInboxScreen.kt +0 -85
  37. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/NotificationsScreen.kt +0 -74
  38. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/PostDetailScreen.kt +0 -293
  39. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/ProfileSelfScreen.kt +0 -116
  40. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/SearchResultsScreen.kt +0 -161
  41. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/SettingsScreen.kt +0 -164
  42. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/SettingsStore.kt +0 -95
  43. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/UserProfileScreen.kt +0 -123
  44. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Color.kt +0 -33
  45. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Shape.kt +0 -41
  46. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Spacing.kt +0 -20
  47. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Theme.kt +0 -82
  48. package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Type.kt +0 -60
  49. package/examples/social-app/generated/android/social-app/app/src/main/res/drawable/ic_launcher_foreground.xml +0 -9
  50. package/examples/social-app/generated/android/social-app/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +0 -5
  51. package/examples/social-app/generated/android/social-app/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +0 -5
  52. package/examples/social-app/generated/android/social-app/app/src/main/res/values/strings.xml +0 -91
  53. package/examples/social-app/generated/android/social-app/app/src/main/res/values/themes.xml +0 -10
  54. package/examples/social-app/generated/android/social-app/app/src/main/res/values-ru/strings.xml +0 -79
  55. package/examples/social-app/generated/android/social-app/app/src/main/res/values-uz/strings.xml +0 -79
  56. package/examples/social-app/generated/android/social-app/app/src/main/xml/AndroidManifest.xml +0 -23
  57. package/examples/social-app/generated/android/social-app/app/src/test/kotlin/com/social/app/screenshots/HomeFeedScreenshotTest.kt +0 -34
  58. package/examples/social-app/generated/android/social-app/build.gradle.kts +0 -7
  59. package/examples/social-app/generated/android/social-app/gradle/libs.versions.toml +0 -50
  60. package/examples/social-app/generated/android/social-app/gradle/wrapper/gradle-wrapper.jar +0 -0
  61. package/examples/social-app/generated/android/social-app/gradle/wrapper/gradle-wrapper.properties +0 -8
  62. package/examples/social-app/generated/android/social-app/gradle.properties +0 -11
  63. package/examples/social-app/generated/android/social-app/gradlew +0 -248
  64. package/examples/social-app/generated/android/social-app/settings.gradle.kts +0 -27
  65. package/examples/social-app/generated/web/social-app/index.html +0 -12
  66. package/examples/social-app/generated/web/social-app/package-lock.json +0 -2517
  67. package/examples/social-app/generated/web/social-app/package.json +0 -27
  68. package/examples/social-app/generated/web/social-app/src/app/App.tsx +0 -58
  69. package/examples/social-app/generated/web/social-app/src/components/Shell.tsx +0 -259
  70. package/examples/social-app/generated/web/social-app/src/components/cards.tsx +0 -317
  71. package/examples/social-app/generated/web/social-app/src/components/ui.tsx +0 -340
  72. package/examples/social-app/generated/web/social-app/src/flows/CreatePostFlow.tsx +0 -86
  73. package/examples/social-app/generated/web/social-app/src/i18n.tsx +0 -59
  74. package/examples/social-app/generated/web/social-app/src/lib/icons.tsx +0 -85
  75. package/examples/social-app/generated/web/social-app/src/lib/tokens.ts +0 -70
  76. package/examples/social-app/generated/web/social-app/src/lib/utils.ts +0 -97
  77. package/examples/social-app/generated/web/social-app/src/locales/en.json +0 -67
  78. package/examples/social-app/generated/web/social-app/src/locales/ru.json +0 -67
  79. package/examples/social-app/generated/web/social-app/src/locales/uz.json +0 -67
  80. package/examples/social-app/generated/web/social-app/src/main.tsx +0 -16
  81. package/examples/social-app/generated/web/social-app/src/screens/ChatDetailScreen.tsx +0 -90
  82. package/examples/social-app/generated/web/social-app/src/screens/DiscoverScreen.tsx +0 -86
  83. package/examples/social-app/generated/web/social-app/src/screens/EditProfileScreen.tsx +0 -57
  84. package/examples/social-app/generated/web/social-app/src/screens/HomeFeedScreen.tsx +0 -103
  85. package/examples/social-app/generated/web/social-app/src/screens/MessagesInboxScreen.tsx +0 -52
  86. package/examples/social-app/generated/web/social-app/src/screens/NotificationsScreen.tsx +0 -41
  87. package/examples/social-app/generated/web/social-app/src/screens/PostDetailScreen.tsx +0 -115
  88. package/examples/social-app/generated/web/social-app/src/screens/ProfileSelfScreen.tsx +0 -57
  89. package/examples/social-app/generated/web/social-app/src/screens/ProfileUserScreen.tsx +0 -76
  90. package/examples/social-app/generated/web/social-app/src/screens/SearchResultsScreen.tsx +0 -96
  91. package/examples/social-app/generated/web/social-app/src/screens/SettingsScreen.tsx +0 -79
  92. package/examples/social-app/generated/web/social-app/src/state/store.ts +0 -592
  93. package/examples/social-app/generated/web/social-app/src/styles.css +0 -125
  94. package/examples/social-app/generated/web/social-app/src/vite-env.d.ts +0 -1
  95. package/examples/social-app/generated/web/social-app/tsconfig.json +0 -22
  96. package/examples/social-app/generated/web/social-app/tsconfig.node.json +0 -13
  97. package/examples/social-app/generated/web/social-app/tsconfig.node.tsbuildinfo +0 -1
  98. package/examples/social-app/generated/web/social-app/tsconfig.tsbuildinfo +0 -1
  99. package/examples/social-app/generated/web/social-app/vite.config.d.ts +0 -2
  100. package/examples/social-app/generated/web/social-app/vite.config.js +0 -6
  101. package/examples/social-app/generated/web/social-app/vite.config.ts +0 -7
  102. package/examples/social-app/package.json +0 -13
  103. package/examples/social-app/take-web-screenshots.ts +0 -97
  104. package/examples/taskflow/.codex/config.toml +0 -4
  105. package/examples/taskflow/.mcp.json +0 -10
  106. package/examples/taskflow/AGENTS.md +0 -124
  107. package/examples/taskflow/CLAUDE.md +0 -124
  108. package/examples/taskflow/backend/.gitkeep +0 -1
  109. package/examples/taskflow/generated/android/TaskFlow/README.md +0 -43
  110. package/examples/taskflow/generated/android/TaskFlow/app/build.gradle.kts +0 -76
  111. package/examples/taskflow/generated/android/TaskFlow/app/proguard-rules.pro +0 -1
  112. package/examples/taskflow/generated/android/TaskFlow/app/src/main/AndroidManifest.xml +0 -21
  113. package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/MainActivity.kt +0 -19
  114. package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/TaskFlowApp.kt +0 -283
  115. package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/model/DomainModels.kt +0 -106
  116. package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/model/SampleData.kt +0 -57
  117. package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/components/Common.kt +0 -109
  118. package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/HomeScreen.kt +0 -112
  119. package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/ProjectsScreen.kt +0 -61
  120. package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/SettingsScreen.kt +0 -82
  121. package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/TaskDetailScreen.kt +0 -111
  122. package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/sheets/Sheets.kt +0 -77
  123. package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/theme/Color.kt +0 -30
  124. package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/theme/Theme.kt +0 -86
  125. package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/theme/Type.kt +0 -57
  126. package/examples/taskflow/generated/android/TaskFlow/app/src/main/res/values/strings.xml +0 -155
  127. package/examples/taskflow/generated/android/TaskFlow/app/src/main/res/values/themes.xml +0 -4
  128. package/examples/taskflow/generated/android/TaskFlow/build.gradle.kts +0 -5
  129. package/examples/taskflow/generated/android/TaskFlow/gradle/gradle-daemon-jvm.properties +0 -12
  130. package/examples/taskflow/generated/android/TaskFlow/gradle/wrapper/gradle-wrapper.jar +0 -0
  131. package/examples/taskflow/generated/android/TaskFlow/gradle/wrapper/gradle-wrapper.properties +0 -7
  132. package/examples/taskflow/generated/android/TaskFlow/gradle.properties +0 -4
  133. package/examples/taskflow/generated/android/TaskFlow/gradlew +0 -18
  134. package/examples/taskflow/generated/android/TaskFlow/gradlew.bat +0 -12
  135. package/examples/taskflow/generated/android/TaskFlow/settings.gradle.kts +0 -18
  136. package/examples/taskflow/generated/ios/TaskFlow/README.md +0 -21
  137. package/examples/taskflow/generated/ios/TaskFlow/Resources/en.lproj/Localizable.strings +0 -115
  138. package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/App/TaskFlowApp.swift +0 -24
  139. package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Components/AppChrome.swift +0 -150
  140. package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Flows/TaskEditorSheet.swift +0 -220
  141. package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Models/DomainModels.swift +0 -122
  142. package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/CalendarView.swift +0 -21
  143. package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/HomeView.swift +0 -201
  144. package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/ProfileEditView.swift +0 -48
  145. package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/ProjectDetailView.swift +0 -59
  146. package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/ProjectsView.swift +0 -63
  147. package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/SettingsView.swift +0 -85
  148. package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/TaskDetailView.swift +0 -219
  149. package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Support/AppModel.swift +0 -320
  150. package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Support/AppSupport.swift +0 -41
  151. package/examples/taskflow/generated/ios/TaskFlow/project.yml +0 -31
  152. package/examples/taskflow/generated/web/TaskFlow/README.md +0 -19
  153. package/examples/taskflow/generated/web/TaskFlow/index.html +0 -12
  154. package/examples/taskflow/generated/web/TaskFlow/package-lock.json +0 -1908
  155. package/examples/taskflow/generated/web/TaskFlow/package.json +0 -24
  156. package/examples/taskflow/generated/web/TaskFlow/src/App.tsx +0 -58
  157. package/examples/taskflow/generated/web/TaskFlow/src/AppShell.tsx +0 -55
  158. package/examples/taskflow/generated/web/TaskFlow/src/components/Common.tsx +0 -82
  159. package/examples/taskflow/generated/web/TaskFlow/src/components/Modals.tsx +0 -191
  160. package/examples/taskflow/generated/web/TaskFlow/src/components/Nav.tsx +0 -41
  161. package/examples/taskflow/generated/web/TaskFlow/src/generated/messages.ts +0 -131
  162. package/examples/taskflow/generated/web/TaskFlow/src/hooks.ts +0 -25
  163. package/examples/taskflow/generated/web/TaskFlow/src/i18n.ts +0 -39
  164. package/examples/taskflow/generated/web/TaskFlow/src/locales.en.json +0 -111
  165. package/examples/taskflow/generated/web/TaskFlow/src/main.tsx +0 -13
  166. package/examples/taskflow/generated/web/TaskFlow/src/screens/HomeScreen.tsx +0 -111
  167. package/examples/taskflow/generated/web/TaskFlow/src/screens/ProjectsScreen.tsx +0 -82
  168. package/examples/taskflow/generated/web/TaskFlow/src/screens/SettingsScreens.tsx +0 -132
  169. package/examples/taskflow/generated/web/TaskFlow/src/screens/TaskDetail.tsx +0 -105
  170. package/examples/taskflow/generated/web/TaskFlow/src/store.ts +0 -216
  171. package/examples/taskflow/generated/web/TaskFlow/src/styles.css +0 -617
  172. package/examples/taskflow/generated/web/TaskFlow/src/types.ts +0 -64
  173. package/examples/taskflow/generated/web/TaskFlow/src/utils.ts +0 -78
  174. package/examples/taskflow/generated/web/TaskFlow/tsconfig.json +0 -21
  175. package/examples/taskflow/generated/web/TaskFlow/vite.config.ts +0 -6
  176. package/examples/todo-orbit/.codex/config.toml +0 -4
  177. package/examples/todo-orbit/.mcp.json +0 -10
  178. package/examples/todo-orbit/AGENTS.md +0 -124
  179. package/examples/todo-orbit/CLAUDE.md +0 -124
  180. package/examples/todo-orbit/backend/.gitkeep +0 -1
  181. package/examples/todo-orbit/generated/android/Todo Orbit/README.md +0 -14
  182. package/examples/todo-orbit/generated/android/Todo Orbit/app/build.gradle.kts +0 -58
  183. package/examples/todo-orbit/generated/android/Todo Orbit/app/proguard-rules.pro +0 -1
  184. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/AndroidManifest.xml +0 -20
  185. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/MainActivity.kt +0 -14
  186. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/TodoOrbitApp.kt +0 -345
  187. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/support/AppLogic.kt +0 -231
  188. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/support/Models.kt +0 -169
  189. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/support/Strings.kt +0 -8
  190. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/ui/components/CommonComponents.kt +0 -236
  191. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/ui/screens/AnalyticsScreen.kt +0 -193
  192. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/ui/screens/SettingsScreen.kt +0 -102
  193. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/ui/screens/TasksScreen.kt +0 -347
  194. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/ui/sheets/EditorSheets.kt +0 -347
  195. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/ui/theme/TodoOrbitTheme.kt +0 -59
  196. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/res/values/strings.xml +0 -149
  197. package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/res/values-ru/strings.xml +0 -155
  198. package/examples/todo-orbit/generated/android/Todo Orbit/build.gradle.kts +0 -4
  199. package/examples/todo-orbit/generated/android/Todo Orbit/gradle/wrapper/gradle-wrapper.jar +0 -0
  200. package/examples/todo-orbit/generated/android/Todo Orbit/gradle/wrapper/gradle-wrapper.properties +0 -7
  201. package/examples/todo-orbit/generated/android/Todo Orbit/gradle.properties +0 -4
  202. package/examples/todo-orbit/generated/android/Todo Orbit/gradlew +0 -248
  203. package/examples/todo-orbit/generated/android/Todo Orbit/gradlew.bat +0 -93
  204. package/examples/todo-orbit/generated/android/Todo Orbit/settings.gradle.kts +0 -18
  205. package/examples/todo-orbit/generated/ios/Todo Orbit/.screenshot-uitest/Sources/ScreenshotUITest.swift +0 -36
  206. package/examples/todo-orbit/generated/ios/Todo Orbit/README.md +0 -29
  207. package/examples/todo-orbit/generated/ios/Todo Orbit/Resources/en.lproj/Localizable.strings +0 -119
  208. package/examples/todo-orbit/generated/ios/Todo Orbit/Resources/ru.lproj/Localizable.strings +0 -119
  209. package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/App/TodoOrbitApp.swift +0 -50
  210. package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Components/OrbitChrome.swift +0 -204
  211. package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Components/SchedulePreviewView.swift +0 -126
  212. package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Components/TrendChartView.swift +0 -70
  213. package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Flows/RecurringRuleSheet.swift +0 -126
  214. package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Flows/TaskEditorSheet.swift +0 -61
  215. package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Models/DomainModels.swift +0 -238
  216. package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Screens/AnalyticsView.swift +0 -94
  217. package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Screens/SettingsView.swift +0 -76
  218. package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Screens/TasksHomeView.swift +0 -364
  219. package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Support/AppModel.swift +0 -324
  220. package/examples/todo-orbit/generated/ios/Todo Orbit/TodoOrbit.xcodeproj/project.pbxproj +0 -439
  221. package/examples/todo-orbit/generated/ios/Todo Orbit/TodoOrbit.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  222. package/examples/todo-orbit/generated/ios/Todo Orbit/TodoOrbit.xcodeproj/xcshareddata/xcschemes/TodoOrbit.xcscheme +0 -89
  223. package/examples/todo-orbit/generated/ios/Todo Orbit/project.yml +0 -32
  224. package/examples/todo-orbit/generated/web/Todo Orbit/index.html +0 -16
  225. package/examples/todo-orbit/generated/web/Todo Orbit/package-lock.json +0 -1087
  226. package/examples/todo-orbit/generated/web/Todo Orbit/package.json +0 -24
  227. package/examples/todo-orbit/generated/web/Todo Orbit/src/App.tsx +0 -2167
  228. package/examples/todo-orbit/generated/web/Todo Orbit/src/main.tsx +0 -13
  229. package/examples/todo-orbit/generated/web/Todo Orbit/src/styles.css +0 -926
  230. package/examples/todo-orbit/generated/web/Todo Orbit/tsconfig.json +0 -19
  231. package/examples/todo-orbit/generated/web/Todo Orbit/vite.config.ts +0 -6
package/README.md CHANGED
@@ -74,7 +74,7 @@ OpenUISpec includes an **MCP server** that AI assistants call automatically duri
74
74
  openuispec init → configures MCP for your agent → AI calls tools automatically
75
75
  ```
76
76
 
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.
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, validates spec integrity after edits, and returns a spec-derived checklist for the AI to review the generated code against.
78
78
 
79
79
  15 tools are available as both MCP tools and CLI commands — see the [full reference](./docs/cli.md).
80
80
 
@@ -90,6 +90,8 @@ When you ask your AI to "add a settings page" or "update the home feed," the MCP
90
90
  | [Todo Orbit](./examples/todo-orbit/openuispec/) | iOS, Android, Web | Bilingual task app with localization, custom contracts |
91
91
  | [Social App](./examples/social-app/openuispec/) | Android, Web | Trilingual social app with feeds, messaging, profiles |
92
92
 
93
+ Screenshots of the generated apps are in the [artifacts](./artifacts/) directory.
94
+
93
95
  ## Documentation
94
96
 
95
97
  | Doc | What's in it |
package/cli/index.ts CHANGED
@@ -332,6 +332,7 @@ async function main(): Promise<void> {
332
332
  width: parseInt(getOption(rest, "--width") ?? "1280"),
333
333
  height: parseInt(getOption(rest, "--height") ?? "800"),
334
334
  },
335
+ scale: parseFloat(getOption(rest, "--scale") ?? "2"),
335
336
  theme: getOption(rest, "--theme") as "light" | "dark" | undefined,
336
337
  wait_for: parseInt(getOption(rest, "--wait-for") ?? "1000"),
337
338
  full_page: getFlag(rest, "--full-page"),
@@ -382,6 +383,7 @@ async function main(): Promise<void> {
382
383
  const result = await takeScreenshotBatch(cwd, {
383
384
  captures,
384
385
  viewport: config.viewport,
386
+ scale: parseFloat(getOption(rest, "--scale") ?? config.scale ?? "2"),
385
387
  theme: (getOption(rest, "--theme") ?? config.theme) as "light" | "dark" | undefined,
386
388
  output_dir: getOption(rest, "--output-dir") ?? config.output_dir ?? undefined,
387
389
  });
@@ -459,14 +461,14 @@ Spec access:
459
461
  openuispec spec-schema <type> Get full JSON schema for a spec type
460
462
 
461
463
  Screenshots (single):
462
- openuispec screenshot [--route /path] [--theme light|dark] [--output-dir dir]
464
+ openuispec screenshot [--route /path] [--width px] [--height px] [--scale n] [--theme light|dark] [--output-dir dir]
463
465
  openuispec screenshot-android [--screen name] [--project-dir path] [--module name]
464
466
  [--route deeplink] [--nav Step1,Step2] [--theme light|dark] [--output-dir dir]
465
467
  openuispec screenshot-ios [--screen name] [--project-dir path] [--scheme name]
466
468
  [--bundle-id id] [--device name] [--nav Step1,Step2] [--theme light|dark]
467
469
 
468
470
  Screenshots (batch — build once, capture many):
469
- openuispec screenshot-web-batch --config captures.json [--theme light|dark] [--output-dir dir]
471
+ openuispec screenshot-web-batch --config captures.json [--scale n] [--theme light|dark] [--output-dir dir]
470
472
  openuispec screenshot-android-batch --config captures.json [--project-dir path]
471
473
  [--module name] [--theme light|dark] [--output-dir dir]
472
474
  openuispec screenshot-ios-batch --config captures.json [--project-dir path]
package/cli/init.ts CHANGED
@@ -348,21 +348,35 @@ Call these MCP tools directly. They return structured JSON with everything you n
348
348
 
349
349
  **Pre-generation:**
350
350
  1. Call \`openuispec_prepare\` with the target platform — returns spec context, platform config, constraints.
351
- 2. Call \`openuispec_read_specs\` to load spec file contents. Use these as the AUTHORITATIVE source.
351
+ Use \`include_specs: true\` to embed all spec contents in one call (saves a separate read_specs).
352
+ 2. Call \`openuispec_read_specs\` to load spec file contents if not using include_specs.
353
+ Without paths: returns file listing. With paths: returns contents. Use these as the AUTHORITATIVE source.
352
354
  3. If spec changes are needed, update spec files FIRST, then call \`openuispec_check\`.
353
355
  4. Generate or update the platform UI code based on the spec contents.
354
356
 
355
357
  **Post-generation (EVERY TIME after writing UI code):**
356
- 5. Call \`openuispec_check\` to validate spec integrity.
357
- 6. Call \`openuispec_read_specs\` for the screens/contracts you just generated code for.
358
- 7. Audit your generated code against the spec. For each screen, verify:
358
+ 5. Call \`openuispec_check\` to validate spec files (schema + semantics) and confirm prepare readiness.
359
+ Note: this validates the SPEC, not the generated code.
360
+ 6. Call \`openuispec_check\` with \`audit: true\` to get a spec-derived checklist, then manually review
361
+ the generated code against it. For each screen, verify:
359
362
  - Every field/action in the spec has a corresponding UI element
360
363
  - Token values (colors, spacing, radii) match exactly — no approximations
361
364
  - Contract \`must_handle\` states are all implemented (loading, error, empty, etc.)
362
365
  - Adaptive breakpoints match the spec's \`size_classes\`
363
366
  - Locale keys match \`$t:\` references
364
367
  - Navigation targets match flow definitions
365
- 8. Report any real gaps found and fix them before finishing.
368
+ 7. Report any real gaps found and fix them before finishing.
369
+
370
+ **Iterating before baseline:**
371
+ Generated code rarely needs just one pass. Read the spec, audit the generated code against it,
372
+ take screenshots to verify visuals, then fix gaps and repeat.
373
+ Multiple generate → review → fix cycles are expected before the user accepts the result.
374
+
375
+ **Baseline reminder:**
376
+ After generation, remind the user to review the output and run the baseline when satisfied:
377
+ > When you're happy with the generated output, run: \`openuispec drift --snapshot --target <t>\`
378
+ > This records the spec state so future changes are tracked as incremental drift.
379
+ Do not baseline on your own initiative — only run the snapshot when the user asks.
366
380
 
367
381
  **Creating new spec files:**
368
382
  - Call \`openuispec_spec_types\` to discover available spec types.
@@ -374,7 +388,7 @@ Call these MCP tools directly. They return structured JSON with everything you n
374
388
  - \`openuispec_get_contract(name, variant?)\` — single contract, optionally one variant
375
389
  - \`openuispec_get_tokens(category)\` — single token category (color, typography, spacing, etc.)
376
390
  - \`openuispec_get_locale(locale, keys?)\` — single locale file, optionally filtered keys
377
- - \`openuispec_check(target, screens?, contracts?)\` — scoped audit for specific screens/contracts
391
+ - \`openuispec_check(target, audit?, screens?, contracts?)\` — validation + optional scoped audit checklist
378
392
 
379
393
  Use \`read_specs\` for full-project generation; use focused getters when editing one screen or contract.
380
394
 
@@ -404,7 +418,7 @@ If MCP tools are not available, use these CLI commands with \`--json\` flag:
404
418
 
405
419
  ### Other CLI commands
406
420
  - \`openuispec init\` — scaffold a new spec project
407
- - \`openuispec drift --snapshot --target <t>\` — snapshot current state (only after UI code is updated)
421
+ - \`openuispec drift --snapshot --target <t>\` — snapshot current state (user-initiated, after reviewing generated output)
408
422
  - \`openuispec configure-target <t>\` — configure target platform stack
409
423
  - \`openuispec update-rules\` — update AI rules to match installed package version
410
424
 
@@ -448,7 +462,8 @@ Read \`spec/openuispec-v0.1.md\` from the package first, then:
448
462
  5. Fill in \`data_model\`, \`api.endpoints\` in \`${specDir}/openuispec.yaml\`
449
463
 
450
464
  ## Rules
451
- - Do not snapshot drift unless the UI code has also been updated.
465
+ - Do not baseline on your own initiative — the user decides when generated output is accepted.
466
+ - After generation, always remind the user to review and baseline: \`openuispec drift --snapshot --target <t>\`.
452
467
  - Do not modify generated UI without checking whether the spec must change first.
453
468
  - Do not use \`configure-target --defaults\` as silent approval — ask the user to confirm.
454
469
  - Always read spec format from the installed package, not from cached/memorized content.
package/docs/cli.md CHANGED
@@ -41,12 +41,12 @@ Or run directly: `openuispec mcp`
41
41
  | Tool | When | What it does |
42
42
  |------|------|-------------|
43
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 |
44
+ | `openuispec_spec_schema` | Before creating/editing spec files | Returns JSON schema for a spec type. Optional `summary` for top-level overview |
45
+ | `openuispec_prepare` | Before UI code generation | Returns spec context, platform config, constraints. Optional `include_specs` embeds all spec contents |
46
+ | `openuispec_read_specs` | Before and after generation | Without `paths`: returns file listing. With `paths`: loads spec contents |
47
+ | `openuispec_check` | After spec edits or generation | Spec validation (schema + semantic) + prepare readiness. `audit=true` returns a spec-derived checklist for manual code review |
48
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 |
49
+ | `openuispec_drift` | Before updates / after generation | Detect drift, or `snapshot=true` to create/update baseline |
50
50
  | `openuispec_status` | Anytime | Cross-target summary: baselines, drift, next steps |
51
51
  | `openuispec_get_screen` | Incremental edits | Get a single screen spec by name |
52
52
  | `openuispec_get_contract` | Incremental edits | Get a single contract spec, optionally filtered to one variant |
@@ -55,6 +55,9 @@ Or run directly: `openuispec mcp`
55
55
  | `openuispec_screenshot` | Visual verification | Screenshot the web app at a route via headless browser |
56
56
  | `openuispec_screenshot_android` | Visual verification | Screenshot Android app on emulator. Works with any project via `project_dir` |
57
57
  | `openuispec_screenshot_ios` | Visual verification | Screenshot iOS app on Simulator via XCUITest. Works with any project via `project_dir` |
58
+ | `openuispec_screenshot_web_batch` | Visual verification | Multiple web screenshots in one server session |
59
+ | `openuispec_screenshot_android_batch` | Visual verification | Multiple Android screenshots in one build+install cycle |
60
+ | `openuispec_screenshot_ios_batch` | Visual verification | Multiple iOS screenshots in one build+install cycle |
58
61
 
59
62
  The server includes **protocol-level instructions** that trigger on UI-related requests independently of CLAUDE.md rules.
60
63
 
@@ -93,12 +96,12 @@ openuispec spec-schema <type> # Get JSON schema for a spec type
93
96
 
94
97
  ```bash
95
98
  # Single captures
96
- openuispec screenshot --route /home [--theme dark] [--output-dir dir]
99
+ openuispec screenshot --route /home [--width 1280] [--height 800] [--scale 2] [--theme dark] [--output-dir dir]
97
100
  openuispec screenshot-android [--project-dir path] [--screen name] [--module name] [--route deeplink]
98
101
  openuispec screenshot-ios [--project-dir path] [--screen name] [--scheme name] [--bundle-id id]
99
102
 
100
103
  # Batch — build once, capture many
101
- openuispec screenshot-web-batch --config captures.json [--theme dark] [--output-dir dir]
104
+ openuispec screenshot-web-batch --config captures.json [--scale 2] [--theme dark] [--output-dir dir]
102
105
  openuispec screenshot-android-batch --config captures.json [--project-dir path] [--module name]
103
106
  openuispec screenshot-ios-batch --config captures.json [--project-dir path] [--scheme name] [--bundle-id id]
104
107
  ```
@@ -113,6 +116,7 @@ Screenshot tools work with **any** project — use `--project-dir` to skip manif
113
116
  | `--bundle-id` | -- | yes | Override bundle ID (default: auto-detect) |
114
117
  | `--route` | yes | -- | Deep link URI for navigation |
115
118
  | `--nav` | yes | yes | UI tap steps, comma-separated |
119
+ | `--scale` | web | -- | Device pixel ratio for sharper screenshots (default: 2) |
116
120
  | `--theme` | yes | yes | Force light or dark mode |
117
121
  | `--device` | -- | yes | Simulator device name |
118
122
  | `--output-dir` | yes | yes | Save screenshot to directory |
@@ -125,6 +129,7 @@ All batch commands accept `--config captures.json`. The JSON file has the same s
125
129
  {
126
130
  "project_dir": "path/to/project",
127
131
  "output_dir": "screenshots",
132
+ "scale": 2,
128
133
  "theme": "light",
129
134
  "captures": [
130
135
  { "screen": "home", "route": "/home", "wait_for": 3000 },
@@ -156,5 +161,5 @@ openuispec drift --snapshot --target ios
156
161
  ```
157
162
 
158
163
  - `prepare` runs in `bootstrap` mode for first-time generation and `update` mode after a snapshot exists
159
- - `drift --snapshot` is bookkeeping — it does not prove code matches the spec, and requires the output directory to exist
164
+ - `drift --snapshot` is bookkeeping — it does not prove code matches the spec, and requires the output directory to exist. Only run it after reviewing the generated output.
160
165
  - Run `openuispec status` between targets to see what still needs updating
package/drift/index.ts CHANGED
@@ -538,19 +538,28 @@ function normalizeEntry(value: string | FileEntry): FileEntry {
538
538
 
539
539
  // ── snapshot ──────────────────────────────────────────────────────────
540
540
 
541
- function snapshot(cwd: string, projectDir: string, target: string): void {
541
+ export interface SnapshotResult {
542
+ target: string;
543
+ snapshot_at: string;
544
+ files_hashed: number;
545
+ stubs: number;
546
+ state_path: string;
547
+ baseline: string | null;
548
+ }
549
+
550
+ export function createSnapshot(cwd: string, target: string): SnapshotResult {
551
+ const projectDir = findProjectDir(cwd);
542
552
  const projectName = readProjectName(projectDir);
543
553
  const outDir = resolveOutputDir(projectDir, projectName, target);
544
554
  if (!existsSync(outDir)) {
545
- console.error(
546
- `Error: Output directory not found: ${relative(cwd, outDir)}\n` +
555
+ throw new Error(
556
+ `Output directory not found: ${relative(cwd, outDir)}\n` +
547
557
  `Run code generation for "${target}" first.`
548
558
  );
549
- process.exit(1);
550
559
  }
551
560
 
561
+ const manifest = readManifest(projectDir);
552
562
  const files = discoverSpecFiles(projectDir);
553
- const doc = YAML.parse(readFileSync(join(projectDir, "openuispec.yaml"), "utf-8"));
554
563
  const baseline = captureBaseline(projectDir, files);
555
564
 
556
565
  const entries: Record<string, FileEntry> = {};
@@ -564,7 +573,7 @@ function snapshot(cwd: string, projectDir: string, target: string): void {
564
573
  }
565
574
 
566
575
  const state: StateFile = {
567
- spec_version: doc.spec_version ?? "0.1",
576
+ spec_version: manifest.spec_version ?? "0.1",
568
577
  snapshot_at: new Date().toISOString(),
569
578
  target,
570
579
  baseline,
@@ -573,15 +582,32 @@ function snapshot(cwd: string, projectDir: string, target: string): void {
573
582
 
574
583
  const outPath = stateFilePath(projectDir, projectName, target);
575
584
  writeFileSync(outPath, JSON.stringify(state, null, 2) + "\n");
576
- console.log(`Snapshot saved: ${relative(cwd, outPath)}`);
577
- console.log(` ${Object.keys(entries).length} files hashed`);
578
- if (stubCount > 0) {
579
- console.log(` ${stubCount} stubs (not tracked for drift)`);
580
- }
581
- console.log(` target: ${target}`);
582
- const baselineLabel = formatBaseline(baseline);
583
- if (baselineLabel) {
584
- console.log(` baseline: ${baselineLabel}`);
585
+
586
+ return {
587
+ target,
588
+ snapshot_at: state.snapshot_at,
589
+ files_hashed: Object.keys(entries).length,
590
+ stubs: stubCount,
591
+ state_path: relative(cwd, outPath),
592
+ baseline: formatBaseline(baseline),
593
+ };
594
+ }
595
+
596
+ function snapshot(cwd: string, projectDir: string, target: string): void {
597
+ try {
598
+ const result = createSnapshot(cwd, target);
599
+ console.log(`Snapshot saved: ${result.state_path}`);
600
+ console.log(` ${result.files_hashed} files hashed`);
601
+ if (result.stubs > 0) {
602
+ console.log(` ${result.stubs} stubs (not tracked for drift)`);
603
+ }
604
+ console.log(` target: ${result.target}`);
605
+ if (result.baseline) {
606
+ console.log(` baseline: ${result.baseline}`);
607
+ }
608
+ } catch (err) {
609
+ console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
610
+ process.exit(1);
585
611
  }
586
612
  }
587
613