openuispec 0.1.4 → 0.1.6
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/cli/init.ts +142 -35
- package/package.json +1 -1
package/cli/init.ts
CHANGED
|
@@ -118,6 +118,88 @@ api:
|
|
|
118
118
|
`;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
function specReadmeTemplate(name: string, targets: string[]): string {
|
|
122
|
+
const targetList = targets.join(", ");
|
|
123
|
+
return `# ${name} — OpenUISpec
|
|
124
|
+
|
|
125
|
+
This directory contains the **OpenUISpec** semantic UI specification for **${name}**.
|
|
126
|
+
|
|
127
|
+
OpenUISpec is a YAML-based format that describes your app's UI semantically — tokens, screens, flows, and platform overrides. AI reads the spec and generates native code (SwiftUI, Compose, React). The spec is the single source of truth across all platforms.
|
|
128
|
+
|
|
129
|
+
## Directory structure
|
|
130
|
+
|
|
131
|
+
| Directory | Contents |
|
|
132
|
+
|-----------|----------|
|
|
133
|
+
| \`tokens/\` | Design tokens — colors, typography, spacing, elevation, motion, icons, themes |
|
|
134
|
+
| \`screens/\` | Screen definitions — one YAML file per screen |
|
|
135
|
+
| \`flows/\` | Navigation flows — multi-step user journeys |
|
|
136
|
+
| \`contracts/\` | Component contracts — custom UI component definitions (\`x_\` prefixed) |
|
|
137
|
+
| \`platform/\` | Platform overrides — per-target (iOS, Android, Web) behaviors |
|
|
138
|
+
| \`locales/\` | Localization — i18n strings (JSON, ICU MessageFormat) |
|
|
139
|
+
|
|
140
|
+
## Getting started
|
|
141
|
+
|
|
142
|
+
**Start here:** read \`openuispec.yaml\` — it's the root manifest that defines the project structure, data model, API endpoints, and generation targets.
|
|
143
|
+
|
|
144
|
+
### New project (no existing UI code)
|
|
145
|
+
|
|
146
|
+
1. Define your data model and API endpoints in \`openuispec.yaml\`
|
|
147
|
+
2. Create token files in \`tokens/\` (colors, typography, spacing)
|
|
148
|
+
3. Create screen specs in \`screens/\` (one YAML per screen)
|
|
149
|
+
4. Create navigation flows in \`flows/\`
|
|
150
|
+
5. Ask AI to generate native code from the spec
|
|
151
|
+
|
|
152
|
+
### Existing project (adopting OpenUISpec)
|
|
153
|
+
|
|
154
|
+
1. Scan the codebase for existing UI screens
|
|
155
|
+
2. Create a stub for each screen in \`screens/\`:
|
|
156
|
+
\`\`\`yaml
|
|
157
|
+
screen_name:
|
|
158
|
+
semantic: "Brief description of what this screen does"
|
|
159
|
+
status: stub
|
|
160
|
+
layout:
|
|
161
|
+
type: scroll_vertical
|
|
162
|
+
\`\`\`
|
|
163
|
+
3. Extract design tokens (colors, fonts, spacing) into \`tokens/\`
|
|
164
|
+
4. Fill in \`data_model\` and \`api.endpoints\` in \`openuispec.yaml\`
|
|
165
|
+
5. Spec screens incrementally: \`stub\` → \`draft\` → \`ready\`
|
|
166
|
+
|
|
167
|
+
## Screen and flow status
|
|
168
|
+
|
|
169
|
+
- \`stub\` — placeholder, not yet specced. Drift detection skips these.
|
|
170
|
+
- \`draft\` — actively being specced. Tracked by drift.
|
|
171
|
+
- \`ready\` — fully specified (default if omitted). Tracked by drift.
|
|
172
|
+
|
|
173
|
+
## Spec format quick reference
|
|
174
|
+
|
|
175
|
+
- **7 contract families:** nav_container, surface, action_trigger, input_field, data_display, collection, feedback
|
|
176
|
+
- **Custom contracts:** prefixed with \`x_\` (e.g., \`x_media_player\`)
|
|
177
|
+
- **Data binding:** \`$data:\`, \`$state:\`, \`$param:\`, \`$t:\` prefixes
|
|
178
|
+
- **Actions:** typed objects — navigate, api_call, set_state, confirm, sequence, feedback, etc.
|
|
179
|
+
- **Adaptive layout:** size classes (compact, regular, expanded) with per-section overrides
|
|
180
|
+
|
|
181
|
+
## CLI commands
|
|
182
|
+
|
|
183
|
+
\`\`\`bash
|
|
184
|
+
openuispec validate # Validate spec files against schemas
|
|
185
|
+
openuispec validate screens # Validate only screens
|
|
186
|
+
openuispec drift --target ${targets[0]} # Check for spec drift
|
|
187
|
+
openuispec drift --snapshot --target ${targets[0]} # Snapshot current state
|
|
188
|
+
openuispec drift --all # Include stubs in drift check
|
|
189
|
+
\`\`\`
|
|
190
|
+
|
|
191
|
+
## Targets
|
|
192
|
+
|
|
193
|
+
This project generates native code for: **${targetList}**
|
|
194
|
+
|
|
195
|
+
## Learn more
|
|
196
|
+
|
|
197
|
+
- Full spec: https://github.com/rsktash/openuispec/blob/main/spec/openuispec-v0.1.md
|
|
198
|
+
- Example app: https://github.com/rsktash/openuispec/tree/main/examples/taskflow
|
|
199
|
+
- Repository: https://github.com/rsktash/openuispec
|
|
200
|
+
`;
|
|
201
|
+
}
|
|
202
|
+
|
|
121
203
|
function aiRulesBlock(specDir: string, targets: string[]): string {
|
|
122
204
|
const targetList = targets.map((t) => `"${t}"`).join(", ");
|
|
123
205
|
return `
|
|
@@ -125,49 +207,67 @@ function aiRulesBlock(specDir: string, targets: string[]): string {
|
|
|
125
207
|
# ================================
|
|
126
208
|
# This project uses OpenUISpec to define UI as a semantic spec.
|
|
127
209
|
# Spec files are the single source of truth for all UI across platforms.
|
|
210
|
+
# Targets: ${targetList}
|
|
211
|
+
|
|
212
|
+
## What is OpenUISpec
|
|
213
|
+
OpenUISpec is a YAML-based spec format that describes an app's UI semantically — tokens, screens, flows, and platform overrides. AI reads the spec and generates native code (SwiftUI, Compose, React). AI reads native code and updates the spec. The spec is the sync layer between platforms.
|
|
128
214
|
|
|
129
215
|
## Spec location
|
|
130
216
|
- Spec root: \`${specDir}/\`
|
|
131
|
-
- Manifest: \`${specDir}/openuispec.yaml\`
|
|
132
|
-
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
##
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
217
|
+
- Manifest: \`${specDir}/openuispec.yaml\` — always read this first.
|
|
218
|
+
- Tokens: \`${specDir}/tokens/\` — colors, typography, spacing, motion, icons, themes
|
|
219
|
+
- Screens: \`${specDir}/screens/\` — one YAML file per screen
|
|
220
|
+
- Flows: \`${specDir}/flows/\` — multi-step navigation journeys
|
|
221
|
+
- Contracts: \`${specDir}/contracts/\` — UI component definitions
|
|
222
|
+
- Platform: \`${specDir}/platform/\` — per-target overrides (iOS, Android, Web)
|
|
223
|
+
- Locales: \`${specDir}/locales/\` — i18n strings (JSON, ICU MessageFormat)
|
|
224
|
+
|
|
225
|
+
## If spec directories are empty (first-time setup)
|
|
226
|
+
This means the project has existing UI code but hasn't been specced yet. Your job:
|
|
227
|
+
|
|
228
|
+
1. **Find existing screens** — scan the codebase for UI screen files (SwiftUI views, Compose screens, React components/pages).
|
|
229
|
+
2. **Create stubs** — for each screen, create \`${specDir}/screens/<name>.yaml\` with:
|
|
230
|
+
\`\`\`yaml
|
|
231
|
+
screen_name:
|
|
232
|
+
semantic: "Brief description of what this screen does"
|
|
233
|
+
status: stub
|
|
234
|
+
layout:
|
|
235
|
+
type: scroll_vertical
|
|
236
|
+
\`\`\`
|
|
237
|
+
3. **Extract tokens** — scan the codebase for colors, fonts, spacing values and create token files in \`${specDir}/tokens/\`.
|
|
238
|
+
4. **Update the manifest** — fill in \`data_model\` and \`api.endpoints\` in \`${specDir}/openuispec.yaml\` based on the existing code.
|
|
239
|
+
5. **Spec screens on demand** — when the user asks to spec a screen, read the native code, create a full spec, and change \`status: draft\` → \`ready\`.
|
|
143
240
|
|
|
144
241
|
## Screen and flow status
|
|
145
|
-
Screens and flows have a \`status\` field that controls drift tracking:
|
|
146
242
|
- \`stub\` — placeholder, not yet specced. Drift detection skips these.
|
|
147
|
-
- \`draft\` —
|
|
243
|
+
- \`draft\` — actively being specced. Tracked by drift.
|
|
148
244
|
- \`ready\` — fully specified (default if omitted). Tracked by drift.
|
|
149
245
|
|
|
150
|
-
|
|
151
|
-
1.
|
|
152
|
-
2.
|
|
153
|
-
3.
|
|
154
|
-
4.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
-
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
-
|
|
246
|
+
## Making UI changes
|
|
247
|
+
1. Read the relevant spec files before modifying any UI code.
|
|
248
|
+
2. If the change requires a spec update, modify the spec FIRST, then update code.
|
|
249
|
+
3. Never modify generated code without updating the spec.
|
|
250
|
+
4. When adding a new screen, create the corresponding spec file.
|
|
251
|
+
5. When removing a screen, remove the spec file and update flow references.
|
|
252
|
+
|
|
253
|
+
## After modifying spec files
|
|
254
|
+
1. Run \`openuispec validate\` to check specs against the schema.
|
|
255
|
+
2. Run \`openuispec drift --snapshot --target <target>\` for each affected platform.
|
|
256
|
+
3. Run \`openuispec drift\` to verify no untracked drift remains.
|
|
257
|
+
|
|
258
|
+
## Spec format reference
|
|
259
|
+
- 7 contract families: nav_container, surface, action_trigger, input_field, data_display, collection, feedback
|
|
260
|
+
- Custom contracts: prefixed with \`x_\` (e.g., \`x_media_player\`)
|
|
261
|
+
- Data binding: \`$data:\`, \`$state:\`, \`$param:\`, \`$t:\` prefixes
|
|
262
|
+
- Actions: typed objects (navigate, api_call, set_state, confirm, sequence, feedback, etc.)
|
|
263
|
+
- Adaptive layout: size classes (compact, regular, expanded) with per-section overrides
|
|
264
|
+
|
|
265
|
+
## CLI commands
|
|
266
|
+
- \`openuispec init\` — scaffold a new spec project
|
|
267
|
+
- \`openuispec validate [group...]\` — validate spec files against schemas
|
|
268
|
+
- \`openuispec drift --target <t>\` — check for spec drift
|
|
269
|
+
- \`openuispec drift --snapshot --target <t>\` — snapshot current state
|
|
270
|
+
- \`openuispec drift --all\` — include stubs in drift check
|
|
171
271
|
`;
|
|
172
272
|
}
|
|
173
273
|
|
|
@@ -229,6 +329,13 @@ export async function init(): Promise<void> {
|
|
|
229
329
|
manifestTemplate(name, targets, specDir)
|
|
230
330
|
);
|
|
231
331
|
|
|
332
|
+
// ── spec README ──────────────────────────────────────────────
|
|
333
|
+
|
|
334
|
+
writeIfMissing(
|
|
335
|
+
join(root, "README.md"),
|
|
336
|
+
specReadmeTemplate(name, targets)
|
|
337
|
+
);
|
|
338
|
+
|
|
232
339
|
// ── .gitkeep for empty dirs ────────────────────────────────────
|
|
233
340
|
|
|
234
341
|
for (const d of dirs) {
|