@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.
- package/README.md +44 -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 +5 -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 +166 -54
- package/dist/cli-image-batch-command.js.map +1 -1
- package/dist/cli-image-batch-materialize.d.ts +27 -0
- package/dist/cli-image-batch-materialize.d.ts.map +1 -0
- package/dist/cli-image-batch-materialize.js +41 -0
- package/dist/cli-image-batch-materialize.js.map +1 -0
- package/dist/cli-image-batch-resume.d.ts +34 -0
- package/dist/cli-image-batch-resume.d.ts.map +1 -0
- package/dist/cli-image-batch-resume.js +175 -0
- package/dist/cli-image-batch-resume.js.map +1 -0
- package/dist/cli-image-command.d.ts.map +1 -1
- package/dist/cli-image-command.js +14 -2
- package/dist/cli-image-command.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-batch-attempt.d.ts +28 -0
- package/dist/image-generation-batch-attempt.d.ts.map +1 -0
- package/dist/image-generation-batch-attempt.js +48 -0
- package/dist/image-generation-batch-attempt.js.map +1 -0
- package/dist/image-generation-completion.d.ts +43 -0
- package/dist/image-generation-completion.d.ts.map +1 -0
- package/dist/image-generation-completion.js +54 -0
- package/dist/image-generation-completion.js.map +1 -0
- package/dist/image-generation-fs.d.ts +3 -0
- package/dist/image-generation-fs.d.ts.map +1 -0
- package/dist/image-generation-fs.js +23 -0
- package/dist/image-generation-fs.js.map +1 -0
- package/dist/image-generation-request.d.ts +13 -3
- package/dist/image-generation-request.d.ts.map +1 -1
- package/dist/image-generation-request.js +21 -19
- package/dist/image-generation-request.js.map +1 -1
- package/dist/image-generation-resume.d.ts +49 -0
- package/dist/image-generation-resume.d.ts.map +1 -0
- package/dist/image-generation-resume.js +96 -0
- package/dist/image-generation-resume.js.map +1 -0
- package/dist/image-generation-run.d.ts +11 -0
- package/dist/image-generation-run.d.ts.map +1 -1
- package/dist/image-generation-run.js +23 -9
- package/dist/image-generation-run.js.map +1 -1
- package/dist/image-generation-staging.d.ts +25 -0
- package/dist/image-generation-staging.d.ts.map +1 -0
- package/dist/image-generation-staging.js +80 -0
- package/dist/image-generation-staging.js.map +1 -0
- 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 +133 -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 +55 -240
- package/skills/design-branch/SKILL.md +36 -116
- package/skills/design-convert/SKILL.md +62 -132
- 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 -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
package/skills/design/SKILL.md
CHANGED
|
@@ -1,246 +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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
12ui
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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: "
|
|
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.
|