@12ui/design 0.2.12 → 0.2.14

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 (203) hide show
  1. package/README.md +44 -9
  2. package/dist/branch-client.d.ts +155 -0
  3. package/dist/branch-client.d.ts.map +1 -0
  4. package/dist/branch-client.js +179 -0
  5. package/dist/branch-client.js.map +1 -0
  6. package/dist/branch-completion.d.ts +37 -0
  7. package/dist/branch-completion.d.ts.map +1 -0
  8. package/dist/branch-completion.js +137 -0
  9. package/dist/branch-completion.js.map +1 -0
  10. package/dist/branch-dispatch-loop.d.ts +84 -0
  11. package/dist/branch-dispatch-loop.d.ts.map +1 -0
  12. package/dist/branch-dispatch-loop.js +206 -0
  13. package/dist/branch-dispatch-loop.js.map +1 -0
  14. package/dist/branch-downloads.d.ts +43 -0
  15. package/dist/branch-downloads.d.ts.map +1 -0
  16. package/dist/branch-downloads.js +94 -0
  17. package/dist/branch-downloads.js.map +1 -0
  18. package/dist/branch-execution-types.d.ts +54 -0
  19. package/dist/branch-execution-types.d.ts.map +1 -0
  20. package/dist/branch-execution-types.js +2 -0
  21. package/dist/branch-execution-types.js.map +1 -0
  22. package/dist/branch-execution.d.ts +18 -0
  23. package/dist/branch-execution.d.ts.map +1 -0
  24. package/dist/branch-execution.js +261 -0
  25. package/dist/branch-execution.js.map +1 -0
  26. package/dist/branch-identity.d.ts +71 -0
  27. package/dist/branch-identity.d.ts.map +1 -0
  28. package/dist/branch-identity.js +72 -0
  29. package/dist/branch-identity.js.map +1 -0
  30. package/dist/branch-materialize.d.ts +22 -0
  31. package/dist/branch-materialize.d.ts.map +1 -0
  32. package/dist/branch-materialize.js +47 -0
  33. package/dist/branch-materialize.js.map +1 -0
  34. package/dist/branch-page-conversion.d.ts +39 -0
  35. package/dist/branch-page-conversion.d.ts.map +1 -0
  36. package/dist/branch-page-conversion.js +206 -0
  37. package/dist/branch-page-conversion.js.map +1 -0
  38. package/dist/branch-plan.d.ts +63 -0
  39. package/dist/branch-plan.d.ts.map +1 -0
  40. package/dist/branch-plan.js +95 -0
  41. package/dist/branch-plan.js.map +1 -0
  42. package/dist/branch-progress.d.ts +75 -0
  43. package/dist/branch-progress.d.ts.map +1 -0
  44. package/dist/branch-progress.js +159 -0
  45. package/dist/branch-progress.js.map +1 -0
  46. package/dist/branch-run-record.d.ts +153 -0
  47. package/dist/branch-run-record.d.ts.map +1 -0
  48. package/dist/branch-run-record.js +94 -0
  49. package/dist/branch-run-record.js.map +1 -0
  50. package/dist/branch-schedule.d.ts +74 -0
  51. package/dist/branch-schedule.d.ts.map +1 -0
  52. package/dist/branch-schedule.js +130 -0
  53. package/dist/branch-schedule.js.map +1 -0
  54. package/dist/branch-status.d.ts +11 -0
  55. package/dist/branch-status.d.ts.map +1 -0
  56. package/dist/branch-status.js +115 -0
  57. package/dist/branch-status.js.map +1 -0
  58. package/dist/branch-viewport-normalization.d.ts +74 -0
  59. package/dist/branch-viewport-normalization.d.ts.map +1 -0
  60. package/dist/branch-viewport-normalization.js +120 -0
  61. package/dist/branch-viewport-normalization.js.map +1 -0
  62. package/dist/cli-arguments.d.ts.map +1 -1
  63. package/dist/cli-arguments.js +5 -0
  64. package/dist/cli-arguments.js.map +1 -1
  65. package/dist/cli-branch-command.d.ts +46 -0
  66. package/dist/cli-branch-command.d.ts.map +1 -0
  67. package/dist/cli-branch-command.js +426 -0
  68. package/dist/cli-branch-command.js.map +1 -0
  69. package/dist/cli-capabilities.d.ts +28 -0
  70. package/dist/cli-capabilities.d.ts.map +1 -1
  71. package/dist/cli-capabilities.js +29 -1
  72. package/dist/cli-capabilities.js.map +1 -1
  73. package/dist/cli-create-command.d.ts +21 -0
  74. package/dist/cli-create-command.d.ts.map +1 -0
  75. package/dist/cli-create-command.js +319 -0
  76. package/dist/cli-create-command.js.map +1 -0
  77. package/dist/cli-detach.d.ts +62 -0
  78. package/dist/cli-detach.d.ts.map +1 -0
  79. package/dist/cli-detach.js +123 -0
  80. package/dist/cli-detach.js.map +1 -0
  81. package/dist/cli-draft-command.d.ts +63 -0
  82. package/dist/cli-draft-command.d.ts.map +1 -0
  83. package/dist/cli-draft-command.js +220 -0
  84. package/dist/cli-draft-command.js.map +1 -0
  85. package/dist/cli-export-command.d.ts.map +1 -1
  86. package/dist/cli-export-command.js +2 -3
  87. package/dist/cli-export-command.js.map +1 -1
  88. package/dist/cli-image-batch-command.d.ts +21 -0
  89. package/dist/cli-image-batch-command.d.ts.map +1 -1
  90. package/dist/cli-image-batch-command.js +166 -54
  91. package/dist/cli-image-batch-command.js.map +1 -1
  92. package/dist/cli-image-batch-materialize.d.ts +27 -0
  93. package/dist/cli-image-batch-materialize.d.ts.map +1 -0
  94. package/dist/cli-image-batch-materialize.js +41 -0
  95. package/dist/cli-image-batch-materialize.js.map +1 -0
  96. package/dist/cli-image-batch-resume.d.ts +34 -0
  97. package/dist/cli-image-batch-resume.d.ts.map +1 -0
  98. package/dist/cli-image-batch-resume.js +175 -0
  99. package/dist/cli-image-batch-resume.js.map +1 -0
  100. package/dist/cli-image-command.d.ts.map +1 -1
  101. package/dist/cli-image-command.js +14 -2
  102. package/dist/cli-image-command.js.map +1 -1
  103. package/dist/cli-package-command.d.ts +18 -0
  104. package/dist/cli-package-command.d.ts.map +1 -0
  105. package/dist/cli-package-command.js +112 -0
  106. package/dist/cli-package-command.js.map +1 -0
  107. package/dist/cli-progress.d.ts +61 -0
  108. package/dist/cli-progress.d.ts.map +1 -1
  109. package/dist/cli-progress.js +53 -0
  110. package/dist/cli-progress.js.map +1 -1
  111. package/dist/cli-select-command.d.ts +12 -0
  112. package/dist/cli-select-command.d.ts.map +1 -0
  113. package/dist/cli-select-command.js +66 -0
  114. package/dist/cli-select-command.js.map +1 -0
  115. package/dist/cli.js +140 -7
  116. package/dist/cli.js.map +1 -1
  117. package/dist/create-identity.d.ts +25 -0
  118. package/dist/create-identity.d.ts.map +1 -0
  119. package/dist/create-identity.js +0 -0
  120. package/dist/create-identity.js.map +1 -0
  121. package/dist/draft-identity.d.ts +30 -0
  122. package/dist/draft-identity.d.ts.map +1 -0
  123. package/dist/draft-identity.js +0 -0
  124. package/dist/draft-identity.js.map +1 -0
  125. package/dist/draft-prompts.d.ts +35 -0
  126. package/dist/draft-prompts.d.ts.map +1 -0
  127. package/dist/draft-prompts.js +51 -0
  128. package/dist/draft-prompts.js.map +1 -0
  129. package/dist/draft-run.d.ts +32 -0
  130. package/dist/draft-run.d.ts.map +1 -0
  131. package/dist/draft-run.js +152 -0
  132. package/dist/draft-run.js.map +1 -0
  133. package/dist/draft-workspace.d.ts +90 -0
  134. package/dist/draft-workspace.d.ts.map +1 -0
  135. package/dist/draft-workspace.js +64 -0
  136. package/dist/draft-workspace.js.map +1 -0
  137. package/dist/image-batch-status.d.ts +42 -0
  138. package/dist/image-batch-status.d.ts.map +1 -0
  139. package/dist/image-batch-status.js +142 -0
  140. package/dist/image-batch-status.js.map +1 -0
  141. package/dist/image-dimensions.d.ts +12 -0
  142. package/dist/image-dimensions.d.ts.map +1 -0
  143. package/dist/image-dimensions.js +14 -0
  144. package/dist/image-dimensions.js.map +1 -0
  145. package/dist/image-generation-batch-attempt.d.ts +28 -0
  146. package/dist/image-generation-batch-attempt.d.ts.map +1 -0
  147. package/dist/image-generation-batch-attempt.js +48 -0
  148. package/dist/image-generation-batch-attempt.js.map +1 -0
  149. package/dist/image-generation-completion.d.ts +43 -0
  150. package/dist/image-generation-completion.d.ts.map +1 -0
  151. package/dist/image-generation-completion.js +54 -0
  152. package/dist/image-generation-completion.js.map +1 -0
  153. package/dist/image-generation-fs.d.ts +3 -0
  154. package/dist/image-generation-fs.d.ts.map +1 -0
  155. package/dist/image-generation-fs.js +23 -0
  156. package/dist/image-generation-fs.js.map +1 -0
  157. package/dist/image-generation-request.d.ts +13 -3
  158. package/dist/image-generation-request.d.ts.map +1 -1
  159. package/dist/image-generation-request.js +21 -19
  160. package/dist/image-generation-request.js.map +1 -1
  161. package/dist/image-generation-resume.d.ts +49 -0
  162. package/dist/image-generation-resume.d.ts.map +1 -0
  163. package/dist/image-generation-resume.js +96 -0
  164. package/dist/image-generation-resume.js.map +1 -0
  165. package/dist/image-generation-run.d.ts +11 -0
  166. package/dist/image-generation-run.d.ts.map +1 -1
  167. package/dist/image-generation-run.js +23 -9
  168. package/dist/image-generation-run.js.map +1 -1
  169. package/dist/image-generation-staging.d.ts +25 -0
  170. package/dist/image-generation-staging.d.ts.map +1 -0
  171. package/dist/image-generation-staging.js +80 -0
  172. package/dist/image-generation-staging.js.map +1 -0
  173. package/dist/index.d.ts +5 -0
  174. package/dist/index.d.ts.map +1 -1
  175. package/dist/index.js +4 -0
  176. package/dist/index.js.map +1 -1
  177. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  178. package/dist/legacy-skill-catalog.js +133 -0
  179. package/dist/legacy-skill-catalog.js.map +1 -1
  180. package/dist/package-manifest-file.d.ts +21 -0
  181. package/dist/package-manifest-file.d.ts.map +1 -0
  182. package/dist/package-manifest-file.js +119 -0
  183. package/dist/package-manifest-file.js.map +1 -0
  184. package/dist/package-manifest-template.d.ts +23 -0
  185. package/dist/package-manifest-template.d.ts.map +1 -0
  186. package/dist/package-manifest-template.js +60 -0
  187. package/dist/package-manifest-template.js.map +1 -0
  188. package/dist/package-submission.d.ts +103 -0
  189. package/dist/package-submission.d.ts.map +1 -0
  190. package/dist/package-submission.js +173 -0
  191. package/dist/package-submission.js.map +1 -0
  192. package/dist/selection-record.d.ts +95 -0
  193. package/dist/selection-record.d.ts.map +1 -0
  194. package/dist/selection-record.js +121 -0
  195. package/dist/selection-record.js.map +1 -0
  196. package/package.json +1 -1
  197. package/skills/design/SKILL.md +55 -240
  198. package/skills/design-branch/SKILL.md +36 -116
  199. package/skills/design-convert/SKILL.md +62 -132
  200. package/skills/design-draft/SKILL.md +71 -135
  201. package/skills/design-search/SKILL.md +29 -78
  202. package/skills/design/references/continuation-contract.md +0 -60
  203. package/skills/design/references/selection-contract.md +0 -96
