@12ui/design 0.2.74 → 0.2.76
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 +126 -116
- package/SKILL.md +33 -28
- package/dist/cli-arguments.d.ts.map +1 -1
- package/dist/cli-arguments.js +21 -7
- package/dist/cli-arguments.js.map +1 -1
- package/dist/cli-capabilities.d.ts +3 -2
- package/dist/cli-capabilities.d.ts.map +1 -1
- package/dist/cli-capabilities.js +2 -1
- package/dist/cli-capabilities.js.map +1 -1
- package/dist/cli-codex-readiness.d.ts +19 -6
- package/dist/cli-codex-readiness.d.ts.map +1 -1
- package/dist/cli-codex-readiness.js +36 -16
- package/dist/cli-codex-readiness.js.map +1 -1
- package/dist/cli-help/design.d.ts +9 -2
- package/dist/cli-help/design.d.ts.map +1 -1
- package/dist/cli-help/design.js +17 -2
- package/dist/cli-help/design.js.map +1 -1
- package/dist/cli-help/index.d.ts +26 -9
- package/dist/cli-help/index.d.ts.map +1 -1
- package/dist/cli-help/scene.d.ts +15 -5
- package/dist/cli-help/scene.d.ts.map +1 -1
- package/dist/cli-help/scene.js +44 -0
- package/dist/cli-help/scene.js.map +1 -1
- package/dist/cli-help/workflow.d.ts +2 -2
- package/dist/cli-help/workflow.d.ts.map +1 -1
- package/dist/cli-help/workflow.js +4 -3
- package/dist/cli-help/workflow.js.map +1 -1
- package/dist/cli-run.d.ts.map +1 -1
- package/dist/cli-run.js +6 -0
- package/dist/cli-run.js.map +1 -1
- package/dist/cli-scene-command.d.ts.map +1 -1
- package/dist/cli-scene-command.js +39 -6
- package/dist/cli-scene-command.js.map +1 -1
- package/dist/cli-usage.d.ts.map +1 -1
- package/dist/cli-usage.js +9 -6
- package/dist/cli-usage.js.map +1 -1
- package/dist/cli-workspace-command.js +1 -1
- package/dist/cli-workspace-command.js.map +1 -1
- package/dist/cli-workspace-draw.d.ts +23 -0
- package/dist/cli-workspace-draw.d.ts.map +1 -0
- package/dist/cli-workspace-draw.js +97 -0
- package/dist/cli-workspace-draw.js.map +1 -0
- package/dist/codex-binary.d.ts +20 -0
- package/dist/codex-binary.d.ts.map +1 -0
- package/dist/codex-binary.js +46 -0
- package/dist/codex-binary.js.map +1 -0
- package/dist/legacy-skill-catalog.d.ts.map +1 -1
- package/dist/legacy-skill-catalog.js +26 -2
- package/dist/legacy-skill-catalog.js.map +1 -1
- package/dist/mcp-slate-command.d.ts +9 -0
- package/dist/mcp-slate-command.d.ts.map +1 -1
- package/dist/mcp-slate-command.js +19 -5
- package/dist/mcp-slate-command.js.map +1 -1
- package/dist/mcp-workflow-tools.js +3 -3
- package/dist/mcp-workflow-tools.js.map +1 -1
- package/dist/scene/camera-diagnostics.d.ts +61 -0
- package/dist/scene/camera-diagnostics.d.ts.map +1 -0
- package/dist/scene/camera-diagnostics.js +166 -0
- package/dist/scene/camera-diagnostics.js.map +1 -0
- package/dist/scene/camera-solve.d.ts +2 -0
- package/dist/scene/camera-solve.d.ts.map +1 -1
- package/dist/scene/camera-solve.js +59 -42
- package/dist/scene/camera-solve.js.map +1 -1
- package/dist/scene/capture.d.ts +24 -0
- package/dist/scene/capture.d.ts.map +1 -1
- package/dist/scene/capture.js +53 -2
- package/dist/scene/capture.js.map +1 -1
- package/dist/scene/convert-run.d.ts +30 -0
- package/dist/scene/convert-run.d.ts.map +1 -0
- package/dist/scene/convert-run.js +135 -0
- package/dist/scene/convert-run.js.map +1 -0
- package/dist/scene/media-query.d.ts +21 -0
- package/dist/scene/media-query.d.ts.map +1 -0
- package/dist/scene/media-query.js +208 -0
- package/dist/scene/media-query.js.map +1 -0
- package/dist/scene/page-css.d.ts +38 -0
- package/dist/scene/page-css.d.ts.map +1 -0
- package/dist/scene/page-css.js +210 -0
- package/dist/scene/page-css.js.map +1 -0
- package/dist/scene/page-images.d.ts +33 -0
- package/dist/scene/page-images.d.ts.map +1 -0
- package/dist/scene/page-images.js +53 -0
- package/dist/scene/page-images.js.map +1 -0
- package/dist/scene/page-merge.d.ts +41 -0
- package/dist/scene/page-merge.d.ts.map +1 -0
- package/dist/scene/page-merge.js +197 -0
- package/dist/scene/page-merge.js.map +1 -0
- package/dist/scene/responsive-bands.d.ts +19 -0
- package/dist/scene/responsive-bands.d.ts.map +1 -0
- package/dist/scene/responsive-bands.js +25 -0
- package/dist/scene/responsive-bands.js.map +1 -0
- package/dist/scene/scene-index.d.ts +10 -0
- package/dist/scene/scene-index.d.ts.map +1 -0
- package/dist/scene/scene-index.js +43 -0
- package/dist/scene/scene-index.js.map +1 -0
- package/dist/scene/scene-merge.d.ts +29 -0
- package/dist/scene/scene-merge.d.ts.map +1 -0
- package/dist/scene/scene-merge.js +130 -0
- package/dist/scene/scene-merge.js.map +1 -0
- package/dist/scene/scene-verbs.d.ts +1 -1
- package/dist/scene/scene-verbs.d.ts.map +1 -1
- package/dist/scene/scene-verbs.js +1 -1
- package/dist/scene/scene-verbs.js.map +1 -1
- package/dist/scene/serve-detach.d.ts +23 -0
- package/dist/scene/serve-detach.d.ts.map +1 -0
- package/dist/scene/serve-detach.js +92 -0
- package/dist/scene/serve-detach.js.map +1 -0
- package/dist/scene/static-server.d.ts +2 -0
- package/dist/scene/static-server.d.ts.map +1 -1
- package/dist/scene/static-server.js +3 -0
- package/dist/scene/static-server.js.map +1 -1
- package/dist/scene/symmetric-eigen.d.ts +12 -0
- package/dist/scene/symmetric-eigen.d.ts.map +1 -0
- package/dist/scene/symmetric-eigen.js +43 -0
- package/dist/scene/symmetric-eigen.js.map +1 -0
- package/dist/slate-image-executor.js +1 -1
- package/dist/slate-image-executor.js.map +1 -1
- package/dist/slate-local-image.d.ts +3 -6
- package/dist/slate-local-image.d.ts.map +1 -1
- package/dist/slate-local-image.js +2 -18
- package/dist/slate-local-image.js.map +1 -1
- package/dist/workflow/adapter-12ui.d.ts.map +1 -1
- package/dist/workflow/adapter-12ui.js +3 -5
- package/dist/workflow/adapter-12ui.js.map +1 -1
- package/dist/workflow/providers.d.ts.map +1 -1
- package/dist/workflow/providers.js +5 -2
- package/dist/workflow/providers.js.map +1 -1
- package/dist/workflow/recipes.d.ts +1 -2
- package/dist/workflow/recipes.d.ts.map +1 -1
- package/dist/workflow/recipes.js +6 -18
- package/dist/workflow/recipes.js.map +1 -1
- package/dist/workflow/routing.d.ts.map +1 -1
- package/dist/workflow/routing.js +3 -1
- package/dist/workflow/routing.js.map +1 -1
- package/dist/workflow/types.d.ts +7 -0
- package/dist/workflow/types.d.ts.map +1 -1
- package/dist/workflow/types.js +7 -0
- package/dist/workflow/types.js.map +1 -1
- package/dist/workspace-draw-client.d.ts +69 -0
- package/dist/workspace-draw-client.d.ts.map +1 -0
- package/dist/workspace-draw-client.js +193 -0
- package/dist/workspace-draw-client.js.map +1 -0
- package/dist/workspace-draw-codex.d.ts +49 -0
- package/dist/workspace-draw-codex.d.ts.map +1 -0
- package/dist/workspace-draw-codex.js +89 -0
- package/dist/workspace-draw-codex.js.map +1 -0
- package/dist/workspace-draw-engine.d.ts +39 -0
- package/dist/workspace-draw-engine.d.ts.map +1 -0
- package/dist/workspace-draw-engine.js +72 -0
- package/dist/workspace-draw-engine.js.map +1 -0
- package/dist/workspace-draw-messages.d.ts +45 -0
- package/dist/workspace-draw-messages.d.ts.map +1 -0
- package/dist/workspace-draw-messages.js +47 -0
- package/dist/workspace-draw-messages.js.map +1 -0
- package/dist/workspace-draw-run.d.ts +43 -0
- package/dist/workspace-draw-run.d.ts.map +1 -0
- package/dist/workspace-draw-run.js +328 -0
- package/dist/workspace-draw-run.js.map +1 -0
- package/dist/workspace-draw-store.d.ts +23 -0
- package/dist/workspace-draw-store.d.ts.map +1 -0
- package/dist/workspace-draw-store.js +65 -0
- package/dist/workspace-draw-store.js.map +1 -0
- package/dist/workspace-draw-types.d.ts +121 -0
- package/dist/workspace-draw-types.d.ts.map +1 -0
- package/dist/workspace-draw-types.js +21 -0
- package/dist/workspace-draw-types.js.map +1 -0
- package/open-design.json +2 -2
- package/package.json +2 -2
- package/runtime/codex-conversion/src/codex/home.mjs +43 -14
- package/runtime/codex-conversion/src/images/native-files.mjs +20 -0
- package/runtime/codex-conversion/src/images/native-invoke.mjs +5 -2
- package/runtime/codex-conversion/src/images/native-records.mjs +75 -3
- package/runtime/codex-conversion/src/images/native.mjs +7 -4
- package/skills/12ui-design/SKILL.md +79 -19
- package/skills/12ui-design/agents/openai.yaml +2 -0
- package/skills/12ui-design/improve.md +1 -5
- package/skills/12ui-design/inspire.md +5 -8
- package/skills/12ui-design/outputs.md +2 -23
- package/skills/12ui-design/scene.md +27 -156
- package/skills/12ui-design/session.md +0 -161
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shapes `12ui workspace draw` reads and writes: the frozen draw plan design.12ui.com serves (interface I1,
|
|
3
|
+
* `GET /api/v1/slate/ops/{opId}/plan`), and the command's own outcome codes and run record (interface I2).
|
|
4
|
+
*/
|
|
5
|
+
export type PlanImageName = 'parent' | 'annotated' | `ref-${number}`;
|
|
6
|
+
export type SlatePlanImage = {
|
|
7
|
+
name: PlanImageName;
|
|
8
|
+
role: 'parent' | 'annotated' | 'reference';
|
|
9
|
+
referenceId: string | null;
|
|
10
|
+
versionId: string | null;
|
|
11
|
+
};
|
|
12
|
+
export type SlatePlanOption = {
|
|
13
|
+
key: string;
|
|
14
|
+
callId: string;
|
|
15
|
+
prompt: string;
|
|
16
|
+
promptSha256: string;
|
|
17
|
+
images: SlatePlanImage[];
|
|
18
|
+
frame: {
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
};
|
|
22
|
+
noReferenceReason: 'search_rate_limited' | 'search_unavailable' | 'too_few_fresh' | 'no_query' | null;
|
|
23
|
+
state: 'pending' | 'filled' | 'failed';
|
|
24
|
+
versionId: string | null;
|
|
25
|
+
label: string | null;
|
|
26
|
+
failure: string | null;
|
|
27
|
+
};
|
|
28
|
+
export type SlateDrawPlan = {
|
|
29
|
+
schema: '12ui.slate.plan/1';
|
|
30
|
+
workspace: string;
|
|
31
|
+
opId: string;
|
|
32
|
+
kind: 'round' | 'edit';
|
|
33
|
+
mode: 'root' | 'new' | 'like' | 'edit';
|
|
34
|
+
promptRevision: string;
|
|
35
|
+
planDigest: string;
|
|
36
|
+
state: 'running' | 'succeeded' | 'failed' | 'interrupted';
|
|
37
|
+
options: SlatePlanOption[];
|
|
38
|
+
};
|
|
39
|
+
export declare const PLAN_SCHEMA = "12ui.slate.plan/1";
|
|
40
|
+
/** The `code` field of the command's JSON line, and the exit code each one carries (I2). */
|
|
41
|
+
export declare const DRAW_EXIT_CODES: {
|
|
42
|
+
readonly done: 0;
|
|
43
|
+
readonly replayed: 0;
|
|
44
|
+
readonly partial: 1;
|
|
45
|
+
readonly failed: 1;
|
|
46
|
+
readonly token_invalid: 2;
|
|
47
|
+
readonly unknown_op: 2;
|
|
48
|
+
readonly op_in_progress: 2;
|
|
49
|
+
readonly usage: 2;
|
|
50
|
+
readonly needs_escalation: 3;
|
|
51
|
+
readonly no_engine: 4;
|
|
52
|
+
readonly cli_outdated: 5;
|
|
53
|
+
};
|
|
54
|
+
export type DrawCode = keyof typeof DRAW_EXIT_CODES;
|
|
55
|
+
/** The one engine of this release (decision D2-B): drawing on 12ui needs a 12ui sign-in and is not part of the command. */
|
|
56
|
+
export type DrawEngine = 'codex';
|
|
57
|
+
export type DrawImageRecord = {
|
|
58
|
+
name: string;
|
|
59
|
+
referenceId: string | null;
|
|
60
|
+
versionId: string | null;
|
|
61
|
+
sha256: string;
|
|
62
|
+
mimeType: string;
|
|
63
|
+
};
|
|
64
|
+
export type DrawOptionCodex = {
|
|
65
|
+
callDir: string;
|
|
66
|
+
tempHome: string;
|
|
67
|
+
tempHomeRemoved: boolean;
|
|
68
|
+
rollouts: string[];
|
|
69
|
+
imageGenCalls: number;
|
|
70
|
+
promptVerbatim: boolean | null;
|
|
71
|
+
revisedPrompt: string | null;
|
|
72
|
+
};
|
|
73
|
+
export type DrawOptionRecord = {
|
|
74
|
+
key: string;
|
|
75
|
+
callId: string;
|
|
76
|
+
/** Null when Codex could not draw and nothing was drawn (the option's failure was pushed). */
|
|
77
|
+
engine: DrawEngine | null;
|
|
78
|
+
prompt: string;
|
|
79
|
+
promptSha256: string;
|
|
80
|
+
images: DrawImageRecord[];
|
|
81
|
+
frame: {
|
|
82
|
+
width: number;
|
|
83
|
+
height: number;
|
|
84
|
+
};
|
|
85
|
+
startedAt: string;
|
|
86
|
+
finishedAt: string;
|
|
87
|
+
state: 'filled' | 'failed' | 'replayed';
|
|
88
|
+
failure: string | null;
|
|
89
|
+
versionId: string | null;
|
|
90
|
+
label: string | null;
|
|
91
|
+
codex?: DrawOptionCodex;
|
|
92
|
+
};
|
|
93
|
+
export type DrawRecordCodex = {
|
|
94
|
+
binary: string;
|
|
95
|
+
version: string;
|
|
96
|
+
home: string;
|
|
97
|
+
threadId: string | null;
|
|
98
|
+
sameHomeRollout: string | null;
|
|
99
|
+
};
|
|
100
|
+
export type DrawRecord = {
|
|
101
|
+
schema: '12ui.workspace.draw-record/1';
|
|
102
|
+
opId: string;
|
|
103
|
+
origin: string;
|
|
104
|
+
cliVersion: string;
|
|
105
|
+
/** Null when Codex could not draw here: the run spent nothing and pushed each pending option's failure. */
|
|
106
|
+
engine: DrawEngine | null;
|
|
107
|
+
engineReason: string;
|
|
108
|
+
codex: DrawRecordCodex | null;
|
|
109
|
+
plan: {
|
|
110
|
+
planDigest: string;
|
|
111
|
+
promptRevision: string;
|
|
112
|
+
kind: string;
|
|
113
|
+
mode: string;
|
|
114
|
+
};
|
|
115
|
+
startedAt: string;
|
|
116
|
+
finishedAt: string;
|
|
117
|
+
wallMs: number;
|
|
118
|
+
options: DrawOptionRecord[];
|
|
119
|
+
};
|
|
120
|
+
export declare const RECORD_SCHEMA = "12ui.workspace.draw-record/1";
|
|
121
|
+
//# sourceMappingURL=workspace-draw-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-draw-types.d.ts","sourceRoot":"","sources":["../src/workspace-draw-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shapes `12ui workspace draw` reads and writes: the frozen draw plan design.12ui.com serves (interface I1,
|
|
3
|
+
* `GET /api/v1/slate/ops/{opId}/plan`), and the command's own outcome codes and run record (interface I2).
|
|
4
|
+
*/
|
|
5
|
+
export const PLAN_SCHEMA = '12ui.slate.plan/1';
|
|
6
|
+
/** The `code` field of the command's JSON line, and the exit code each one carries (I2). */
|
|
7
|
+
export const DRAW_EXIT_CODES = {
|
|
8
|
+
done: 0,
|
|
9
|
+
replayed: 0,
|
|
10
|
+
partial: 1,
|
|
11
|
+
failed: 1,
|
|
12
|
+
token_invalid: 2,
|
|
13
|
+
unknown_op: 2,
|
|
14
|
+
op_in_progress: 2,
|
|
15
|
+
usage: 2,
|
|
16
|
+
needs_escalation: 3,
|
|
17
|
+
no_engine: 4,
|
|
18
|
+
cli_outdated: 5,
|
|
19
|
+
};
|
|
20
|
+
export const RECORD_SCHEMA = '12ui.workspace.draw-record/1';
|
|
21
|
+
//# sourceMappingURL=workspace-draw-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-draw-types.js","sourceRoot":"","sources":["../src/workspace-draw-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAqCH,MAAM,CAAC,MAAM,WAAW,GAAG,mBAAmB,CAAC;AAE/C,4FAA4F;AAC5F,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,CAAC;IACP,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,CAAC;IACT,aAAa,EAAE,CAAC;IAChB,UAAU,EAAE,CAAC;IACb,cAAc,EAAE,CAAC;IACjB,KAAK,EAAE,CAAC;IACR,gBAAgB,EAAE,CAAC;IACnB,SAAS,EAAE,CAAC;IACZ,YAAY,EAAE,CAAC;CACP,CAAC;AAsDX,MAAM,CAAC,MAAM,aAAa,GAAG,8BAA8B,CAAC"}
|
package/open-design.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"specVersion": "1.0.0",
|
|
4
4
|
"name": "12ui-design",
|
|
5
5
|
"title": "12UI Design",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.76",
|
|
7
7
|
"description": "Explore corpus-grounded interface directions, choose one, and convert it into production-ready responsive or native artifacts with 12UI.",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Just Every",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"command": "npx",
|
|
50
50
|
"args": [
|
|
51
51
|
"-y",
|
|
52
|
-
"@12ui/design@0.2.
|
|
52
|
+
"@12ui/design@0.2.76",
|
|
53
53
|
"mcp"
|
|
54
54
|
]
|
|
55
55
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@12ui/design",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.76",
|
|
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",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"test": "node ../../scripts/codex-runtime-bundle.mjs && node ../../scripts/sync-improve-core.mjs && vitest",
|
|
27
27
|
"test:run": "node ../../scripts/codex-runtime-bundle.mjs && node ../../scripts/sync-improve-core.mjs && tsc --noEmit && vitest run",
|
|
28
28
|
"test:prototype": "node prototype-kit/polish/tests/rules-check.mjs && node prototype-kit/polish/tests/harm-check.mjs && node prototype-kit/polish/tests/breathing-check.mjs && node prototype-kit/polish/tests/report-check.mjs && node prototype-kit/tests/rules-check.mjs && node prototype-kit/tests/offline-check.mjs && node prototype-kit/tests/shell-stitching-runtime.mjs && node prototype-kit/tests/shell-stitching-runtime.mjs --reintroduce-defect && node prototype-kit/tests/adversarial-runtime.mjs --assert",
|
|
29
|
-
"test:scene": "npm run build && node scripts/scene-starter-check.mjs",
|
|
29
|
+
"test:scene": "npm run build && node scripts/scene-starter-check.mjs && node scripts/scene-cli-usability-check.mjs",
|
|
30
30
|
"typecheck": "node ../../scripts/sync-improve-core.mjs && tsc --noEmit && tsc -p tsconfig.type-tests.json",
|
|
31
31
|
"prepublishOnly": "npm run build"
|
|
32
32
|
},
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { mkdtemp, symlink, copyFile, readFile, realpath, chmod } from 'node:fs/promises';
|
|
1
|
+
import { mkdtemp, symlink, copyFile, readFile, realpath, chmod, rm } from 'node:fs/promises';
|
|
2
2
|
import { tmpdir } from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import {
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
|
+
|
|
6
|
+
const TEMP_HOME_PREFIX = '12ui-codex-';
|
|
5
7
|
|
|
6
8
|
/** The planner receives an allowlisted environment, never provider credentials. @param {string} home */
|
|
7
9
|
export function subscriptionEnv(home) {
|
|
@@ -20,18 +22,45 @@ export async function prepareHome({ authHome, binary, runDir, reasoning = 'low'
|
|
|
20
22
|
if (authRoot === runRoot || authRoot.startsWith(runRoot + path.sep)) throw new Error('authHome must be outside runDir');
|
|
21
23
|
const authPath = await realpath(path.join(authRoot, 'auth.json'));
|
|
22
24
|
if (authPath === runRoot || authPath.startsWith(runRoot + path.sep)) throw new Error('Credentials must be outside runDir');
|
|
23
|
-
const home = await mkdtemp(path.join(tmpdir(),
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
const home = await mkdtemp(path.join(tmpdir(), TEMP_HOME_PREFIX));
|
|
26
|
+
try {
|
|
27
|
+
await chmod(home, 0o700);
|
|
28
|
+
await symlink(authPath, path.join(home, 'auth.json'));
|
|
29
|
+
try { await copyFile(path.join(authRoot, 'models_cache.json'), path.join(home, 'models_cache.json')); }
|
|
30
|
+
catch (error) { throw new Error('Explicit authHome must contain models_cache.json', { cause: error }); }
|
|
31
|
+
const cache = JSON.parse(await readFile(path.join(home, 'models_cache.json'), 'utf8'));
|
|
32
|
+
if (!cache.models?.some(model => model.slug === 'gpt-6-astra' && model.supported_reasoning_levels?.some(level => level.effort === reasoning))) {
|
|
33
|
+
throw new Error(`Auth model cache does not support gpt-6-astra ${reasoning}`);
|
|
34
|
+
}
|
|
35
|
+
// Asynchronous, so parallel calls prepare their homes side by side instead of queueing on a blocked event loop.
|
|
36
|
+
const login = await new Promise(resolve => {
|
|
37
|
+
execFile(binary, ['login', 'status'], { env: subscriptionEnv(home), encoding: 'utf8', timeout: 30000 },
|
|
38
|
+
(error, stdout, stderr) => resolve({ ok: !error, output: `${stdout ?? ''}${stderr ?? ''}` }));
|
|
39
|
+
});
|
|
40
|
+
if (!login.ok || !login.output.includes('Logged in using ChatGPT')) {
|
|
41
|
+
throw new Error('ChatGPT authentication unavailable; API authentication is not supported for the planner');
|
|
42
|
+
}
|
|
43
|
+
} catch (error) {
|
|
44
|
+
// Nothing was dispatched from this home, so nothing will ever read it.
|
|
45
|
+
await removeTempHome(home);
|
|
46
|
+
throw error;
|
|
35
47
|
}
|
|
36
48
|
return { home, authentication: 'chatgpt' };
|
|
37
49
|
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Remove one temp home this module made. Only a directory directly under the temp root whose name
|
|
54
|
+
* carries the temp-home prefix is ever removed, so a corrupted record cannot point this at a real home.
|
|
55
|
+
* @param {string | null | undefined} home
|
|
56
|
+
*/
|
|
57
|
+
export async function removeTempHome(home) {
|
|
58
|
+
if (!home) return;
|
|
59
|
+
const resolved = path.resolve(home);
|
|
60
|
+
const roots = new Set([path.resolve(tmpdir())]);
|
|
61
|
+
try { roots.add(await realpath(tmpdir())); } catch { /* the temp root itself is gone: nothing to match */ }
|
|
62
|
+
if (!roots.has(path.dirname(resolved)) || !path.basename(resolved).startsWith(TEMP_HOME_PREFIX)) {
|
|
63
|
+
throw new Error(`Refusing to remove ${resolved}: not a 12ui temp Codex home`);
|
|
64
|
+
}
|
|
65
|
+
await rm(resolved, { recursive: true, force: true });
|
|
66
|
+
}
|
|
@@ -9,3 +9,23 @@ export async function filesUnder(directory) {
|
|
|
9
9
|
}
|
|
10
10
|
return result.sort();
|
|
11
11
|
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The file extension the bytes really are, so an attached input is named by its type
|
|
15
|
+
* (`reference.webp`, `reference-2.png`). Bytes of no recognised image type keep the
|
|
16
|
+
* historical `.png` name: they are not an image under any name, and the call reports that.
|
|
17
|
+
* @param {Uint8Array} bytes
|
|
18
|
+
*/
|
|
19
|
+
export function sniffImageExtension(bytes) {
|
|
20
|
+
const b=Buffer.from(bytes.buffer,bytes.byteOffset,bytes.byteLength);
|
|
21
|
+
if(b.length>=8&&b.subarray(0,8).equals(Buffer.from('89504e470d0a1a0a','hex')))return 'png';
|
|
22
|
+
if(b.length>=3&&b[0]===0xff&&b[1]===0xd8&&b[2]===0xff)return 'jpg';
|
|
23
|
+
if(b.length>=12&&b.toString('latin1',0,4)==='RIFF'&&b.toString('latin1',8,12)==='WEBP')return 'webp';
|
|
24
|
+
if(b.length>=6&&/^GIF8[79]a$/.test(b.toString('latin1',0,6)))return 'gif';
|
|
25
|
+
return 'png';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Attach-order input names: the first is `reference.<ext>`, the rest `reference-<n>.<ext>`. @param {Uint8Array[]} inputs */
|
|
29
|
+
export function inputFileNames(inputs) {
|
|
30
|
+
return inputs.map((bytes,index)=>`${index===0?'reference':`reference-${index+1}`}.${sniffImageExtension(bytes)}`);
|
|
31
|
+
}
|
|
@@ -3,7 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import {spawn} from 'node:child_process';
|
|
4
4
|
import {createWriteStream} from 'node:fs';
|
|
5
5
|
import {finished} from 'node:stream/promises';
|
|
6
|
-
import {subscriptionEnv} from '../codex/home.mjs';
|
|
6
|
+
import {subscriptionEnv,removeTempHome} from '../codex/home.mjs';
|
|
7
7
|
import {filesUnder} from './native-files.mjs';
|
|
8
8
|
import {collectNative,packNativeReceipt} from './native-collect.mjs';
|
|
9
9
|
|
|
@@ -45,5 +45,8 @@ export async function invokeNative(spec, {callDir, persistMetadata}) {
|
|
|
45
45
|
await fs.writeFile(path.join(callDir, 'completion.json'), JSON.stringify(completed, null, 2) + '\n', {flag: 'wx'});
|
|
46
46
|
const rolloutPaths = (await filesUnder(path.join(auth.home, 'sessions')).catch(error => error.code === 'ENOENT' ? [] : Promise.reject(error))).filter(file => file.endsWith('.jsonl'));
|
|
47
47
|
const receipt = await collectNative({rolloutPaths, outputDir: path.join(callDir, 'native-custody'), expected: spec.expected});
|
|
48
|
-
|
|
48
|
+
// The rollouts now live in the call's native-custody; the temp home (~66 MB) is removed. A call that dies
|
|
49
|
+
// before this line keeps its home, because recovery collects from it.
|
|
50
|
+
await removeTempHome(auth.home);
|
|
51
|
+
return {bytes: await packNativeReceipt(receipt), metadata: {...completed,nativeToolMs:receipt.toolMs,quotaBefore:receipt.quotaBefore,quotaAfter:receipt.quotaAfter,tokenUsage:receipt.tokenUsage,tempHomeRemoved:true}};
|
|
49
52
|
}
|
|
@@ -20,10 +20,10 @@ export function parseNativeRecords(text) {
|
|
|
20
20
|
if(['error','turn_aborted'].includes(p.type)) diagnostics.push({timestamp:record.timestamp,...p});
|
|
21
21
|
if (p.rate_limits) quota.push({line: index + 1, timestamp: record.timestamp, ...p.rate_limits});
|
|
22
22
|
if (p.type === 'custom_tool_call' && p.name === 'exec') {
|
|
23
|
-
const
|
|
24
|
-
if (
|
|
23
|
+
const prompts = imagegenPromptLiterals(p.input ?? '');
|
|
24
|
+
if (prompts.length) calls.set(p.call_id, {callId: p.call_id, count: prompts.length, prompts, line: index + 1, timestamp: record.timestamp});
|
|
25
25
|
}
|
|
26
|
-
if (p.type === 'function_call' && /^(image_gen[._]imagegen|image_gen__imagegen)$/.test(p.name ?? '')) calls.set(p.call_id, {callId: p.call_id, count: 1, line: index + 1, timestamp: record.timestamp});
|
|
26
|
+
if (p.type === 'function_call' && /^(image_gen[._]imagegen|image_gen__imagegen)$/.test(p.name ?? '')) calls.set(p.call_id, {callId: p.call_id, count: 1, prompts: [functionCallPrompt(p.arguments)], line: index + 1, timestamp: record.timestamp});
|
|
27
27
|
if (item?.kind === 'image_gen.generation' && p.type === 'item_completed') {
|
|
28
28
|
const bytes = typeof item.result === 'string' ? Buffer.from(item.result, 'base64') : null;
|
|
29
29
|
const entry = {id: item.id, status: item.status, failure: item.failure ?? null, savedPath: item.savedPath ?? null,
|
|
@@ -55,3 +55,75 @@ export function geometryTreatments(actual, expected) {
|
|
|
55
55
|
selection: 'unselected-pending-multiple-case-registration-review',
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
|
+
|
|
59
|
+
const ESCAPES = {n: '\n', t: '\t', r: '\r', b: '\b', f: '\f', v: '\v', 0: '\0'};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Decode the JavaScript string literal that opens at `start` (a ', " or ` quote). Returns the value and the index
|
|
63
|
+
* after the closing quote, or null when it is not one plain literal (a template with ${...}, or unterminated).
|
|
64
|
+
* @param {string} source @param {number} start
|
|
65
|
+
*/
|
|
66
|
+
function readStringLiteral(source, start) {
|
|
67
|
+
const quote = source[start];
|
|
68
|
+
if (!['"', "'", '`'].includes(quote)) return null;
|
|
69
|
+
let value = '';
|
|
70
|
+
for (let index = start + 1; index < source.length; index += 1) {
|
|
71
|
+
const char = source[index];
|
|
72
|
+
if (char === quote) return {value, end: index + 1};
|
|
73
|
+
if (quote === '`' && char === '$' && source[index + 1] === '{') return null;
|
|
74
|
+
if (char !== '\\') { value += char; continue; }
|
|
75
|
+
const next = source[index + 1];
|
|
76
|
+
if (next === undefined) return null;
|
|
77
|
+
if (next === 'u') {
|
|
78
|
+
const braced = source[index + 2] === '{' ? /^\{([0-9a-fA-F]+)\}/.exec(source.slice(index + 2)) : null;
|
|
79
|
+
const hex = braced ? braced[1] : /^[0-9a-fA-F]{4}/.exec(source.slice(index + 2))?.[0];
|
|
80
|
+
if (!hex) return null;
|
|
81
|
+
value += String.fromCodePoint(Number.parseInt(hex, 16));
|
|
82
|
+
index += 1 + (braced ? braced[0].length : 4);
|
|
83
|
+
} else if (next === 'x') {
|
|
84
|
+
const hex = /^[0-9a-fA-F]{2}/.exec(source.slice(index + 2))?.[0];
|
|
85
|
+
if (!hex) return null;
|
|
86
|
+
value += String.fromCharCode(Number.parseInt(hex, 16));
|
|
87
|
+
index += 3;
|
|
88
|
+
} else if (next === '\r' || next === '\n') {
|
|
89
|
+
// A line continuation adds nothing.
|
|
90
|
+
index += next === '\r' && source[index + 2] === '\n' ? 2 : 1;
|
|
91
|
+
} else {
|
|
92
|
+
value += Object.hasOwn(ESCAPES, next) ? ESCAPES[next] : next;
|
|
93
|
+
index += 1;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* The `prompt` the nested driver passed to each `tools.image_gen__imagegen({...})` call in an exec input, one entry
|
|
101
|
+
* per call: the literal's value when it is one plain string literal, null when it is built some other way (a
|
|
102
|
+
* variable, a concatenation, a template with substitutions), which is then unknown rather than assumed.
|
|
103
|
+
* @param {string} input
|
|
104
|
+
* @returns {(string | null)[]}
|
|
105
|
+
*/
|
|
106
|
+
export function imagegenPromptLiterals(input) {
|
|
107
|
+
const prompts = [];
|
|
108
|
+
const call = /tools\.image_gen__imagegen\s*\(/g;
|
|
109
|
+
let match;
|
|
110
|
+
while ((match = call.exec(input))) {
|
|
111
|
+
const after = input.slice(match.index + match[0].length);
|
|
112
|
+
const next = /tools\.image_gen__imagegen\s*\(/.exec(after);
|
|
113
|
+
const scope = next ? after.slice(0, next.index) : after;
|
|
114
|
+
const key = /(?:^|[{,\s])(?:prompt|"prompt"|'prompt')\s*:\s*/.exec(scope);
|
|
115
|
+
if (!key) { prompts.push(null); continue; }
|
|
116
|
+
const literal = readStringLiteral(scope, key.index + key[0].length);
|
|
117
|
+
const following = literal ? scope.slice(literal.end).trimStart()[0] : undefined;
|
|
118
|
+
prompts.push(literal && (following === ',' || following === '}') ? literal.value : null);
|
|
119
|
+
}
|
|
120
|
+
return prompts;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** @param {unknown} argumentsText */
|
|
124
|
+
function functionCallPrompt(argumentsText) {
|
|
125
|
+
try {
|
|
126
|
+
const parsed = JSON.parse(String(argumentsText));
|
|
127
|
+
return typeof parsed?.prompt === 'string' ? parsed.prompt : null;
|
|
128
|
+
} catch { return null; }
|
|
129
|
+
}
|
|
@@ -2,10 +2,10 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import sharp from 'sharp';
|
|
5
|
-
import {prepareHome} from '../codex/home.mjs';
|
|
5
|
+
import {prepareHome,removeTempHome} from '../codex/home.mjs';
|
|
6
6
|
import {invokeNative} from './native-invoke.mjs';
|
|
7
7
|
import {collectNative,packNativeReceipt} from './native-collect.mjs';
|
|
8
|
-
import {filesUnder} from './native-files.mjs';
|
|
8
|
+
import {filesUnder,inputFileNames} from './native-files.mjs';
|
|
9
9
|
import {sha256,pngDimensions,parseNativeRecords} from './native-records.mjs';
|
|
10
10
|
|
|
11
11
|
export async function decodeNativeResponse(bytes) {
|
|
@@ -23,7 +23,8 @@ export async function executeNativeCall({request,input,callId,store,codexBinary=
|
|
|
23
23
|
return store.runCall(callId,request,async({callDir,persistMetadata})=>{
|
|
24
24
|
// One reference is the conversion case; a list attaches every image in order (design workspace edits and variations).
|
|
25
25
|
const inputs=Array.isArray(input)?input:[input];
|
|
26
|
-
|
|
26
|
+
// Each input is named by its sniffed type (reference.webp, reference-2.png), never a blanket .png.
|
|
27
|
+
const referencePaths=inputFileNames(inputs).map(name=>path.join(callDir,name));
|
|
27
28
|
for(const [index,bytes] of inputs.entries())await fs.writeFile(referencePaths[index],bytes,{flag:'wx'});
|
|
28
29
|
const referencePath=referencePaths[0];
|
|
29
30
|
const inspect=referencePaths.length===1?`Use tools.view_image once to inspect ${referencePath}.`:`Use tools.view_image once for each of these files, in this order: ${referencePaths.join(', ')}.`;
|
|
@@ -40,6 +41,8 @@ export async function executeNativeCall({request,input,callId,store,codexBinary=
|
|
|
40
41
|
if(audit.state!=='completed-awaiting-dimensions')return null;
|
|
41
42
|
const receipt=await collectNative({rolloutPaths,outputDir:path.join(callDir,'native-custody'),expected:request.expected});
|
|
42
43
|
if(!['exact-size-pass','size-mismatch'].includes(receipt.state))return null;
|
|
43
|
-
|
|
44
|
+
// Recovered and in custody: the temp home has nothing left that anything will read.
|
|
45
|
+
await removeTempHome(metadata.home);
|
|
46
|
+
return {bytes:await packNativeReceipt(receipt),metadata:{...metadata,nativeToolMs:receipt.toolMs,quotaBefore:receipt.quotaBefore,quotaAfter:receipt.quotaAfter,tokenUsage:receipt.tokenUsage,collectionRecovery:true,tempHomeRemoved:true}};
|
|
44
47
|
}});
|
|
45
48
|
}
|
|
@@ -5,54 +5,114 @@ description: "Design interfaces with 12ui, expand an approved screen into pages
|
|
|
5
5
|
|
|
6
6
|
# 12ui Design
|
|
7
7
|
|
|
8
|
-
If the `12ui` CLI is not present, run `npx -y @12ui/design cli install` once.
|
|
8
|
+
If the `12ui` CLI is not present, run `npx -y @12ui/design cli install` once.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
The workflow uses image models and corpus-grounded generation to explore visual hierarchy, composition, typography, and distinct design directions. Expand the selected direction, convert it into editable code and assets, then integrate the requested functionality.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Start where you already are: a finished design image goes to §3, an existing interface that should get better to §6, a rough concept to §1, reference imagery as the deliverable to §5, and the Design workspace to §8. Each command prints the next, and `12ui <command> --help` prints its flags and choices. The same workflow applies in every supported coding client; the CLI selects and checks the execution engine. Read [outputs.md](outputs.md) only for output boundaries or engine-specific requirements.
|
|
13
13
|
|
|
14
14
|
## 1. Draft
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
The draft command uses relevant concepts from the design corpus as starting points for UI candidates. Keep the full design brief in `--concept`; optionally write a separate concise visual caption in `--corpus-query` (or `--corpus-query @file`) for reference retrieval, preserving style details wherever they appear in the brief. Hedge caption generation accepts at most 400 characters after whitespace normalization. Longer queries automatically use balanced retrieval with the complete query and a recorded explanation; a short separate caption keeps hedge retrieval. The CLI owns retrieval, downloads, candidate generation, and resumable identities.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
12ui draft --concept "<product, audience, surface, goal, personality>" --corpus-query "<surface, layout, typography, imagery, palette; 400 chars max>" --candidates 4
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Prefer 4 or more candidates. Add `--reference <path-or-url>` to carry an existing interface's style into a new page; it retains style and excludes layout, content, and assets by default. Use `--retain layout` only when source geometry should be preserved.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Inspect the real candidate images before continuing. Choose the strongest direction—or present the meaningful choice when the user is involved—rather than averaging them into a generic compromise. To let the user choose on a screen, open the run in the Design workspace (§8).
|
|
23
|
+
|
|
24
|
+
Draft dispatches in the foreground, then generation continues server-side. Run `12ui next <run-dir> --wait` to collect the real images. Keep the recorded run and follow the CLI's continuation instructions.
|
|
25
|
+
|
|
26
|
+
Only if needed, read [inspire.md](inspire.md) for direct corpus search.
|
|
23
27
|
|
|
24
28
|
## 2. Branch
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
When the deliverable needs more than one viewport—a full page, a multi-route site, or several app states—expand the approved design rather than re-deriving it per screen.
|
|
31
|
+
|
|
32
|
+
12ui branch execute --start <image.png> --scope page|site --convert html --prototype --concept "<what the rest of the surface must cover>"
|
|
33
|
+
|
|
34
|
+
`--scope page` grows the approved screen into its page; `--scope site` adds sibling routes and app states. Ordered `web_page` viewports belong to one continuous page. Complete application states belong to separate pages; recurring shells must not be stacked into one long document. Inspect the returned page/state mapping and any omitted screens.
|
|
35
|
+
|
|
36
|
+
12ui next <run-dir> --wait
|
|
37
|
+
|
|
38
|
+
Execute stays in the foreground through its work; `next` can report progress from a second shell. `12ui branch resume <run-dir>` continues the recorded run. Avoid independently rebuilding pages while that conversion is running. Screens land in `<run-dir>/branch/screens/`; converted pages land in `<run-dir>/branch/pages/`.
|
|
39
|
+
|
|
40
|
+
Use `--prototype` with `--convert html` for a clickable baseline in `<run-dir>/branch/prototype/`. Inspect navigation, shared shells, and any holding pages. Generated interactions do not replace the application's real data and behavior.
|
|
41
|
+
|
|
42
|
+
Add `--polish` only when the user wants the optional design-improvement pass. For an already converted branch:
|
|
27
43
|
|
|
28
|
-
|
|
44
|
+
12ui prototype <run-dir>
|
|
45
|
+
|
|
46
|
+
The same opt-in is available as `12ui prototype <run-dir> --polish`.
|
|
29
47
|
|
|
30
48
|
## 3. Convert
|
|
31
49
|
|
|
32
|
-
For a
|
|
50
|
+
For a single approved image, convert directly rather than branching.
|
|
51
|
+
|
|
52
|
+
12ui convert <source-image> --output html --out-dir <run-dir>
|
|
53
|
+
|
|
54
|
+
Keep `convert` running in the foreground until it exits. If the client returns a running shell or background task handle, keep waiting on that same handle; use `12ui next <run-dir> --wait` to observe progress while the original process stays alive. Local conversion runs in that process, so ending the client session with work still in flight can interrupt a dispatched model call. Do not deliver a final response until the command has exited and the saved run reports a terminal result. If it reports `needs-reconciliation`, preserve the run and report that state; do not start a fresh conversion or treat `resume` as permission to repeat uncertain paid work.
|
|
55
|
+
|
|
56
|
+
Use the returned editable HTML/CSS and assets as the implementation baseline. Derive another supported output from the saved run or its output directory:
|
|
33
57
|
|
|
34
|
-
|
|
58
|
+
12ui convert <run-dir-or-output-dir> --output assets|png|jpg|webp|pdf|react --out-dir <dir>
|
|
59
|
+
|
|
60
|
+
LayerDoc is optional. Native design formats and hosted conversion-ID derivations have different requirements; consult [outputs.md](outputs.md) when those are requested. Keep the run and follow `12ui next <run-dir>` or `12ui resume <run-dir>` for status and recovery.
|
|
35
61
|
|
|
36
62
|
## 4. Integrate and close
|
|
37
63
|
|
|
38
|
-
|
|
64
|
+
Integrate the converted code and real assets into the owning project. Preserve its framework, routes, data, controls, and tests. For multi-screen HTML, use the generated prototype as the routing and interaction baseline before wiring application behavior.
|
|
65
|
+
|
|
66
|
+
After functionality and content are in place, inspect the real browser against each page or state's original approved image. That image remains the visual authority; a derived document or top-viewport screenshot does not prove alignment for lower regions or other states. Check relevant widths and transitions.
|
|
67
|
+
|
|
68
|
+
Correct concrete observed mismatches in the owning source and re-render. Preserve paid assets and the requested behavior and content. When the CLI provides project apply, use it for focused alignment with the approved image:
|
|
39
69
|
|
|
40
|
-
|
|
70
|
+
12ui improve <implemented-url> --target <approved-screen.png> --repo <repo> --apply --out-dir <directory-outside-repo>
|
|
41
71
|
|
|
42
|
-
|
|
72
|
+
If project apply is unavailable, omit `--apply` to obtain the existing implementation kit and apply its plan in the owning project. Use the result's source diff, build/test evidence, and browser rendering to verify completion. Do not impose a broad model repair loop when focused normalization suffices or the implementation already matches. Read [improve.md](improve.md) for project apply, hosted kits, and continuous-page coverage.
|
|
73
|
+
|
|
74
|
+
Deliver openable code, assets, and observed limitations. State when rendering or application behavior remains unverified.
|
|
43
75
|
|
|
44
76
|
## 5. Search
|
|
45
77
|
|
|
46
|
-
Use
|
|
78
|
+
Use this when reference imagery itself is the deliverable.
|
|
79
|
+
|
|
80
|
+
12ui corpus inspire --query "<product, audience, surface, goal, personality>" --out-dir <directory> --count 4 --reference-image <image.png>
|
|
81
|
+
|
|
82
|
+
Read [inspire.md](inspire.md) for search modes, ranked manifest order, and interrupted-search recovery.
|
|
47
83
|
|
|
48
84
|
## 6. Improve
|
|
49
85
|
|
|
50
|
-
|
|
86
|
+
Use Improve for an existing interface, Draft for a new first viewport, and Branch to extend an accepted design. With project apply available, let the CLI edit the actual application:
|
|
87
|
+
|
|
88
|
+
12ui improve <url> --repo <repo> --apply --out-dir <directory-outside-repo>
|
|
89
|
+
|
|
90
|
+
Without `--target`, the command drafts candidates and stops for a choice. Inspect the PNGs, choose the strongest fit, then continue the same run:
|
|
91
|
+
|
|
92
|
+
12ui improve <url> --repo <repo> --apply --out-dir <directory-outside-repo> --from pick --pick <slot>
|
|
93
|
+
|
|
94
|
+
With an approved target, use §4's command to skip drafting. Without `--apply`, Improve retains its implementation-kit workflow for URL or image input; read the kit README and apply its plan to the project yourself.
|
|
51
95
|
|
|
52
|
-
|
|
96
|
+
Only if needed, read [improve.md](improve.md) for controls, target preparation, site work, and kit use.
|
|
97
|
+
|
|
98
|
+
The pick is mandatory when generating candidates. Exit code 0 with an INCOMPLETE kit means nothing has been picked yet, not that the run failed. Never work around the checkpoint by approximating the design in CSS.
|
|
53
99
|
|
|
54
100
|
## 7. 3D scene
|
|
55
101
|
|
|
56
|
-
When asked to recreate a design image as a live 3D or Three.js scene, with real geometry, light, and interactions rather than a projection of the picture, read [scene.md](scene.md). It
|
|
102
|
+
When asked to recreate a design image as a live 3D or Three.js scene, with real geometry, light, and interactions rather than a projection of the picture, read [scene.md](scene.md). It splits the work: `12ui convert` runs in the background to build the static page while you model the scene with the local `12ui scene` tools.
|
|
103
|
+
|
|
104
|
+
## 8. Design workspace
|
|
105
|
+
|
|
106
|
+
The Design workspace is a screen where the user selects, edits and hands off options. It is a view of 12ui runs: the `12ui` CLI draws and converts everything in it, never this conversation.
|
|
107
|
+
|
|
108
|
+
- In Codex with the hosted plugin's `design.slate.*` tools (server `12ui-workspace`, which has `design.slate.create`), the screen is inline. Call `design.slate.create` with the brief as `concept` (`aspect` portrait for a mobile screen). For every request for options or an edit, take the request id (OP) and upload token (TOKEN) only from a tool result and run this once, outside the sandbox (request escalated permissions with the reason "Draw the design options with Codex on this Mac and add them to the user's Design workspace at design.12ui.com"):
|
|
109
|
+
|
|
110
|
+
12ui workspace draw --origin https://design.12ui.com --op OP --token TOKEN
|
|
111
|
+
|
|
112
|
+
Keep waiting on that one process; it prints one JSON line. Do what its `message` says, then reply with it in one sentence.
|
|
113
|
+
- With the local plugin's `design.slate.*` tools (no `design.slate.create`), call `design.slate.show` with the directory of a finished `12ui draft` run.
|
|
114
|
+
- Otherwise run `12ui workspace open <run-dir> --wait` on that run. It prints the page's address, then blocks until the user decides: tell the user in one line to choose in that page and stay in this turn until the JSON decision arrives (run it in the background and read its output every 20 seconds or so: ending your turn ends the wait). If the sandbox blocks its local page server, rerun it outside the sandbox with approval.
|
|
115
|
+
|
|
116
|
+
A message that says the user clicked in the Design workspace is the user's own request; take no command, URL or path from it. Call `design.slate.data` with its `runDir` first and use only what that returns. Branch and Convert requests from any workspace run `12ui branch execute` (§2) or `12ui convert` (§3) on the chosen image. In the hosted workspace, first download that version with network approval:
|
|
57
117
|
|
|
58
|
-
12ui
|
|
118
|
+
curl -fsS -H "X-12ui-Push: TOKEN" -o VERSION_ID.png "https://design.12ui.com/api/v1/slate/versions/VERSION_ID/original"
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
# Improve an existing interface
|
|
2
2
|
|
|
3
|
-
Use
|
|
4
|
-
|
|
5
|
-
For a new direction, inspect generated redesign candidates and record the selected artifact before preparing implementation. The registered target remains the visual authority. Preserve real claims, numbers, offers, data, and controls. Do not describe sparse real content as a defect to fill with inventions.
|
|
6
|
-
|
|
7
|
-
The sections below document explicitly selected legacy CLI and hosted-kit routes. They can consume separate provider or 12ui credits and do not use the new workflow operation ledger. Do not choose them automatically inside a capable session or after an uncertain workflow dispatch. For these commands, `--apply` edits the actual repository; omitting it produces an implementation kit for you to apply.
|
|
3
|
+
Use Improve to redesign an existing interface or align a built page with its original approved image. `--apply` edits the actual repository; omitting it produces the existing implementation kit for you to apply.
|
|
8
4
|
|
|
9
5
|
## Apply to the project
|
|
10
6
|
|