@12ui/design 0.2.9 → 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 (48) hide show
  1. package/README.md +34 -6
  2. package/dist/cli-cli-command.d.ts +20 -0
  3. package/dist/cli-cli-command.d.ts.map +1 -0
  4. package/dist/cli-cli-command.js +51 -0
  5. package/dist/cli-cli-command.js.map +1 -0
  6. package/dist/cli-persistence-report.d.ts +10 -0
  7. package/dist/cli-persistence-report.d.ts.map +1 -0
  8. package/dist/cli-persistence-report.js +25 -0
  9. package/dist/cli-persistence-report.js.map +1 -0
  10. package/dist/cli-persistence.d.ts +15 -0
  11. package/dist/cli-persistence.d.ts.map +1 -1
  12. package/dist/cli-persistence.js +39 -0
  13. package/dist/cli-persistence.js.map +1 -1
  14. package/dist/cli-skill-command.d.ts.map +1 -1
  15. package/dist/cli-skill-command.js +3 -11
  16. package/dist/cli-skill-command.js.map +1 -1
  17. package/dist/cli.js +11 -4
  18. package/dist/cli.js.map +1 -1
  19. package/dist/corpus-client.d.ts +15 -1
  20. package/dist/corpus-client.d.ts.map +1 -1
  21. package/dist/corpus-client.js +6 -0
  22. package/dist/corpus-client.js.map +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/legacy-skill-catalog.d.ts +3 -1
  28. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  29. package/dist/legacy-skill-catalog.js +72 -4
  30. package/dist/legacy-skill-catalog.js.map +1 -1
  31. package/dist/package-client.d.ts +40 -11
  32. package/dist/package-client.d.ts.map +1 -1
  33. package/dist/package-client.js +1 -1
  34. package/dist/package-client.js.map +1 -1
  35. package/dist/skill-installer.d.ts +1 -1
  36. package/dist/skill-installer.d.ts.map +1 -1
  37. package/dist/skill-installer.js +15 -2
  38. package/dist/skill-installer.js.map +1 -1
  39. package/package.json +1 -1
  40. package/skills/design/SKILL.md +4 -0
  41. package/skills/design-branch/SKILL.md +130 -0
  42. package/skills/design-branch/agents/openai.yaml +8 -0
  43. package/skills/design-branch/assets/large-logo.svg +7 -0
  44. package/skills/design-branch/assets/small-400px.png +0 -0
  45. package/skills/design-draft/SKILL.md +139 -0
  46. package/skills/design-draft/agents/openai.yaml +8 -0
  47. package/skills/design-draft/assets/large-logo.svg +3 -0
  48. package/skills/design-draft/assets/small-400px.png +0 -0
