openuispec 0.1.0

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 (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +214 -0
  3. package/cli/index.ts +49 -0
  4. package/cli/init.ts +390 -0
  5. package/drift/index.ts +398 -0
  6. package/examples/taskflow/README.md +103 -0
  7. package/examples/taskflow/contracts/README.md +18 -0
  8. package/examples/taskflow/contracts/action_trigger.yaml +7 -0
  9. package/examples/taskflow/contracts/collection.yaml +7 -0
  10. package/examples/taskflow/contracts/data_display.yaml +7 -0
  11. package/examples/taskflow/contracts/feedback.yaml +7 -0
  12. package/examples/taskflow/contracts/input_field.yaml +7 -0
  13. package/examples/taskflow/contracts/nav_container.yaml +7 -0
  14. package/examples/taskflow/contracts/surface.yaml +7 -0
  15. package/examples/taskflow/contracts/x_media_player.yaml +185 -0
  16. package/examples/taskflow/flows/create_task.yaml +171 -0
  17. package/examples/taskflow/flows/edit_task.yaml +131 -0
  18. package/examples/taskflow/locales/en.json +158 -0
  19. package/examples/taskflow/openuispec.yaml +144 -0
  20. package/examples/taskflow/platform/android.yaml +32 -0
  21. package/examples/taskflow/platform/ios.yaml +39 -0
  22. package/examples/taskflow/platform/web.yaml +35 -0
  23. package/examples/taskflow/screens/calendar.yaml +23 -0
  24. package/examples/taskflow/screens/home.yaml +220 -0
  25. package/examples/taskflow/screens/profile_edit.yaml +70 -0
  26. package/examples/taskflow/screens/project_detail.yaml +65 -0
  27. package/examples/taskflow/screens/projects.yaml +142 -0
  28. package/examples/taskflow/screens/settings.yaml +178 -0
  29. package/examples/taskflow/screens/task_detail.yaml +317 -0
  30. package/examples/taskflow/tokens/color.yaml +88 -0
  31. package/examples/taskflow/tokens/elevation.yaml +27 -0
  32. package/examples/taskflow/tokens/icons.yaml +189 -0
  33. package/examples/taskflow/tokens/layout.yaml +156 -0
  34. package/examples/taskflow/tokens/motion.yaml +41 -0
  35. package/examples/taskflow/tokens/spacing.yaml +23 -0
  36. package/examples/taskflow/tokens/themes.yaml +34 -0
  37. package/examples/taskflow/tokens/typography.yaml +61 -0
  38. package/package.json +43 -0
  39. package/schema/custom-contract.schema.json +257 -0
  40. package/schema/defs/action.schema.json +272 -0
  41. package/schema/defs/adaptive.schema.json +13 -0
  42. package/schema/defs/common.schema.json +330 -0
  43. package/schema/defs/data-binding.schema.json +119 -0
  44. package/schema/defs/validation.schema.json +121 -0
  45. package/schema/flow.schema.json +164 -0
  46. package/schema/locale.schema.json +26 -0
  47. package/schema/openuispec.schema.json +287 -0
  48. package/schema/platform.schema.json +95 -0
  49. package/schema/screen.schema.json +346 -0
  50. package/schema/tokens/color.schema.json +104 -0
  51. package/schema/tokens/elevation.schema.json +84 -0
  52. package/schema/tokens/icons.schema.json +149 -0
  53. package/schema/tokens/layout.schema.json +170 -0
  54. package/schema/tokens/motion.schema.json +83 -0
  55. package/schema/tokens/spacing.schema.json +93 -0
  56. package/schema/tokens/themes.schema.json +92 -0
  57. package/schema/tokens/typography.schema.json +106 -0
  58. package/schema/validate.ts +258 -0
  59. package/spec/openuispec-v0.1.md +3677 -0
@@ -0,0 +1,257 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://openuispec.org/schema/custom-contract.schema.json",
4
+ "title": "OpenUISpec Custom Contract",
5
+ "description": "Custom contract extension — root key must be x_ prefixed, value follows the standard contract anatomy",
6
+ "type": "object",
7
+ "minProperties": 1,
8
+ "maxProperties": 1,
9
+ "propertyNames": {
10
+ "pattern": "^x_[a-z][a-z0-9_]*$"
11
+ },
12
+ "additionalProperties": {
13
+ "$ref": "https://openuispec.org/schema/custom-contract.schema.json#/$defs/contract_def"
14
+ },
15
+ "$defs": {
16
+ "contract_def": {
17
+ "type": "object",
18
+ "description": "A custom contract definition following the standard contract anatomy",
19
+ "properties": {
20
+ "semantic": {
21
+ "type": "string",
22
+ "description": "Human-readable description of this contract's purpose"
23
+ },
24
+ "props": {
25
+ "type": "object",
26
+ "description": "Typed property definitions for this contract",
27
+ "additionalProperties": {
28
+ "$ref": "https://openuispec.org/schema/custom-contract.schema.json#/$defs/prop_def"
29
+ }
30
+ },
31
+ "states": {
32
+ "type": "object",
33
+ "description": "State machine definition — each key is a state name",
34
+ "additionalProperties": {
35
+ "$ref": "https://openuispec.org/schema/custom-contract.schema.json#/$defs/state_def"
36
+ }
37
+ },
38
+ "a11y": {
39
+ "type": "object",
40
+ "description": "Accessibility requirements",
41
+ "properties": {
42
+ "role": {
43
+ "type": "string",
44
+ "description": "ARIA/accessibility role"
45
+ },
46
+ "label": {
47
+ "type": "string",
48
+ "description": "Accessibility label source (usually a props reference)"
49
+ },
50
+ "traits": {
51
+ "type": "object",
52
+ "description": "Per-state accessibility traits",
53
+ "additionalProperties": true
54
+ },
55
+ "focus": {
56
+ "type": "object",
57
+ "description": "Focus and keyboard interaction definitions",
58
+ "additionalProperties": true
59
+ }
60
+ },
61
+ "required": ["role", "label"],
62
+ "additionalProperties": true
63
+ },
64
+ "tokens": {
65
+ "type": "object",
66
+ "description": "Per-variant visual token bindings",
67
+ "additionalProperties": true
68
+ },
69
+ "platform_mapping": {
70
+ "type": "object",
71
+ "description": "Per-platform native component mapping",
72
+ "properties": {
73
+ "ios": {
74
+ "type": "object",
75
+ "additionalProperties": true
76
+ },
77
+ "android": {
78
+ "type": "object",
79
+ "additionalProperties": true
80
+ },
81
+ "web": {
82
+ "type": "object",
83
+ "additionalProperties": true
84
+ }
85
+ },
86
+ "additionalProperties": {
87
+ "type": "object",
88
+ "additionalProperties": true
89
+ }
90
+ },
91
+ "dependencies": {
92
+ "type": "object",
93
+ "description": "Per-platform library/framework requirements",
94
+ "additionalProperties": {
95
+ "$ref": "https://openuispec.org/schema/custom-contract.schema.json#/$defs/dependency_def"
96
+ }
97
+ },
98
+ "generation": {
99
+ "type": "object",
100
+ "description": "AI generation compliance hints",
101
+ "properties": {
102
+ "must_handle": {
103
+ "type": "array",
104
+ "items": { "type": "string" },
105
+ "description": "Requirements the generator MUST implement"
106
+ },
107
+ "should_handle": {
108
+ "type": "array",
109
+ "items": { "type": "string" },
110
+ "description": "Requirements the generator SHOULD implement"
111
+ },
112
+ "may_handle": {
113
+ "type": "array",
114
+ "items": { "type": "string" },
115
+ "description": "Optional enhancements the generator MAY implement"
116
+ }
117
+ },
118
+ "additionalProperties": false
119
+ },
120
+ "test_cases": {
121
+ "type": "array",
122
+ "description": "Behavioral verification scenarios",
123
+ "items": {
124
+ "$ref": "https://openuispec.org/schema/custom-contract.schema.json#/$defs/test_case"
125
+ }
126
+ }
127
+ },
128
+ "required": ["semantic", "props", "states", "a11y", "tokens", "platform_mapping"],
129
+ "additionalProperties": false
130
+ },
131
+ "prop_def": {
132
+ "type": "object",
133
+ "description": "A single prop definition",
134
+ "properties": {
135
+ "type": {
136
+ "type": "string",
137
+ "description": "Data type of this prop"
138
+ },
139
+ "required": {
140
+ "type": "boolean"
141
+ },
142
+ "default": {},
143
+ "description": {
144
+ "type": "string"
145
+ },
146
+ "values": {
147
+ "type": "array",
148
+ "items": { "type": "string" },
149
+ "description": "Allowed values for enum types"
150
+ },
151
+ "position": {
152
+ "type": "string",
153
+ "description": "UI position hint"
154
+ },
155
+ "binding": {
156
+ "type": "boolean",
157
+ "description": "Whether this prop supports two-way data binding"
158
+ },
159
+ "condition": {
160
+ "type": "string",
161
+ "description": "Condition when this prop is applicable"
162
+ }
163
+ },
164
+ "required": ["type"],
165
+ "additionalProperties": false
166
+ },
167
+ "state_def": {
168
+ "type": "object",
169
+ "description": "A single state in the state machine",
170
+ "properties": {
171
+ "semantic": {
172
+ "type": "string"
173
+ },
174
+ "transitions_to": {
175
+ "type": "array",
176
+ "items": { "type": "string" },
177
+ "description": "States this state can transition to"
178
+ },
179
+ "duration": {
180
+ "type": "string",
181
+ "description": "Transition duration token reference"
182
+ },
183
+ "behavior": {
184
+ "type": "string",
185
+ "description": "Behavioral description of this state"
186
+ },
187
+ "condition": {
188
+ "type": "string",
189
+ "description": "Condition that triggers this state"
190
+ },
191
+ "feedback": {
192
+ "type": "string",
193
+ "description": "User feedback during this state"
194
+ },
195
+ "label_override": {
196
+ "type": "string",
197
+ "description": "Accessibility label override for this state"
198
+ },
199
+ "style": {
200
+ "type": "object",
201
+ "description": "Visual style overrides for this state",
202
+ "additionalProperties": true
203
+ },
204
+ "visual": {
205
+ "type": "string",
206
+ "description": "Visual description of this state"
207
+ }
208
+ },
209
+ "additionalProperties": false
210
+ },
211
+ "dependency_def": {
212
+ "type": "object",
213
+ "description": "Platform-specific dependencies",
214
+ "properties": {
215
+ "frameworks": {
216
+ "type": "array",
217
+ "items": { "type": "string" },
218
+ "description": "Required frameworks"
219
+ },
220
+ "libraries": {
221
+ "type": "array",
222
+ "items": { "type": "string" },
223
+ "description": "Required libraries"
224
+ },
225
+ "packages": {
226
+ "type": "array",
227
+ "items": { "type": "string" },
228
+ "description": "Required packages"
229
+ }
230
+ },
231
+ "additionalProperties": false
232
+ },
233
+ "test_case": {
234
+ "type": "object",
235
+ "description": "A behavioral test case",
236
+ "properties": {
237
+ "id": {
238
+ "type": "string"
239
+ },
240
+ "description": {
241
+ "type": "string"
242
+ },
243
+ "given": {
244
+ "type": "string"
245
+ },
246
+ "when": {
247
+ "type": "string"
248
+ },
249
+ "then": {
250
+ "type": "string"
251
+ }
252
+ },
253
+ "required": ["id", "description", "given", "when", "then"],
254
+ "additionalProperties": false
255
+ }
256
+ }
257
+ }
@@ -0,0 +1,272 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://openuispec.org/schema/defs/action.schema.json",
4
+ "title": "OpenUISpec Action",
5
+ "description": "Discriminated union of the 13 action types in OpenUISpec",
6
+
7
+ "type": "object",
8
+ "required": ["type"],
9
+ "properties": {
10
+ "type": {
11
+ "type": "string",
12
+ "enum": [
13
+ "navigate",
14
+ "api_call",
15
+ "set_state",
16
+ "present",
17
+ "dismiss",
18
+ "submit_form",
19
+ "confirm",
20
+ "refresh",
21
+ "open_url",
22
+ "share",
23
+ "copy",
24
+ "sequence",
25
+ "conditional",
26
+ "feedback"
27
+ ]
28
+ }
29
+ },
30
+
31
+ "allOf": [
32
+ {
33
+ "if": { "properties": { "type": { "const": "navigate" } } },
34
+ "then": {
35
+ "properties": {
36
+ "type": true,
37
+ "destination": { "type": "string" },
38
+ "params": { "type": "object", "additionalProperties": true },
39
+ "presentation": { "type": "string" },
40
+ "animation": { "type": "string" }
41
+ },
42
+ "required": ["type", "destination"],
43
+ "additionalProperties": false
44
+ }
45
+ },
46
+ {
47
+ "if": { "properties": { "type": { "const": "api_call" } } },
48
+ "then": {
49
+ "properties": {
50
+ "type": true,
51
+ "endpoint": { "type": "string" },
52
+ "params": { "type": "object", "additionalProperties": true },
53
+ "body": { "type": ["string", "object"] },
54
+ "method": { "type": "string" },
55
+ "optimistic": {
56
+ "type": "object",
57
+ "properties": {
58
+ "target": { "type": "string" },
59
+ "value": {},
60
+ "revert_on_error": { "type": "boolean" }
61
+ },
62
+ "additionalProperties": false
63
+ },
64
+ "on_success": {
65
+ "anyOf": [
66
+ { "$ref": "#" },
67
+ { "type": "object", "additionalProperties": true }
68
+ ]
69
+ },
70
+ "on_error": {
71
+ "anyOf": [
72
+ { "$ref": "#" },
73
+ { "type": "object", "additionalProperties": true }
74
+ ]
75
+ },
76
+ "feedback": {
77
+ "type": "object",
78
+ "additionalProperties": true
79
+ }
80
+ },
81
+ "required": ["type", "endpoint"],
82
+ "additionalProperties": false
83
+ }
84
+ },
85
+ {
86
+ "if": { "properties": { "type": { "const": "set_state" } } },
87
+ "then": {
88
+ "properties": {
89
+ "type": true,
90
+ "target": { "type": "string" },
91
+ "value": {}
92
+ },
93
+ "additionalProperties": true
94
+ }
95
+ },
96
+ {
97
+ "if": { "properties": { "type": { "const": "present" } } },
98
+ "then": {
99
+ "properties": {
100
+ "type": true,
101
+ "surface": { "type": "string" },
102
+ "params": { "type": "object", "additionalProperties": true }
103
+ },
104
+ "required": ["type", "surface"],
105
+ "additionalProperties": false
106
+ }
107
+ },
108
+ {
109
+ "if": { "properties": { "type": { "const": "dismiss" } } },
110
+ "then": {
111
+ "properties": {
112
+ "type": true,
113
+ "target": { "type": "string" }
114
+ },
115
+ "additionalProperties": false
116
+ }
117
+ },
118
+ {
119
+ "if": { "properties": { "type": { "const": "submit_form" } } },
120
+ "then": {
121
+ "properties": {
122
+ "type": true,
123
+ "form_id": { "type": "string" },
124
+ "validate_only": {
125
+ "type": "boolean",
126
+ "description": "Run validation without triggering on_submit (useful for multi-step forms)"
127
+ },
128
+ "on_validation_error": {
129
+ "$ref": "#",
130
+ "description": "Action to execute when validation fails (e.g., scroll to first error, show toast)"
131
+ }
132
+ },
133
+ "required": ["type", "form_id"],
134
+ "additionalProperties": false
135
+ }
136
+ },
137
+ {
138
+ "if": { "properties": { "type": { "const": "confirm" } } },
139
+ "then": {
140
+ "properties": {
141
+ "type": true,
142
+ "confirmation": {
143
+ "type": "object",
144
+ "properties": {
145
+ "contract": { "const": "feedback" },
146
+ "variant": { "type": "string" },
147
+ "props": {
148
+ "type": "object",
149
+ "properties": {
150
+ "title": { "type": "string" },
151
+ "message": { "type": "string" },
152
+ "severity": { "type": "string" },
153
+ "t_params": { "type": "object", "additionalProperties": true },
154
+ "actions": {
155
+ "type": "array",
156
+ "items": {
157
+ "type": "object",
158
+ "properties": {
159
+ "label": { "type": "string" },
160
+ "variant": { "type": "string" },
161
+ "action": { "$ref": "#" }
162
+ },
163
+ "required": ["label", "action"],
164
+ "additionalProperties": false
165
+ }
166
+ }
167
+ },
168
+ "additionalProperties": true
169
+ }
170
+ },
171
+ "required": ["contract", "variant", "props"],
172
+ "additionalProperties": false
173
+ }
174
+ },
175
+ "required": ["type", "confirmation"],
176
+ "additionalProperties": false
177
+ }
178
+ },
179
+ {
180
+ "if": { "properties": { "type": { "const": "refresh" } } },
181
+ "then": {
182
+ "properties": {
183
+ "type": true,
184
+ "target": { "type": "string" }
185
+ },
186
+ "required": ["type", "target"],
187
+ "additionalProperties": false
188
+ }
189
+ },
190
+ {
191
+ "if": { "properties": { "type": { "const": "open_url" } } },
192
+ "then": {
193
+ "properties": {
194
+ "type": true,
195
+ "url": { "type": "string" },
196
+ "external": { "type": "boolean" }
197
+ },
198
+ "required": ["type", "url"],
199
+ "additionalProperties": false
200
+ }
201
+ },
202
+ {
203
+ "if": { "properties": { "type": { "const": "share" } } },
204
+ "then": {
205
+ "properties": {
206
+ "type": true,
207
+ "content": { "type": "string" },
208
+ "title": { "type": "string" },
209
+ "url": { "type": "string" }
210
+ },
211
+ "required": ["type"],
212
+ "additionalProperties": false
213
+ }
214
+ },
215
+ {
216
+ "if": { "properties": { "type": { "const": "copy" } } },
217
+ "then": {
218
+ "properties": {
219
+ "type": true,
220
+ "content": { "type": "string" },
221
+ "feedback": { "type": "string" }
222
+ },
223
+ "required": ["type", "content"],
224
+ "additionalProperties": false
225
+ }
226
+ },
227
+ {
228
+ "if": { "properties": { "type": { "const": "sequence" } } },
229
+ "then": {
230
+ "properties": {
231
+ "type": true,
232
+ "actions": {
233
+ "type": "array",
234
+ "items": { "$ref": "#" },
235
+ "minItems": 1
236
+ }
237
+ },
238
+ "required": ["type", "actions"],
239
+ "additionalProperties": false
240
+ }
241
+ },
242
+ {
243
+ "if": { "properties": { "type": { "const": "conditional" } } },
244
+ "then": {
245
+ "properties": {
246
+ "type": true,
247
+ "condition": { "type": "string" },
248
+ "then": { "$ref": "#" },
249
+ "else": { "$ref": "#" }
250
+ },
251
+ "required": ["type", "condition", "then"],
252
+ "additionalProperties": false
253
+ }
254
+ },
255
+ {
256
+ "if": { "properties": { "type": { "const": "feedback" } } },
257
+ "then": {
258
+ "properties": {
259
+ "type": true,
260
+ "variant": { "type": "string" },
261
+ "message": { "type": "string" },
262
+ "title": { "type": "string" },
263
+ "severity": { "type": "string" },
264
+ "icon": { "type": "string" },
265
+ "duration": { "type": "integer" }
266
+ },
267
+ "required": ["type", "variant"],
268
+ "additionalProperties": false
269
+ }
270
+ }
271
+ ]
272
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://openuispec.org/schema/defs/adaptive.schema.json",
4
+ "title": "OpenUISpec Adaptive Override",
5
+ "description": "Adaptive overrides keyed by size class (compact, regular, expanded). Values are override objects whose shape depends on context.",
6
+ "type": "object",
7
+ "properties": {
8
+ "compact": { "type": "object", "additionalProperties": true },
9
+ "regular": { "type": "object", "additionalProperties": true },
10
+ "expanded": { "type": "object", "additionalProperties": true }
11
+ },
12
+ "additionalProperties": false
13
+ }