@12ui/design 0.2.13 → 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.
- package/README.md +35 -9
- package/dist/branch-client.d.ts +155 -0
- package/dist/branch-client.d.ts.map +1 -0
- package/dist/branch-client.js +179 -0
- package/dist/branch-client.js.map +1 -0
- package/dist/branch-completion.d.ts +37 -0
- package/dist/branch-completion.d.ts.map +1 -0
- package/dist/branch-completion.js +137 -0
- package/dist/branch-completion.js.map +1 -0
- package/dist/branch-dispatch-loop.d.ts +84 -0
- package/dist/branch-dispatch-loop.d.ts.map +1 -0
- package/dist/branch-dispatch-loop.js +206 -0
- package/dist/branch-dispatch-loop.js.map +1 -0
- package/dist/branch-downloads.d.ts +43 -0
- package/dist/branch-downloads.d.ts.map +1 -0
- package/dist/branch-downloads.js +94 -0
- package/dist/branch-downloads.js.map +1 -0
- package/dist/branch-execution-types.d.ts +54 -0
- package/dist/branch-execution-types.d.ts.map +1 -0
- package/dist/branch-execution-types.js +2 -0
- package/dist/branch-execution-types.js.map +1 -0
- package/dist/branch-execution.d.ts +18 -0
- package/dist/branch-execution.d.ts.map +1 -0
- package/dist/branch-execution.js +261 -0
- package/dist/branch-execution.js.map +1 -0
- package/dist/branch-identity.d.ts +71 -0
- package/dist/branch-identity.d.ts.map +1 -0
- package/dist/branch-identity.js +72 -0
- package/dist/branch-identity.js.map +1 -0
- package/dist/branch-materialize.d.ts +22 -0
- package/dist/branch-materialize.d.ts.map +1 -0
- package/dist/branch-materialize.js +47 -0
- package/dist/branch-materialize.js.map +1 -0
- package/dist/branch-page-conversion.d.ts +39 -0
- package/dist/branch-page-conversion.d.ts.map +1 -0
- package/dist/branch-page-conversion.js +206 -0
- package/dist/branch-page-conversion.js.map +1 -0
- package/dist/branch-plan.d.ts +63 -0
- package/dist/branch-plan.d.ts.map +1 -0
- package/dist/branch-plan.js +95 -0
- package/dist/branch-plan.js.map +1 -0
- package/dist/branch-progress.d.ts +75 -0
- package/dist/branch-progress.d.ts.map +1 -0
- package/dist/branch-progress.js +159 -0
- package/dist/branch-progress.js.map +1 -0
- package/dist/branch-run-record.d.ts +153 -0
- package/dist/branch-run-record.d.ts.map +1 -0
- package/dist/branch-run-record.js +94 -0
- package/dist/branch-run-record.js.map +1 -0
- package/dist/branch-schedule.d.ts +74 -0
- package/dist/branch-schedule.d.ts.map +1 -0
- package/dist/branch-schedule.js +130 -0
- package/dist/branch-schedule.js.map +1 -0
- package/dist/branch-status.d.ts +11 -0
- package/dist/branch-status.d.ts.map +1 -0
- package/dist/branch-status.js +115 -0
- package/dist/branch-status.js.map +1 -0
- package/dist/branch-viewport-normalization.d.ts +74 -0
- package/dist/branch-viewport-normalization.d.ts.map +1 -0
- package/dist/branch-viewport-normalization.js +120 -0
- package/dist/branch-viewport-normalization.js.map +1 -0
- package/dist/cli-arguments.d.ts.map +1 -1
- package/dist/cli-arguments.js +4 -0
- package/dist/cli-arguments.js.map +1 -1
- package/dist/cli-branch-command.d.ts +46 -0
- package/dist/cli-branch-command.d.ts.map +1 -0
- package/dist/cli-branch-command.js +426 -0
- package/dist/cli-branch-command.js.map +1 -0
- package/dist/cli-capabilities.d.ts +28 -0
- package/dist/cli-capabilities.d.ts.map +1 -1
- package/dist/cli-capabilities.js +29 -1
- package/dist/cli-capabilities.js.map +1 -1
- package/dist/cli-create-command.d.ts +21 -0
- package/dist/cli-create-command.d.ts.map +1 -0
- package/dist/cli-create-command.js +319 -0
- package/dist/cli-create-command.js.map +1 -0
- package/dist/cli-detach.d.ts +62 -0
- package/dist/cli-detach.d.ts.map +1 -0
- package/dist/cli-detach.js +123 -0
- package/dist/cli-detach.js.map +1 -0
- package/dist/cli-draft-command.d.ts +63 -0
- package/dist/cli-draft-command.d.ts.map +1 -0
- package/dist/cli-draft-command.js +220 -0
- package/dist/cli-draft-command.js.map +1 -0
- package/dist/cli-export-command.d.ts.map +1 -1
- package/dist/cli-export-command.js +2 -3
- package/dist/cli-export-command.js.map +1 -1
- package/dist/cli-image-batch-command.d.ts +21 -0
- package/dist/cli-image-batch-command.d.ts.map +1 -1
- package/dist/cli-image-batch-command.js +65 -4
- package/dist/cli-image-batch-command.js.map +1 -1
- package/dist/cli-image-batch-resume.d.ts +7 -0
- package/dist/cli-image-batch-resume.d.ts.map +1 -1
- package/dist/cli-image-batch-resume.js +19 -2
- package/dist/cli-image-batch-resume.js.map +1 -1
- package/dist/cli-package-command.d.ts +18 -0
- package/dist/cli-package-command.d.ts.map +1 -0
- package/dist/cli-package-command.js +112 -0
- package/dist/cli-package-command.js.map +1 -0
- package/dist/cli-progress.d.ts +61 -0
- package/dist/cli-progress.d.ts.map +1 -1
- package/dist/cli-progress.js +53 -0
- package/dist/cli-progress.js.map +1 -1
- package/dist/cli-select-command.d.ts +12 -0
- package/dist/cli-select-command.d.ts.map +1 -0
- package/dist/cli-select-command.js +66 -0
- package/dist/cli-select-command.js.map +1 -0
- package/dist/cli.js +140 -7
- package/dist/cli.js.map +1 -1
- package/dist/create-identity.d.ts +25 -0
- package/dist/create-identity.d.ts.map +1 -0
- package/dist/create-identity.js +0 -0
- package/dist/create-identity.js.map +1 -0
- package/dist/draft-identity.d.ts +30 -0
- package/dist/draft-identity.d.ts.map +1 -0
- package/dist/draft-identity.js +0 -0
- package/dist/draft-identity.js.map +1 -0
- package/dist/draft-prompts.d.ts +35 -0
- package/dist/draft-prompts.d.ts.map +1 -0
- package/dist/draft-prompts.js +51 -0
- package/dist/draft-prompts.js.map +1 -0
- package/dist/draft-run.d.ts +32 -0
- package/dist/draft-run.d.ts.map +1 -0
- package/dist/draft-run.js +152 -0
- package/dist/draft-run.js.map +1 -0
- package/dist/draft-workspace.d.ts +90 -0
- package/dist/draft-workspace.d.ts.map +1 -0
- package/dist/draft-workspace.js +64 -0
- package/dist/draft-workspace.js.map +1 -0
- package/dist/image-batch-status.d.ts +42 -0
- package/dist/image-batch-status.d.ts.map +1 -0
- package/dist/image-batch-status.js +142 -0
- package/dist/image-batch-status.js.map +1 -0
- package/dist/image-dimensions.d.ts +12 -0
- package/dist/image-dimensions.d.ts.map +1 -0
- package/dist/image-dimensions.js +14 -0
- package/dist/image-dimensions.js.map +1 -0
- package/dist/image-generation-resume.d.ts +13 -0
- package/dist/image-generation-resume.d.ts.map +1 -1
- package/dist/image-generation-resume.js +13 -0
- package/dist/image-generation-resume.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/legacy-skill-catalog.d.ts.map +1 -1
- package/dist/legacy-skill-catalog.js +115 -0
- package/dist/legacy-skill-catalog.js.map +1 -1
- package/dist/package-manifest-file.d.ts +21 -0
- package/dist/package-manifest-file.d.ts.map +1 -0
- package/dist/package-manifest-file.js +119 -0
- package/dist/package-manifest-file.js.map +1 -0
- package/dist/package-manifest-template.d.ts +23 -0
- package/dist/package-manifest-template.d.ts.map +1 -0
- package/dist/package-manifest-template.js +60 -0
- package/dist/package-manifest-template.js.map +1 -0
- package/dist/package-submission.d.ts +103 -0
- package/dist/package-submission.d.ts.map +1 -0
- package/dist/package-submission.js +173 -0
- package/dist/package-submission.js.map +1 -0
- package/dist/selection-record.d.ts +95 -0
- package/dist/selection-record.d.ts.map +1 -0
- package/dist/selection-record.js +121 -0
- package/dist/selection-record.js.map +1 -0
- package/package.json +1 -1
- package/skills/design/SKILL.md +40 -266
- package/skills/design-branch/SKILL.md +36 -116
- package/skills/design-convert/SKILL.md +62 -148
- package/skills/design-draft/SKILL.md +71 -135
- package/skills/design-search/SKILL.md +29 -78
- package/skills/design/references/continuation-contract.md +0 -60
- package/skills/design/references/selection-contract.md +0 -112
|
@@ -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
package/skills/design/SKILL.md
CHANGED
|
@@ -1,287 +1,61 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: design
|
|
3
|
-
description: "
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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.
|
|
13
20
|
|
|
14
|
-
##
|
|
21
|
+
## 1. Explore — four directions
|
|
15
22
|
|
|
16
|
-
|
|
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.
|
|
23
|
+
12ui draft --query "<product, audience, surface, goal, personality>"
|
|
28
24
|
|
|
29
|
-
|
|
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
30
|
|
|
31
|
-
|
|
31
|
+
## 2. Select
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
components, assets, conventions, validation commands, and existing user
|
|
35
|
-
changes. Create the run directory under the system temporary directory.
|
|
33
|
+
12ui select <run-dir> --winner B --reason "<rationale>"
|
|
36
34
|
|
|
37
|
-
If
|
|
38
|
-
|
|
35
|
+
If the run indicates a recommended candidate, prefer it; overriding it
|
|
36
|
+
requires a stated reason.
|
|
39
37
|
|
|
40
|
-
|
|
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.
|
|
38
|
+
## 3. Execute
|
|
44
39
|
|
|
45
|
-
|
|
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.
|
|
40
|
+
For a single fold, view, or state:
|
|
49
41
|
|
|
50
|
-
|
|
42
|
+
12ui convert <run-dir>/candidates/B.png --export html
|
|
51
43
|
|
|
52
|
-
|
|
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
|
-
```
|
|
44
|
+
Runs ~5 minutes with streamed progress.
|
|
59
45
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
Balanced set and recording why it failed the brief:
|
|
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:
|
|
63
48
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
repetitive to author four meaningfully distinct directions.
|
|
49
|
+
12ui branch execute <run-dir> \
|
|
50
|
+
--concept "<what the rest of the surface must cover>" \
|
|
51
|
+
--scope page|site --convert html
|
|
68
52
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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/`.
|
|
73
57
|
|
|
74
|
-
|
|
58
|
+
## 4. Integrate
|
|
75
59
|
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
Expect about **90 seconds** of blocking for four candidates. The command has not
|
|
181
|
-
hung: never kill it, never background it, and never list the candidates
|
|
182
|
-
directory to decide whether it worked. Nothing lands there until the batch is
|
|
183
|
-
terminal, and then everything appears at once — the four PNGs, their attempt
|
|
184
|
-
evidence, and `<run-dir>/candidates/generation.complete.json`. Poll that
|
|
185
|
-
sentinel if you must poll anything. It is written only at a terminal state and
|
|
186
|
-
records each candidate's status, sha256, and byte count; its absence means
|
|
187
|
-
still running, never failed.
|
|
188
|
-
|
|
189
|
-
If the command was interrupted, re-run the identical command with `--resume`. A
|
|
190
|
-
resume delivers candidates that were already generated and re-requests only
|
|
191
|
-
those the provider provably never billed, so it can never buy a candidate
|
|
192
|
-
twice. It refuses a batch that already completed, and its refusal names the
|
|
193
|
-
candidates already on disk — read those rather than generating again.
|
|
194
|
-
|
|
195
|
-
### 3. Select
|
|
196
|
-
|
|
197
|
-
Inspect all candidates at original detail. Looking at them is not optional: your
|
|
198
|
-
judgment is the channel through which anything the run could not compute gets
|
|
199
|
-
into the decision.
|
|
200
|
-
|
|
201
|
-
If the run indicates a recommended candidate, prefer it. Overriding the
|
|
202
|
-
recommendation is legitimate and expected when the context warrants — an
|
|
203
|
-
explicit user preference, a brief or steering directive the recommendation could
|
|
204
|
-
not see, or a visible defect in the recommended image are all good reasons — and
|
|
205
|
-
an override must state its reason. If no recommendation is indicated, select on
|
|
206
|
-
the criteria below as usual.
|
|
207
|
-
|
|
208
|
-
Choose the best eligible direction for the brief, hierarchy, usability,
|
|
209
|
-
personality, accessibility, feasibility, and ability to extend into the rest of
|
|
210
|
-
the product.
|
|
211
|
-
|
|
212
|
-
Treat common model palettes as neutral, not evidence of quality. Neon lime on
|
|
213
|
-
dark and orange on light should win only when the brief or paired reference
|
|
214
|
-
supports them. Prefer a specific, repeatable visual system over an impressive
|
|
215
|
-
hero that gives no direction for later screens. Use corpus metrics only as
|
|
216
|
-
provenance or a tie-breaker between visibly strong candidates.
|
|
217
|
-
|
|
218
|
-
Write `<run-dir>/selection.json` using
|
|
219
|
-
[the selection contract](references/selection-contract.md). Record exact
|
|
220
|
-
prompts, original/prepared redesign-source paths and hashes, preserve/change contract, design mode,
|
|
221
|
-
reference policy, corpus directions, candidate paths and hashes, winner,
|
|
222
|
-
specific rejection reasons, and visible rationale. Record whether the
|
|
223
|
-
recommendation was followed or overridden, and for an override the reason. When
|
|
224
|
-
the flow also writes a `design-run.json`, record the same pair there, the reason
|
|
225
|
-
under `selection_override_reason`, alongside its existing selection fields.
|
|
226
|
-
|
|
227
|
-
### 4. Extend and convert
|
|
228
|
-
|
|
229
|
-
If the winner represents the complete simple surface, convert only that winner
|
|
230
|
-
with `design-convert` and continue to integration.
|
|
231
|
-
|
|
232
|
-
When the first image intentionally omitted later page viewports, routes, or app
|
|
233
|
-
states, freeze the winner as the sole visual reference for every continuation.
|
|
234
|
-
Plan 2-16 useful continuations. Prompt only the state, content, actions, and
|
|
235
|
-
route purpose that must change; do not redescribe palette, typography, layout,
|
|
236
|
-
style, or visual techniques. Set the continuation batch `referenceMode` to
|
|
237
|
-
`inspiration`: the winner supplies the visual system, not a first-viewport
|
|
238
|
-
composition to clone. Never attach a corpus image, composite, prior
|
|
239
|
-
continuation, or predecessor. If a particular app-state edit must preserve the
|
|
240
|
-
winner's exact structure, put only those edits in a separate
|
|
241
|
-
`preserve-structure` batch rather than changing the continuation default.
|
|
242
|
-
|
|
243
|
-
Submit the winner's base LayerDoc conversion in detached mode, then immediately
|
|
244
|
-
run one foreground `12ui image generate-batch` for all continuations so image
|
|
245
|
-
generation overlaps the base conversion. Inspect every result before accepting
|
|
246
|
-
it. Convert accepted continuation images concurrently with distinct stable
|
|
247
|
-
idempotency keys; never retry or replace an ambiguous generation.
|
|
248
|
-
|
|
249
|
-
Budget about 4 minutes per conversion at `--model standard`. When a surface also
|
|
250
|
-
needs responsive HTML, ask for it in the same command with `--export html`
|
|
251
|
-
rather than exporting afterwards — the export then overlaps the conversion and
|
|
252
|
-
the pair costs about 5 minutes instead of about 8, at the same price. One
|
|
253
|
-
blocking command replaces the create-then-poll-then-export sequence. Both
|
|
254
|
-
commands block for those durations and stream progress; neither has hung.
|
|
255
|
-
|
|
256
|
-
The exported HTML is the deliverable page. Adapt and compose it: keep its
|
|
257
|
-
document, structure, classes, and anchor bindings, and build the surface around
|
|
258
|
-
that document — routing, real copy, state, interactions, and the later sections
|
|
259
|
-
the first-viewport prompt deliberately omitted. Do not mine the export for its
|
|
260
|
-
images and re-author the markup: that discards the design you just chose and
|
|
261
|
-
paid to convert, and the page lands back on generic defaults. Fix defects in the
|
|
262
|
-
export's own markup. Rebuild from scratch only when the export cannot carry the
|
|
263
|
-
surface at all, and report it explicitly when you do.
|
|
264
|
-
|
|
265
|
-
For ordered viewports of one continuous page, use the conversion package API
|
|
266
|
-
to preserve page order. Integrate independent web routes, app states, or mobile
|
|
267
|
-
screens as separate surfaces. Record the run in `<run-dir>/continuations.json`
|
|
268
|
-
using [the continuation contract](references/continuation-contract.md).
|
|
269
|
-
|
|
270
|
-
If conversion is interrupted, resume its ID or repeat the exact create request
|
|
271
|
-
with the same idempotency key; do not convert another candidate as a shortcut.
|
|
272
|
-
|
|
273
|
-
### 5. Integrate and verify
|
|
274
|
-
|
|
275
|
-
Inspect generated files before merging the smallest coherent set into the
|
|
276
|
-
project. Preserve routing, components, tokens, accessibility, dependencies,
|
|
277
|
-
and unrelated changes. The converted export goes in as the page; integration is
|
|
278
|
-
adapting it to the project, not replacing it. Add the exact copy, interactions,
|
|
279
|
-
responsive behavior, later sections, and routes intentionally omitted from the
|
|
280
|
-
first-viewport prompt while extending the visual system from the winner and
|
|
281
|
-
accepted continuations.
|
|
282
|
-
|
|
283
|
-
Run focused checks, launch the real interface, exercise interactions, and
|
|
284
|
-
compare it with the winner at the source viewport plus representative narrower
|
|
285
|
-
and wider widths. Report corpus and generation IDs/evidence, candidate hashes,
|
|
286
|
-
selection rationale, conversion ID, integrated files, validation, and visible
|
|
287
|
-
differences.
|
|
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: "
|
|
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
|
|
9
|
+
# Design branch
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
##
|
|
17
|
+
## 1. Execute
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
##
|
|
45
|
+
## 3. Collect
|
|
51
46
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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.
|