@@ -0,0 +1,130 @@
1
+ ---
2
+ name: design-branch
3
+ description: "Expand one approved design into a coherent multi-screen site or app, generate every planned screen in dependency order, and download the ordered pages. Use after a design is chosen to produce its remaining routes, viewports, and app states."
4
+ ---
5
+
6
+ # Design Branch
7
+
8
+ Branch one approved design into the rest of the product. The server plans the
9
+ screens and their dependencies; dispatch each screen only when the plan allows
10
+ it, and keep every paid screen addressable.
11
+
12
+ ## Start the run
13
+
14
+ A branch run is a create run with `"source": "build"`. It starts from exactly one
15
+ of an earlier create candidate or an uploaded image — sending both, or neither,
16
+ is `400 invalid_request`.
17
+
18
+ ```bash
19
+ curl -sS -X POST "$ORIGIN/api/v1/create" \
20
+ -H "Authorization: Bearer $TWELVE_UI_API_KEY" \
21
+ -H 'content-type: application/json' \
22
+ -H "Idempotency-Key: <stable-run-key>" \
23
+ -d '{
24
+ "source": "build",
25
+ "concept": "<product, audience, and what the rest of the surface must cover>",
26
+ "winner": { "createRunId": "crt-<run>", "slot": "a" }
27
+ }' | tee <run-dir>/branch.json
28
+ ```
29
+
30
+ Start from an image instead of a winner with
31
+ `"referenceImage": {"data": "<base64>", "mediaType": "image/png", "sha256": "<hex>"}`,
32
+ at most 6 MB decoded and matching its magic bytes.
33
+
34
+ `concept` is required and capped at 600 characters. `aspect` is optional and
35
+ inherits the winner's run; set `landscape`, `portrait`, or `square` only to
36
+ override it. There is no screen count, seed, or candidates field: the server
37
+ plans 2-8 screens into slots `a`-`h` and trims a longer plan to that cap.
38
+
39
+ Work under the system temporary directory, set `ORIGIN` to `TWELVE_UI_ORIGIN`
40
+ or `https://12ui.com`, and authenticate as for any create run —
41
+ `Authorization: Bearer <key>` scoped to `design.corpus.retrieve`, or a browser
42
+ `x-session-token`. `Idempotency-Key` is
43
+ required and derives the run ID; the same key with the same body replays `200`,
44
+ and with a changed body answers `409 idempotency_conflict`.
45
+
46
+ The claim runs the planner inline and takes roughly ten to twenty seconds before
47
+ answering, and buys no image. `502 build_plan_failed` means planning failed
48
+ before any image spend: retry the same request with the same key.
49
+
50
+ ## Read the plan
51
+
52
+ `plan.pages[]` gives each page's `index`, `kind` (`source` or `additional`),
53
+ `title`, `pageType`, `surfaceType`, `purpose`, and its ordered `slots`. Page 0 is
54
+ the approved design's own page and is absent when that screen already ends the
55
+ page. `plan.statusUpdate` is written to be shown verbatim.
56
+
57
+ Each `candidates[]` entry adds `pageIndex`, `viewportOrdinal` (continuations of
58
+ the approved screen start at 2), `header`, `footer`, `pageEndsHere`,
59
+ `dependsOnSlot`, and `content`. Preserve that grouping and order; it is the site
60
+ structure, not a ranking to redo.
61
+
62
+ ## Dispatch in plan order
63
+
64
+ Dispatch every screen whose dependencies are already settled, concurrently. Each
65
+ request blocks until that screen settles.
66
+
67
+ ```bash
68
+ curl -sS -X POST "$ORIGIN/api/v1/create/<run-id>/candidates/b" \
69
+ -H "Authorization: Bearer $TWELVE_UI_API_KEY" \
70
+ -H 'content-length: 0'
71
+ ```
72
+
73
+ Two gates hold a screen back, and both answer `409` with a nested error object
74
+ carrying `code` and `dependsOn`:
75
+
76
+ - `dependency_pending`: the screen continues `dependsOn`; generate that slot
77
+ first.
78
+ - `footer_reference_pending`: the screen closes a page and waits for the first
79
+ footer-bearing screen in plan order to draw the site footer. Once that seed has
80
+ failed, later footer screens proceed without it.
81
+
82
+ Send no `Idempotency-Key` on dispatch: an unkeyed repeat replays the settled
83
+ screen for free. A new key on a settled slot buys one more image for that screen
84
+ and leaves its siblings untouched, so reserve it for an explicit redraw request.
85
+ `409 candidate_in_flight` means another caller holds the slot — wait a few
86
+ seconds and read the run.
87
+
88
+ ## Poll and download
89
+
90
+ ```bash
91
+ curl -sS "$ORIGIN/api/v1/create/<run-id>" \
92
+ -H "Authorization: Bearer $TWELVE_UI_API_KEY" | tee <run-dir>/status.json
93
+ ```
94
+
95
+ There is no run-level progress: count candidate `status` values, which are
96
+ `pending`, `dispatched`, `succeeded`, and `failed`. A `failed` screen is a
97
+ settled, paid outcome, not a transient error. Download each succeeded screen
98
+ with the same headers:
99
+
100
+ ```bash
101
+ curl -sS "$ORIGIN/api/v1/create/<run-id>/candidates/b/image" \
102
+ -H "Authorization: Bearer $TWELVE_UI_API_KEY" \
103
+ -o <run-dir>/screens/b.png
104
+ ```
105
+
106
+ Runs expire seven days after the claim and then answer `410 expired`.
107
+
108
+ ## Quota
109
+
110
+ A branch run is charged per dispatched screen rather than at the claim: one
111
+ image against the daily allowance — 20 per UTC day for an account, 12 for an
112
+ anonymous caller — then the prepaid wallet for the overflow. An exhausted
113
+ allowance without a funded wallet is `429 quota_exhausted` with `retry-after`; a
114
+ funded account that cannot cover a screen is `402 insufficient_funds`, and that
115
+ screen is not persisted. Decide which screens the task needs before dispatching.
116
+
117
+ ## Hand off
118
+
119
+ Keep the plan's grouping: `plan.pages[].slots` is the order viewports stack down
120
+ one page, and page order is site order with the approved design first.
121
+
122
+ - Ordered viewports of one continuous page: submit them as one conversion
123
+ package (`POST /api/v1/convert/package`, read back with
124
+ `GET /api/v1/convert/package/<package-id>`) so page order and stitching are
125
+ preserved. Every viewport of a page must share one width.
126
+ - One independent route, app state, or mobile screen: `design-convert` on that
127
+ PNG.
128
+
129
+ Report the run ID, planned pages and slots, each screen's slot, status, and
130
+ hash, any regeneration, and the conversion package or conversion IDs.
@@ -0,0 +1,8 @@
1
+ interface:
2
+ display_name: "Design Branch"
3
+ short_description: "Expand one approved design into a whole site using 12ui design branch"
4
+ icon_small: "./assets/small-400px.png"
5
+ icon_large: "./assets/large-logo.svg"
6
+ default_prompt: "Use $design-branch to expand this homepage into a site."
7
+ policy:
8
+ allow_implicit_invocation: true
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024" version="1.1" role="img" aria-label="design-branch logo">
2
+ <path d="M 366.13 592.44 L 716.78 247.44 L 657.87 187.56 L 307.22 532.56 Z" stroke="none" fill="#000"/>
3
+ <path d="M 307.22 491.44 L 657.87 836.44 L 716.78 776.56 L 366.13 431.56 Z" stroke="none" fill="#000"/>
4
+ <path d="M 96 366 L 388 366 L 388 658 L 96 658 Z" stroke="none" fill="#000"/>
5
+ <path d="M 636 122 L 928 122 L 928 414 L 636 414 Z" stroke="none" fill="#000"/>
6
+ <path d="M 636 610 L 928 610 L 928 902 L 636 902 Z" stroke="none" fill="#000"/>
7
+ </svg>
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: design-draft
3
+ description: "Draft candidate interface designs from a written brief, optionally conditioned on reference images, then poll the run and download the winning image. Use to explore several distinctive directions for a new UI, web, or mobile screen before branching or converting one."
4
+ ---
5
+
6
+ # Design Draft
7
+
8
+ Buy one small set of candidate designs, keep the run addressable, and hand the
9
+ chosen candidate to branching or conversion. Every candidate is paid work: the
10
+ run is identified by its idempotency key, so a retry replays evidence instead of
11
+ generating again.
12
+
13
+ ## Prepare
14
+
15
+ Work under the system temporary directory. Set `ORIGIN` to `TWELVE_UI_ORIGIN`
16
+ or `https://12ui.com`, and send a personal key in `Authorization: Bearer <key>`
17
+ taken from `TWELVE_UI_API_KEY` or `~/.config/12ui/credentials.json` and scoped
18
+ to `design.corpus.retrieve`. A browser session may present `x-session-token`
19
+ instead.
20
+
21
+ Write one `concept`: product, audience, surface, primary goal, and personality
22
+ in at most 600 characters. Describe the design problem, not every section,
23
+ control, or exact string.
24
+
25
+ Default to four candidates in slots `a`-`d`; a run accepts 1-96 across slots
26
+ `a`-`cr`. Pick one `aspect` for the whole run — `landscape` (1536x1024),
27
+ `portrait` (1024x1536), or `square` (1024x1024).
28
+
29
+ Give every candidate its own short `direction` (at most 120 characters), such as
30
+ airy editorial, tactile retail, or cinematic, and make the directions
31
+ meaningfully different. Leaving any direction blank spends one extra metered
32
+ text call to derive them all.
33
+
34
+ ## Claim the run
35
+
36
+ `Idempotency-Key` is required and derives the run ID, so the same key always
37
+ resolves the same run, quota allocation, and stored images.
38
+
39
+ ```bash
40
+ curl -sS -X POST "$ORIGIN/api/v1/create" \
41
+ -H "Authorization: Bearer $TWELVE_UI_API_KEY" \
42
+ -H 'content-type: application/json' \
43
+ -H "Idempotency-Key: <stable-run-key>" \
44
+ -d '{
45
+ "concept": "<concise interface concept>",
46
+ "aspect": "landscape",
47
+ "mode": "inspiration",
48
+ "candidates": [
49
+ { "slot": "a", "direction": "<short direction>", "referenceId": "gen-<corpus-id>" },
50
+ { "slot": "b", "direction": "<short direction>", "referenceId": "gen-<corpus-id>" }
51
+ ]
52
+ }' | tee <run-dir>/run.json
53
+ ```
54
+
55
+ Give a candidate at most one reference and never both kinds: `referenceId` is a
56
+ `design-search` corpus ID, `"useReferenceImage": true` conditions on the one
57
+ run-level image sent as base64 with its media type and SHA-256. Omitting both
58
+ generates from the concept and direction alone.
59
+
60
+ ```json
61
+ "referenceImage": { "data": "<base64>", "mediaType": "image/png", "sha256": "<hex>" }
62
+ ```
63
+
64
+ The decoded image must be at most 6 MB, its media type must match its magic
65
+ bytes, and the whole body must stay under 8 MB. `mode` defaults to
66
+ `inspiration`; use `preserve-structure` only with a `referenceImage` that every
67
+ candidate uses.
68
+
69
+ The reply is the run envelope: `id`, `aspect`, `mode`, `source`, `expiresAt`
70
+ seven days out, and one `pending` entry per slot. Replaying the same key with the
71
+ same body answers `200` with that envelope. The same key with a changed body is
72
+ `409 idempotency_conflict`, or `503 service_unavailable` when the candidate
73
+ count changed too; either way keep the original request rather than editing a
74
+ claim. Mint a new key only when the reply says to start a new run, which a
75
+ poisoned claim such as `502 create_directions_failed` or
76
+ `409 run_setup_incomplete` does say.
77
+
78
+ ## Dispatch the candidates
79
+
80
+ Each slot is one provider call and one paid image. Dispatch all slots
81
+ concurrently; every request blocks until its own image settles.
82
+
83
+ ```bash
84
+ curl -sS -X POST "$ORIGIN/api/v1/create/<run-id>/candidates/a" \
85
+ -H "Authorization: Bearer $TWELVE_UI_API_KEY" \
86
+ -H 'content-length: 0'
87
+ ```
88
+
89
+ Send no `Idempotency-Key` on dispatch: an unkeyed repeat replays the durable
90
+ result for free. A new key on a settled slot buys another image for that slot,
91
+ so use it only when the user asks for a fresh attempt. `409 candidate_in_flight`
92
+ means another caller already holds the slot — wait a few seconds and read the
93
+ run instead of dispatching again.
94
+
95
+ ## Poll and download
96
+
97
+ ```bash
98
+ curl -sS "$ORIGIN/api/v1/create/<run-id>" \
99
+ -H "Authorization: Bearer $TWELVE_UI_API_KEY" | tee <run-dir>/status.json
100
+ ```
101
+
102
+ There is no run-level status or percentage: count candidate `status` values,
103
+ which are `pending`, `dispatched`, `succeeded`, and `failed`. A `failed`
104
+ candidate is a settled, paid outcome — `content_policy`, `provider_timeout`,
105
+ `provider_error`, or `reference_unavailable` — not a transient error to retry.
106
+
107
+ A succeeded candidate carries a relative `image` path. It is owner
108
+ authenticated rather than signed, so download it with the same headers:
109
+
110
+ ```bash
111
+ curl -sS "$ORIGIN/api/v1/create/<run-id>/candidates/a/image" \
112
+ -H "Authorization: Bearer $TWELVE_UI_API_KEY" \
113
+ -o <run-dir>/candidates/a.png
114
+ ```
115
+
116
+ Runs expire seven days after the claim; `410 expired` is terminal.
117
+
118
+ ## Quota
119
+
120
+ An account generates 20 images per UTC day and an anonymous caller 12. Overflow
121
+ spills to the prepaid wallet as one billable image per slot. An exhausted
122
+ allowance without a funded wallet is `429 quota_exhausted` with `retry-after`; a
123
+ funded account that cannot cover the overflow is `402 insufficient_funds` with
124
+ `required_micros` and `available_micros`, and no candidate is persisted. Neither
125
+ answer becomes success by resending.
126
+
127
+ ## Select and hand off
128
+
129
+ Inspect every downloaded candidate at original detail and choose the best
130
+ direction for the brief, hierarchy, usability, personality, accessibility, and
131
+ ability to extend into later screens. Treat common model palettes as neutral,
132
+ and prefer a repeatable visual system over an impressive one-off hero. Record
133
+ the run ID, slots, directions, references, image hashes, and rejection reasons.
134
+
135
+ - Expand the winner into a multi-screen site or app with `design-branch`, which
136
+ starts from `{ "createRunId": "<run-id>", "slot": "<slot>" }` and never needs
137
+ the bytes.
138
+ - Turn one screen into code or another format with `design-convert` on the
139
+ downloaded PNG.
@@ -0,0 +1,8 @@
1
+ interface:
2
+ display_name: "Design Draft"
3
+ short_description: "Draft candidate design directions from a brief with 12ui design draft"
4
+ icon_small: "./assets/small-400px.png"
5
+ icon_large: "./assets/large-logo.svg"
6
+ default_prompt: "Use $design-draft to draft four homepage directions."
7
+ policy:
8
+ allow_implicit_invocation: true
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024" version="1.1" role="img" aria-label="design-create logo">
2
+ <path d="M 600 110 C 600 335.72, 716.28 452, 942 452 C 716.28 452, 600 568.28, 600 794 C 600 568.28, 483.72 452, 258 452 C 483.72 452, 600 335.72, 600 110 Z M 232 628 C 232 745.48, 292.52 806, 410 806 C 292.52 806, 232 866.52, 232 984 C 232 866.52, 171.48 806, 54 806 C 171.48 806, 232 745.48, 232 628 Z" stroke="none" fill="#000"/>
3
+ </svg>