@@ -0,0 +1,121 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readFile, writeFile } from 'node:fs/promises';
3
+ import { readBatchAttempt, imageBatchAttemptPath } from './image-generation-batch-attempt.js';
4
+ import { imageAttemptPath } from './image-generation-evidence.js';
5
+ import { readImageGenerationAttemptFile } from './image-generation-staging.js';
6
+ /**
7
+ * `selection.json`, version 6 — the same contract the skill used to ask an
8
+ * agent to hand-assemble from four other files. Every field here is copied
9
+ * from durable evidence the run already wrote, which is the point: a record
10
+ * assembled by hand can disagree with the run it describes, and this one
11
+ * cannot.
12
+ *
13
+ * The recommendation protocol is preserved exactly: `recommended` when the
14
+ * winner is the recommended candidate, `override` when it is not (and then a
15
+ * specific reason is required), `no-recommendation` when the run indicated
16
+ * none.
17
+ */
18
+ export const SELECTION_RECORD_VERSION = 6;
19
+ export const buildSelectionRecord = async (args) => {
20
+ const now = args.now ?? (() => new Date());
21
+ const { draft } = args;
22
+ if (!draft.generation.candidates.some((candidate) => candidate.id === args.winner)) {
23
+ throw new Error(`Candidate ${args.winner} is not in this run. It has`
24
+ + ` ${draft.generation.candidates.map((candidate) => candidate.id).join(', ')}.`);
25
+ }
26
+ const batchAttemptPath = imageBatchAttemptPath(draft.generation.manifestPath);
27
+ const batch = await readBatchAttempt(batchAttemptPath);
28
+ const candidates = await Promise.all(draft.generation.candidates.map(async (candidate) => {
29
+ const attemptEvidencePath = imageAttemptPath(candidate.outputPath);
30
+ const attempt = await readImageGenerationAttemptFile(attemptEvidencePath);
31
+ const bytes = await readFile(candidate.outputPath).catch(() => null);
32
+ return {
33
+ id: candidate.id,
34
+ path: candidate.outputPath,
35
+ sha256: attempt?.outputSha256
36
+ ?? (bytes ? createHash('sha256').update(bytes).digest('hex') : null),
37
+ prompt: candidate.prompt,
38
+ promptSha256: candidate.promptSha256,
39
+ directionReferenceId: candidate.referenceId,
40
+ direction: candidate.direction,
41
+ generationReferencePath: candidate.referencePath,
42
+ generationReferenceSha256: candidate.referenceSha256,
43
+ referenceMode: draft.referenceMode,
44
+ provider: attempt?.provider ?? batch?.provider ?? null,
45
+ idempotencyKey: candidate.idempotencyKey,
46
+ // Only ever the recorded CLI value, never an assumed guarantee.
47
+ providerIdempotencyEnforced: attempt?.providerIdempotencyEnforced === true,
48
+ attemptEvidencePath,
49
+ rejectionReasons: candidate.id === args.winner
50
+ ? []
51
+ : args.rejectionReasons?.[candidate.id] ?? [],
52
+ };
53
+ }));
54
+ const recommendation = args.recommendation ?? { candidateId: null, source: null };
55
+ const selectionSource = recommendation.candidateId === null
56
+ ? 'no-recommendation'
57
+ : recommendation.candidateId === args.winner
58
+ ? 'recommended'
59
+ : 'override';
60
+ if (selectionSource === 'override' && !args.reason.trim()) {
61
+ throw new Error('Overriding the recommended candidate requires a specific reason');
62
+ }
63
+ const reskin = draft.mode === 'structure-preserving-reskin';
64
+ return {
65
+ version: SELECTION_RECORD_VERSION,
66
+ createdAt: now().toISOString(),
67
+ requestSummary: draft.query,
68
+ viewportMode: 'first-viewport',
69
+ designMode: draft.mode,
70
+ redesignSource: {
71
+ originalPath: draft.redesignSource?.path ?? null,
72
+ originalSha256: draft.redesignSource?.sha256 ?? null,
73
+ preparedPath: draft.redesignSource?.path ?? null,
74
+ preparedSha256: draft.redesignSource?.sha256 ?? null,
75
+ preparation: 'none',
76
+ },
77
+ contract: { preserve: [], change: [] },
78
+ referencePolicy: {
79
+ retrieval: draft.redesignSource ? 'text-and-redesign-source' : 'text-only',
80
+ generation: reskin ? 'redesign-source-only' : 'one-corpus-image-per-candidate',
81
+ imagesPerGeneration: 1,
82
+ },
83
+ corpus: {
84
+ query: draft.corpus.query,
85
+ mode: draft.corpus.mode,
86
+ fallback: null,
87
+ idempotencyKey: draft.corpus.idempotencyKey,
88
+ setId: draft.corpus.setId,
89
+ references: draft.corpus.references.map((reference) => ({
90
+ id: reference.id,
91
+ path: reference.path,
92
+ sha256: reference.sha256,
93
+ aspect: reference.aspect,
94
+ })),
95
+ },
96
+ generation: {
97
+ referenceMode: draft.referenceMode,
98
+ manifestPath: draft.generation.manifestPath,
99
+ manifestSha256: draft.generation.manifestSha256,
100
+ batchAttemptPath,
101
+ },
102
+ candidates,
103
+ recommendation,
104
+ winner: args.winner,
105
+ selectionSource,
106
+ selectionOverrideReason: selectionSource === 'override' ? args.reason.trim() : null,
107
+ rationale: args.reason.trim(),
108
+ };
109
+ };
110
+ export const writeSelectionRecord = async (file, record) => {
111
+ await writeFile(file, `${JSON.stringify(record, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 });
112
+ };
113
+ export const readSelectionRecord = async (file) => {
114
+ try {
115
+ return JSON.parse(await readFile(file, 'utf8'));
116
+ }
117
+ catch {
118
+ return undefined;
119
+ }
120
+ };
121
+ //# sourceMappingURL=selection-record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-record.js","sourceRoot":"","sources":["../src/selection-record.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@12ui/design",
3
- "version": "0.2.12",
3
+ "version": "0.2.14",
4
4
  "type": "module",
5
5
  "description": "The canonical 12UI CLI, SDK, MCP server, and visual interface design skills",
6
6
  "main": "dist/index.js",
@@ -1,246 +1,61 @@
1
1
  ---
2
2
  name: design
3
- description: "REQUIRED for all visual interface tasks (UI, Web, Mobile). Uses design-search to find high-quality references with strong UX and personality, image generation to explore distinctive directions, and design-convert to turn the chosen design into ready-to-use code quickly. Use for creating, redesigning, or implementing interfaces; it routes finished screenshots directly to conversion and keeps tiny edits code-only."
3
+ description: "Required for non-trivial UI creation and redesign (web, app,
4
+ mobile): explores distinctive, corpus-grounded visual directions as images,
5
+ then converts the chosen one into production-ready code."
4
6
  ---
5
7
 
6
8
  # Design
7
9
 
8
- Author the visual direction before coding it. Code-first agents tend toward
9
- safe, generic visual defaults. Corpus-conditioned generation introduces a
10
- wider visual vocabulary and more personality; converting the chosen image
11
- then preserves that direction with near-pixel-perfect fidelity much faster
12
- than recreating it manually.
13
-
14
- ## Choose the route
15
-
16
- - Finished screenshot or mockup to reproduce faithfully: use `design-convert`
17
- directly.
18
- - Existing screenshot supplied as a redesign source: choose an exploratory
19
- redesign or a structure-preserving reskin below. It is not a corpus
20
- inspiration image.
21
- - Small visual edit: change the existing project code. Do not search, generate,
22
- or convert.
23
- - Only one pipeline stage is wanted, or no local image provider is available:
24
- use `design-search` for references, `design-draft` for hosted candidate
25
- generation, `design-branch` to expand one approved design into the remaining
26
- screens, and `design-convert` for code and other formats.
27
- - Rough brief, new interface, or major redesign: use the workflow below.
28
-
29
- ## Authored workflow
30
-
31
- ### 1. Inspect and search
32
-
33
- Inspect the project before designing: its instructions, framework, routes,
34
- components, assets, conventions, validation commands, and existing user
35
- changes. Create the run directory under the system temporary directory.
36
-
37
- If there is a redesign source, state a short preserve/change contract before
38
- searching. Choose one mode:
39
-
40
- - `exploratory-redesign`: preserve only named product/UX constraints and allow
41
- layout and visual language to change.
42
- - `structure-preserving-reskin`: preserve the named information architecture,
43
- content hierarchy, and interactions; change only the named visual qualities.
44
-
45
- If the source is a long page or contains more than the target screen, crop the
46
- relevant first viewport into the system temporary run directory before search
47
- or generation. Keep and hash both the original and prepared crop; do not make
48
- the image model solve a whole-page composition inside one viewport.
49
-
50
- Search with the CLI; do not make a separate brief file:
51
-
52
- ```bash
53
- 12ui corpus inspire \
54
- --query "<product, audience, surface, primary goal, personality>" \
55
- --mode balanced \
56
- --count 4 \
57
- --out-dir <run-dir>/references
58
- ```
59
-
60
- `balanced` is the recommended mode and the default. Run it once; do not compare
61
- all three modes speculatively. Change modes only after inspecting a complete
62
- Balanced set and recording why it failed the brief:
63
-
64
- - Use `--mode direct` when Balanced is visually competent but semantically
65
- diffuse or misses the literal product or screen requested.
66
- - Use `--mode adventurer` when Balanced is on-brief but too conventional or
67
- repetitive to author four meaningfully distinct directions.
68
-
69
- Use at most one fallback mode in a new output directory. A transport error,
70
- ambiguous request, underfilled set, or interrupted download is not a retrieval
71
- failure: resume the original Balanced attempt with `12ui corpus resume` and do
72
- not switch modes.
73
-
74
- For either redesign mode, add the existing screenshot to retrieval:
75
-
76
- ```bash
77
- 12ui corpus inspire \
78
- --query "<preserve/change contract and desired direction>" \
79
- --mode balanced \
80
- --reference-image <redesign-source.png> \
81
- --count 4 \
82
- --out-dir <run-dir>/references
83
- ```
84
-
85
- This performs one image-and-text-conditioned search. The redesign source stays
86
- distinct from the four returned corpus inspirations.
87
-
88
- Use the four real downloaded images in endpoint order. `manifest.json` records
89
- the locked mode, IDs, paths, hashes, and returned provenance. Preserve that
90
- order and evidence; do not rerank or invent a composite score. If interrupted,
91
- run `12ui corpus resume --out-dir <run-dir>/references` rather than starting
92
- another search.
93
-
94
- ### 2. Generate four directions
95
-
96
- Generate only the first viewport, one primary app state, or one mobile screen.
97
- Do not squeeze the whole page or journey into one canvas. Prefer full-bleed
98
- imagery where useful, strong hierarchy, breathing room, and sound UX. Make the
99
- result striking at first glance, but keep the prompt to a few sentences and
100
- let the image model choose layout, style, palette, typography, and detail.
101
-
102
- For new interfaces and exploratory redesigns, use this shape as guidance, not
103
- a form to fill mechanically:
104
-
105
- ```text
106
- Create one distinctive [desktop/mobile] [interface] for [product and purpose].
107
- It should feel [desired quality]. Show only [first viewport / primary state /
108
- single screen], with [primary goal] immediately clear. Use the attached image
109
- as loose visual inspiration, not a template. Leave breathing room and choose
110
- the visual language yourself. Fill the canvas without a device or presentation
111
- frame.
112
- ```
113
-
114
- For a structure-preserving reskin, be explicit about what is fixed but leave
115
- visual choices open:
116
-
117
- ```text
118
- Reskin this [desktop/mobile] interface for [product and purpose]. Preserve the
119
- attached source's information architecture, content hierarchy, primary actions,
120
- and interactions. Change only [named visual qualities]. Show the first viewport
121
- or primary screen and choose the palette, typography, spacing, and detail.
122
- Fill the canvas without a device or presentation frame.
123
- ```
124
-
125
- Map corpus reference 1 to candidate A, 2 to B, 3 to C, and 4 to D. Before
126
- writing the prompts, derive one short, visibly grounded direction from each
127
- paired corpus reference—such as airy editorial, tactile retail, cinematic, or
128
- playful illustration. Use that as the candidate's one desired quality, and
129
- make the four directions meaningfully different. Do not describe the whole
130
- reference or prescribe its layout, palette, or techniques.
131
-
132
- Use exactly one image reference per generation; never combine images:
133
-
134
- - New interface or `exploratory-redesign`: each candidate uses its paired
135
- corpus image. The redesign source conditions search but is not also attached
136
- to generation.
137
- - `structure-preserving-reskin`: every candidate uses the redesign source as
138
- its sole image reference. Its paired corpus image contributes only the short
139
- textual direction above; do not attach that corpus image to generation.
140
-
141
- Write one batch manifest in the run directory with four candidates:
142
-
143
- ```json
144
- {
145
- "version": 1,
146
- "projectRoot": "<absolute-project-root>",
147
- "provider": "auto",
148
- "aspect": "landscape",
149
- "referenceMode": "inspiration",
150
- "candidates": [
151
- {
152
- "id": "A",
153
- "prompt": "<short candidate prompt>",
154
- "reference": "<single-generation-reference-path>",
155
- "out": "<run-dir>/candidates/A.png",
156
- "idempotencyKey": "<stable-A-key>"
157
- }
158
- ]
159
- }
160
- ```
161
-
162
- Include A-D, each with its one allowed image reference, unique PNG output, and
163
- stable key. Set the top-level `referenceMode` to `inspiration` for new and
164
- exploratory candidates, or `preserve-structure` when the redesign source is
165
- the sole reference. This is persisted semantic evidence; GPT Image 2 already
166
- processes image inputs at fixed high fidelity, so do not add `input_fidelity`.
167
- Then run one foreground command:
168
-
169
- ```bash
170
- 12ui image generate-batch --manifest <run-dir>/generation.json
171
- ```
172
-
173
- The CLI chooses and preflights one provider, reserves all four attempts, starts
174
- all four provider calls concurrently, waits for every result, and records start
175
- and completion evidence. Do not replace this with four built-in imagegen calls
176
- from one host task: that tool path may queue them serially. Never retry a failed
177
- or ambiguous candidate, switch providers after dispatch, use cached samples, or
178
- leave generation in detached background work.
179
-
180
- ### 3. Select
181
-
182
- Inspect all candidates at original detail. Choose the best eligible direction
183
- for the brief, hierarchy, usability, personality, accessibility, feasibility,
184
- and ability to extend into the rest of the product.
185
-
186
- Treat common model palettes as neutral, not evidence of quality. Neon lime on
187
- dark and orange on light should win only when the brief or paired reference
188
- supports them. Prefer a specific, repeatable visual system over an impressive
189
- hero that gives no direction for later screens. Use corpus metrics only as
190
- provenance or a tie-breaker between visibly strong candidates.
191
-
192
- Write `<run-dir>/selection.json` using
193
- [the selection contract](references/selection-contract.md). Record exact
194
- prompts, original/prepared redesign-source paths and hashes, preserve/change contract, design mode,
195
- reference policy, corpus directions, candidate paths and hashes, winner,
196
- specific rejection reasons, and visible rationale.
197
-
198
- ### 4. Extend and convert
199
-
200
- If the winner represents the complete simple surface, convert only that winner
201
- with `design-convert` and continue to integration.
202
-
203
- When the first image intentionally omitted later page viewports, routes, or app
204
- states, freeze the winner as the sole visual reference for every continuation.
205
- Plan 2-16 useful continuations. Prompt only the state, content, actions, and
206
- route purpose that must change; do not redescribe palette, typography, layout,
207
- style, or visual techniques. Set the continuation batch `referenceMode` to
208
- `inspiration`: the winner supplies the visual system, not a first-viewport
209
- composition to clone. Never attach a corpus image, composite, prior
210
- continuation, or predecessor. If a particular app-state edit must preserve the
211
- winner's exact structure, put only those edits in a separate
212
- `preserve-structure` batch rather than changing the continuation default.
213
-
214
- Submit the winner's base LayerDoc conversion in detached mode, then immediately
215
- run one foreground `12ui image generate-batch` for all continuations so image
216
- generation overlaps the base conversion. Inspect every result before accepting
217
- it. Convert accepted continuation images concurrently with distinct stable
218
- idempotency keys; never retry or replace an ambiguous generation.
219
-
220
- Budget about 4 minutes per conversion at `--model standard`. When a surface also
221
- needs responsive HTML, ask for it in the same command with `--export html`
222
- rather than exporting afterwards — the export then overlaps the conversion and
223
- the pair costs about 5 minutes instead of about 8, at the same price. One
224
- blocking command replaces the create-then-poll-then-export sequence.
225
-
226
- For ordered viewports of one continuous page, use the conversion package API
227
- to preserve page order. Integrate independent web routes, app states, or mobile
228
- screens as separate surfaces. Record the run in `<run-dir>/continuations.json`
229
- using [the continuation contract](references/continuation-contract.md).
230
-
231
- If conversion is interrupted, resume its ID or repeat the exact create request
232
- with the same idempotency key; do not convert another candidate as a shortcut.
233
-
234
- ### 5. Integrate and verify
235
-
236
- Inspect generated files before merging the smallest coherent set into the
237
- project. Preserve routing, components, tokens, accessibility, dependencies,
238
- and unrelated changes. Add the exact copy, interactions, responsive behavior,
239
- later sections, and routes intentionally omitted from the first-viewport prompt
240
- while extending the visual system from the winner and accepted continuations.
241
-
242
- Run focused checks, launch the real interface, exercise interactions, and
243
- compare it with the winner at the source viewport plus representative narrower
244
- and wider widths. Report corpus and generation IDs/evidence, candidate hashes,
245
- selection rationale, conversion ID, integrated files, validation, and visible
246
- differences.
10
+ Code-generating models converge on a narrow band of visual defaults — the
11
+ same fonts, palettes, and layouts across unrelated products — and a model
12
+ cannot see its own convergence from inside it. This skill escapes that:
13
+ corpus-grounded image generation explores genuinely different visual
14
+ directions, and converting the chosen image preserves it with near-pixel
15
+ fidelity, faster and truer than recreating it by hand. Once you have a
16
+ single screen then `12ui branch` extends it into a full page or app with
17
+ consistent, professional quality design. That is why the flow below beats
18
+ designing directly in code, even when coding the interface yourself feels
19
+ quicker.
20
+
21
+ ## 1. Explore four directions
22
+
23
+ 12ui draft --query "<product, audience, surface, goal, personality>"
24
+
25
+ Creates the run directory and prints its path pass it to every later
26
+ command. Searches the corpus for four diverse references and generates one
27
+ one-viewport candidate steered by each, returning immediately.
28
+ `12ui draft status <run-dir>` reports progress (typically ~90s).
29
+ Redesigns: `--redesign-source <png> --mode exploratory|reskin`.
30
+
31
+ ## 2. Select
32
+
33
+ 12ui select <run-dir> --winner B --reason "<rationale>"
34
+
35
+ If the run indicates a recommended candidate, prefer it; overriding it
36
+ requires a stated reason.
37
+
38
+ ## 3. Execute
39
+
40
+ For a single fold, view, or state:
41
+
42
+ 12ui convert <run-dir>/candidates/B.png --export html
43
+
44
+ Runs ~5 minutes with streamed progress.
45
+
46
+ For a full page or a multi-page site or app — the winner is viewport 1 of
47
+ the first page; it needs no separate conversion:
48
+
49
+ 12ui branch execute <run-dir> \
50
+ --concept "<what the rest of the surface must cover>" \
51
+ --scope page|site --convert html
52
+
53
+ The server plans the screens; the command dispatches, downloads, and
54
+ converts one package per page. Returns immediately;
55
+ `12ui branch status <run-dir>` reports progress (~10–25 min typical).
56
+ Per-page HTML lands in `<run-dir>/branch/pages/`.
57
+
58
+ ## 4. Integrate
59
+
60
+ The exported HTML is the page: build the surface around its document —
61
+ copy, routes, state, interactions — rather than replacing it.
@@ -1,130 +1,50 @@
1
1
  ---
2
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."
3
+ description: "Required whenever the deliverable is more than one viewport a
4
+ full page, a multi-route site, or an app with several states: expands one
5
+ approved design into every planned screen and converts each page as one
6
+ ordered package. Not for a single above-the-fold screen."
4
7
  ---
5
8
 
6
- # Design Branch
9
+ # Design branch
7
10
 
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
+ One approved screen fixes the visual system; branching extends it across the
12
+ rest of the surface with consistent, professional quality instead of
13
+ re-deriving the design once per screen. The server plans the screens and
14
+ their dependencies; one command executes the whole plan and keeps every paid
15
+ screen addressable, so a retry never repeats paid work.
11
16
 
12
- ## Start the run
17
+ ## 1. Execute
13
18
 
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`.
19
+ 12ui branch execute <run-dir> \
20
+ --concept "<product, audience, what the rest of the surface must cover>" \
21
+ --scope page|site --convert html
17
22
 
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
- ```
23
+ The run directory is the one `12ui draft` printed; the starting design is
24
+ the candidate `12ui select` recorded there. `--scope page` grows that screen
25
+ into viewports 2..n of its own page; `--scope site` adds sibling routes and
26
+ app states as well. The server plans 2-8 screens (`--max-screens` trims the
27
+ plan). `--convert html` converts each finished page as one ordered package;
28
+ omitting it stops at downloaded PNGs.
29
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.
30
+ To start from something else, pass a fresh directory plus exactly one of
31
+ `--winner-run crt-<id> --winner-slot <slot>` an earlier hosted candidate,
32
+ whose bytes never leave the server or `--winner-image <file>` with a PNG,
33
+ JPEG, or WebP. The starting design is viewport 1 of the first page; it needs
34
+ no separate conversion.
33
35
 
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.
36
+ ## 2. Follow
38
37
 
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`.
38
+ 12ui branch status <run-dir>
45
39
 
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.
40
+ Execute returns immediately and the run continues on its own (~10-25 min
41
+ typical; add `--wait` to block instead). Status reports per-screen progress
42
+ and the next action. `12ui branch resume <run-dir>` continues an interrupted
43
+ run, replaying already-settled screens for free.
49
44
 
50
- ## Read the plan
45
+ ## 3. Collect
51
46
 
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.
47
+ Screens land in `<run-dir>/branch/screens/<slot>.png` and per-page HTML in
48
+ `<run-dir>/branch/pages/<page-id>.html`, materialized when the run reaches a
49
+ terminal state. Each exported page is the page: build the surface around its
50
+ document rather than replacing it.