@12ui/design 0.2.65 → 0.2.67
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 +45 -35
- package/SKILL.md +1 -1
- package/dist/branch-client.d.ts +4 -2
- package/dist/branch-client.d.ts.map +1 -1
- package/dist/branch-client.js +36 -21
- package/dist/branch-client.js.map +1 -1
- package/dist/branch-conversion-engine.d.ts +8 -0
- package/dist/branch-conversion-engine.d.ts.map +1 -0
- package/dist/branch-conversion-engine.js +43 -0
- package/dist/branch-conversion-engine.js.map +1 -0
- package/dist/branch-execution.d.ts +12 -0
- package/dist/branch-execution.d.ts.map +1 -1
- package/dist/branch-execution.js +62 -39
- package/dist/branch-execution.js.map +1 -1
- package/dist/branch-local-conversion.d.ts +27 -0
- package/dist/branch-local-conversion.d.ts.map +1 -0
- package/dist/branch-local-conversion.js +80 -0
- package/dist/branch-local-conversion.js.map +1 -0
- package/dist/branch-local-publication.d.ts +15 -0
- package/dist/branch-local-publication.d.ts.map +1 -0
- package/dist/branch-local-publication.js +111 -0
- package/dist/branch-local-publication.js.map +1 -0
- package/dist/branch-page-conversion.d.ts +7 -0
- package/dist/branch-page-conversion.d.ts.map +1 -1
- package/dist/branch-page-conversion.js +13 -0
- package/dist/branch-page-conversion.js.map +1 -1
- package/dist/branch-progress.d.ts +2 -0
- package/dist/branch-progress.d.ts.map +1 -1
- package/dist/branch-progress.js.map +1 -1
- package/dist/branch-run-record.d.ts +24 -2
- package/dist/branch-run-record.d.ts.map +1 -1
- package/dist/branch-run-record.js +3 -2
- package/dist/branch-run-record.js.map +1 -1
- package/dist/branch-status.d.ts.map +1 -1
- package/dist/branch-status.js +21 -3
- package/dist/branch-status.js.map +1 -1
- package/dist/branch-winner.d.ts.map +1 -1
- package/dist/branch-winner.js +1 -2
- package/dist/branch-winner.js.map +1 -1
- package/dist/cli-arguments.d.ts.map +1 -1
- package/dist/cli-arguments.js +1 -0
- package/dist/cli-arguments.js.map +1 -1
- package/dist/cli-branch-command.d.ts.map +1 -1
- package/dist/cli-branch-command.js +7 -2
- package/dist/cli-branch-command.js.map +1 -1
- package/dist/cli-capabilities.d.ts +37 -15
- package/dist/cli-capabilities.d.ts.map +1 -1
- package/dist/cli-capabilities.js +38 -22
- package/dist/cli-capabilities.js.map +1 -1
- package/dist/cli-codex-readiness.d.ts +11 -0
- package/dist/cli-codex-readiness.d.ts.map +1 -0
- package/dist/cli-codex-readiness.js +72 -0
- package/dist/cli-codex-readiness.js.map +1 -0
- package/dist/cli-conversion-engine.d.ts +11 -0
- package/dist/cli-conversion-engine.d.ts.map +1 -0
- package/dist/cli-conversion-engine.js +26 -0
- package/dist/cli-conversion-engine.js.map +1 -0
- package/dist/cli-conversion-receipt.d.ts +28 -0
- package/dist/cli-conversion-receipt.d.ts.map +1 -0
- package/dist/cli-conversion-receipt.js +130 -0
- package/dist/cli-conversion-receipt.js.map +1 -0
- package/dist/cli-convert-command.d.ts.map +1 -1
- package/dist/cli-convert-command.js +12 -5
- package/dist/cli-convert-command.js.map +1 -1
- package/dist/cli-corpus-command.d.ts.map +1 -1
- package/dist/cli-corpus-command.js +5 -7
- package/dist/cli-corpus-command.js.map +1 -1
- package/dist/cli-corpus-evidence.d.ts +0 -1
- package/dist/cli-corpus-evidence.d.ts.map +1 -1
- package/dist/cli-corpus-evidence.js +22 -49
- package/dist/cli-corpus-evidence.js.map +1 -1
- package/dist/cli-corpus-manifest.d.ts +18 -0
- package/dist/cli-corpus-manifest.d.ts.map +1 -0
- package/dist/cli-corpus-manifest.js +83 -0
- package/dist/cli-corpus-manifest.js.map +1 -0
- package/dist/cli-corpus-reference-downloads.d.ts.map +1 -1
- package/dist/cli-corpus-reference-downloads.js +5 -3
- package/dist/cli-corpus-reference-downloads.js.map +1 -1
- package/dist/cli-corpus-run.d.ts +2 -0
- package/dist/cli-corpus-run.d.ts.map +1 -1
- package/dist/cli-corpus-run.js +40 -16
- package/dist/cli-corpus-run.js.map +1 -1
- package/dist/cli-corpus-types.d.ts +10 -6
- package/dist/cli-corpus-types.d.ts.map +1 -1
- package/dist/cli-corpus-types.js.map +1 -1
- package/dist/cli-draft-command.d.ts +2 -0
- package/dist/cli-draft-command.d.ts.map +1 -1
- package/dist/cli-draft-command.js +20 -9
- package/dist/cli-draft-command.js.map +1 -1
- package/dist/cli-engine.d.ts +10 -0
- package/dist/cli-engine.d.ts.map +1 -0
- package/dist/cli-engine.js +28 -0
- package/dist/cli-engine.js.map +1 -0
- package/dist/cli-help/conversion.d.ts +10 -3
- package/dist/cli-help/conversion.d.ts.map +1 -1
- package/dist/cli-help/conversion.js +14 -6
- package/dist/cli-help/conversion.js.map +1 -1
- package/dist/cli-help/design.d.ts +7 -7
- package/dist/cli-help/design.d.ts.map +1 -1
- package/dist/cli-help/design.js +9 -7
- package/dist/cli-help/design.js.map +1 -1
- package/dist/cli-help/index.d.ts +19 -12
- package/dist/cli-help/index.d.ts.map +1 -1
- package/dist/cli-help/setup.d.ts +2 -2
- package/dist/cli-help/setup.js +3 -3
- package/dist/cli-help/setup.js.map +1 -1
- package/dist/cli-image-backend.d.ts +3 -0
- package/dist/cli-image-backend.d.ts.map +1 -0
- package/dist/cli-image-backend.js +12 -0
- package/dist/cli-image-backend.js.map +1 -0
- package/dist/cli-local-conversion.d.ts +17 -0
- package/dist/cli-local-conversion.d.ts.map +1 -0
- package/dist/cli-local-conversion.js +74 -0
- package/dist/cli-local-conversion.js.map +1 -0
- package/dist/cli-local-dispatch.d.ts +4 -0
- package/dist/cli-local-dispatch.d.ts.map +1 -0
- package/dist/cli-local-dispatch.js +102 -0
- package/dist/cli-local-dispatch.js.map +1 -0
- package/dist/cli-local-export.d.ts +7 -0
- package/dist/cli-local-export.d.ts.map +1 -0
- package/dist/cli-local-export.js +31 -0
- package/dist/cli-local-export.js.map +1 -0
- package/dist/cli-local-improve-context.d.ts +3 -0
- package/dist/cli-local-improve-context.d.ts.map +1 -0
- package/dist/cli-local-improve-context.js +47 -0
- package/dist/cli-local-improve-context.js.map +1 -0
- package/dist/cli-local-improve.d.ts +16 -0
- package/dist/cli-local-improve.d.ts.map +1 -0
- package/dist/cli-local-improve.js +214 -0
- package/dist/cli-local-improve.js.map +1 -0
- package/dist/cli-local-record.d.ts +8 -0
- package/dist/cli-local-record.d.ts.map +1 -0
- package/dist/cli-local-record.js +67 -0
- package/dist/cli-local-record.js.map +1 -0
- package/dist/cli-local-runtime.d.ts +7 -0
- package/dist/cli-local-runtime.d.ts.map +1 -0
- package/dist/cli-local-runtime.js +21 -0
- package/dist/cli-local-runtime.js.map +1 -0
- package/dist/cli-next-command.d.ts +1 -0
- package/dist/cli-next-command.d.ts.map +1 -1
- package/dist/cli-next-command.js +12 -9
- package/dist/cli-next-command.js.map +1 -1
- package/dist/cli-run.d.ts.map +1 -1
- package/dist/cli-run.js +3 -0
- package/dist/cli-run.js.map +1 -1
- package/dist/cli-skill-command.d.ts +0 -3
- package/dist/cli-skill-command.d.ts.map +1 -1
- package/dist/cli-skill-command.js +9 -24
- package/dist/cli-skill-command.js.map +1 -1
- package/dist/cli-usage.d.ts.map +1 -1
- package/dist/cli-usage.js +21 -12
- package/dist/cli-usage.js.map +1 -1
- package/dist/concept-input.d.ts +1 -1
- package/dist/concept-input.d.ts.map +1 -1
- package/dist/concept-input.js +1 -1
- package/dist/concept-input.js.map +1 -1
- package/dist/conversion-status-contract.d.ts +13 -1
- package/dist/conversion-status-contract.d.ts.map +1 -1
- package/dist/conversion-status-contract.js +12 -11
- package/dist/conversion-status-contract.js.map +1 -1
- package/dist/corpus-client.d.ts +11 -7
- package/dist/corpus-client.d.ts.map +1 -1
- package/dist/corpus-client.js +36 -8
- package/dist/corpus-client.js.map +1 -1
- package/dist/corpus-inspiration-failure.d.ts +9 -0
- package/dist/corpus-inspiration-failure.d.ts.map +1 -0
- package/dist/corpus-inspiration-failure.js +49 -0
- package/dist/corpus-inspiration-failure.js.map +1 -0
- package/dist/corpus-request-error.d.ts +7 -13
- package/dist/corpus-request-error.d.ts.map +1 -1
- package/dist/corpus-request-error.js +3 -12
- package/dist/corpus-request-error.js.map +1 -1
- package/dist/draft-corpus-query.d.ts +5 -0
- package/dist/draft-corpus-query.d.ts.map +1 -0
- package/dist/draft-corpus-query.js +31 -0
- package/dist/draft-corpus-query.js.map +1 -0
- package/dist/draft-identity.d.ts +2 -0
- package/dist/draft-identity.d.ts.map +1 -1
- package/dist/draft-identity.js +1 -0
- package/dist/draft-identity.js.map +1 -1
- package/dist/draft-run.d.ts +5 -1
- package/dist/draft-run.d.ts.map +1 -1
- package/dist/draft-run.js +10 -4
- package/dist/draft-run.js.map +1 -1
- package/dist/draft-workspace.d.ts +2 -0
- package/dist/draft-workspace.d.ts.map +1 -1
- package/dist/draft-workspace.js.map +1 -1
- package/dist/http-response-diagnostic.d.ts +12 -0
- package/dist/http-response-diagnostic.d.ts.map +1 -0
- package/dist/http-response-diagnostic.js +58 -0
- package/dist/http-response-diagnostic.js.map +1 -0
- package/dist/improve-branch-stage.d.ts.map +1 -1
- package/dist/improve-branch-stage.js +6 -25
- package/dist/improve-branch-stage.js.map +1 -1
- package/dist/improve-concept.d.ts +1 -1
- package/dist/improve-concept.d.ts.map +1 -1
- package/dist/improve-concept.js +1 -1
- package/dist/improve-concept.js.map +1 -1
- package/dist/improve-core/concept-input.d.ts +2 -43
- package/dist/improve-core/concept-input.d.ts.map +1 -1
- package/dist/improve-core/concept-input.js +3 -53
- package/dist/improve-core/concept-input.js.map +1 -1
- package/dist/improve-core/improve-concept.d.ts +0 -6
- package/dist/improve-core/improve-concept.d.ts.map +1 -1
- package/dist/improve-core/improve-concept.js +4 -36
- package/dist/improve-core/improve-concept.js.map +1 -1
- package/dist/improve-core/improve-page-words.d.ts +2 -2
- package/dist/improve-core/improve-page-words.d.ts.map +1 -1
- package/dist/improve-core/improve-page-words.js +8 -6
- package/dist/improve-core/improve-page-words.js.map +1 -1
- package/dist/improve-generation-stages.d.ts.map +1 -1
- package/dist/improve-generation-stages.js +6 -24
- package/dist/improve-generation-stages.js.map +1 -1
- package/dist/improve-kit-readme.d.ts.map +1 -1
- package/dist/improve-kit-readme.js +1 -0
- package/dist/improve-kit-readme.js.map +1 -1
- package/dist/improve-source-words.d.ts +14 -0
- package/dist/improve-source-words.d.ts.map +1 -0
- package/dist/improve-source-words.js +66 -0
- package/dist/improve-source-words.js.map +1 -0
- package/dist/improve-workspace.d.ts +3 -0
- package/dist/improve-workspace.d.ts.map +1 -1
- package/dist/improve-workspace.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy-skill-catalog.d.ts.map +1 -1
- package/dist/legacy-skill-catalog.js +44 -5
- package/dist/legacy-skill-catalog.js.map +1 -1
- package/dist/package-client.d.ts +3 -1
- package/dist/package-client.d.ts.map +1 -1
- package/dist/package-client.js +34 -11
- package/dist/package-client.js.map +1 -1
- package/dist/prototype-gates.d.ts.map +1 -1
- package/dist/prototype-gates.js +1 -1
- package/dist/prototype-gates.js.map +1 -1
- package/dist/prototype-poststep.js +1 -1
- package/dist/prototype-poststep.js.map +1 -1
- package/dist/prototype-requests.d.ts +1 -0
- package/dist/prototype-requests.d.ts.map +1 -1
- package/dist/prototype-requests.js.map +1 -1
- package/dist/prototype-revision.d.ts +1 -1
- package/dist/prototype-revision.js +1 -1
- package/dist/prototype-runner.d.ts.map +1 -1
- package/dist/prototype-runner.js +9 -3
- package/dist/prototype-runner.js.map +1 -1
- package/dist/reference-search-mode.d.ts +27 -2
- package/dist/reference-search-mode.d.ts.map +1 -1
- package/dist/reference-search-mode.js +29 -2
- package/dist/reference-search-mode.js.map +1 -1
- package/dist/review-page.js +2 -2
- package/dist/review-page.js.map +1 -1
- package/dist/review-prototype-gap.js +1 -1
- package/dist/review-prototype-gap.js.map +1 -1
- package/dist/run-journal-commands.d.ts.map +1 -1
- package/dist/run-journal-commands.js +1 -0
- package/dist/run-journal-commands.js.map +1 -1
- package/dist/skill-installer.d.ts +2 -1
- package/dist/skill-installer.d.ts.map +1 -1
- package/dist/skill-installer.js +3 -3
- package/dist/skill-installer.js.map +1 -1
- package/open-design.json +2 -2
- package/package.json +5 -4
- package/prototype-kit/analyze.mjs +4 -1
- package/prototype-kit/build.mjs +29 -4
- package/prototype-kit/inventory.mjs +11 -2
- package/prototype-kit/lib/local-page.mjs +50 -0
- package/prototype-kit/lib/static-server.mjs +1 -0
- package/skills/12ui-design/SKILL.md +35 -33
- package/skills/12ui-design/improve.md +48 -155
- package/skills/12ui-design/inspire.md +3 -1
- package/skills/12ui-design/outputs.md +22 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@12ui/design",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.67",
|
|
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",
|
|
@@ -12,17 +12,18 @@
|
|
|
12
12
|
"dist/**/*",
|
|
13
13
|
"prototype-kit/**/*",
|
|
14
14
|
"skills/**/*",
|
|
15
|
+
"runtime/**/*",
|
|
15
16
|
"SKILL.md",
|
|
16
17
|
"open-design.json",
|
|
17
18
|
"README.md",
|
|
18
19
|
"package.json"
|
|
19
20
|
],
|
|
20
21
|
"scripts": {
|
|
21
|
-
"build": "node ../../scripts/sync-improve-core.mjs && node ../../scripts/build-typescript-package.mjs",
|
|
22
|
+
"build": "node ../../scripts/codex-runtime-bundle.mjs && node ../../scripts/sync-improve-core.mjs && node ../../scripts/build-typescript-package.mjs",
|
|
22
23
|
"dev": "tsc --watch",
|
|
23
24
|
"start": "node dist/cli.js",
|
|
24
|
-
"test": "node ../../scripts/sync-improve-core.mjs && vitest",
|
|
25
|
-
"test:run": "node ../../scripts/sync-improve-core.mjs && tsc --noEmit && vitest run",
|
|
25
|
+
"test": "node ../../scripts/codex-runtime-bundle.mjs && node ../../scripts/sync-improve-core.mjs && vitest",
|
|
26
|
+
"test:run": "node ../../scripts/codex-runtime-bundle.mjs && node ../../scripts/sync-improve-core.mjs && tsc --noEmit && vitest run",
|
|
26
27
|
"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",
|
|
27
28
|
"typecheck": "node ../../scripts/sync-improve-core.mjs && tsc --noEmit && tsc -p tsconfig.type-tests.json",
|
|
28
29
|
"prepublishOnly": "npm run build"
|
|
@@ -30,6 +30,7 @@ for (const p of inv.pages) {
|
|
|
30
30
|
pageIndex: p.planPage?.index ?? null,
|
|
31
31
|
file: p.file,
|
|
32
32
|
sectionId: s.sectionId,
|
|
33
|
+
...(s.sourceKind ? { sourceKind: s.sourceKind } : {}),
|
|
33
34
|
slot,
|
|
34
35
|
ordinal,
|
|
35
36
|
title: p.planPage?.title || base.replace(/-/g, ' ').replace(/\b\p{L}/gu, (letter) => letter.toUpperCase()),
|
|
@@ -47,7 +48,7 @@ for (const p of inv.pages) {
|
|
|
47
48
|
});
|
|
48
49
|
});
|
|
49
50
|
}
|
|
50
|
-
if (!states.length) throw new Error('Prototype input error: no semantic viewport sections found; exports require section ids shaped like viewport-<ordinal>-<slot>');
|
|
51
|
+
if (!states.length) throw new Error('Prototype input error: no semantic viewport sections found; exports require section ids shaped like viewport-<ordinal>-<slot> or an explicitly marked local page body');
|
|
51
52
|
const byId = Object.fromEntries(states.map((s) => [s.stateId, s]));
|
|
52
53
|
const slotToState = Object.fromEntries(states.map((s) => [s.slot, s.stateId]));
|
|
53
54
|
|
|
@@ -81,6 +82,7 @@ const repeated = repeatedKeys();
|
|
|
81
82
|
// top-level containers per state and their shell share
|
|
82
83
|
function topContainers(s) {
|
|
83
84
|
const pre = s.sectionId + '-';
|
|
85
|
+
if (s.sourceKind === 'local-page') return [];
|
|
84
86
|
return s.containers.filter((c) => c.id.startsWith(pre) && !c.id.slice(pre.length).includes('-') && c.children > 0);
|
|
85
87
|
}
|
|
86
88
|
function regionOf(c) {
|
|
@@ -305,6 +307,7 @@ const model = {
|
|
|
305
307
|
nav,
|
|
306
308
|
states: states.map((s) => ({
|
|
307
309
|
stateId: s.stateId, pageId: s.pageId, file: s.file, sectionId: s.sectionId, slot: s.slot, ordinal: s.ordinal, title: s.title, purpose: s.purpose,
|
|
310
|
+
...(s.sourceKind ? { sourceKind: s.sourceKind } : {}),
|
|
308
311
|
surfaceType: s.surfaceType, direction: s.direction, content: s.content, dependsOn: s.dependsOnSlot ? slotToState[s.dependsOnSlot] : null, isSource: s.isSource,
|
|
309
312
|
shell: s.shell, candidates: s.candidates, fields: s.fields, scriptDirection: s.scriptDirection, writingMode: s.writingMode,
|
|
310
313
|
texts: s.items.filter((t) => t.text).map((t) => ({ id: t.id, text: t.text })).length,
|
package/prototype-kit/build.mjs
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
shellPlacementCss,
|
|
14
14
|
} from './lib/holding-composition.mjs';
|
|
15
15
|
import { injectReviewFraming } from './lib/review-framing.mjs';
|
|
16
|
+
import { buildLocalPage, isLocalPage } from './lib/local-page.mjs';
|
|
16
17
|
import { removeRemoteHeadLinks } from './lib/local-document.mjs';
|
|
17
18
|
import {
|
|
18
19
|
isolateTransplantedShell,
|
|
@@ -28,6 +29,8 @@ const [runDir, invFile, modelFile, labelsDir, outDir] = process.argv.slice(2);
|
|
|
28
29
|
const inv = JSON.parse(fs.readFileSync(invFile, 'utf8'));
|
|
29
30
|
const model = JSON.parse(fs.readFileSync(modelFile, 'utf8'));
|
|
30
31
|
const review = model.review || null;
|
|
32
|
+
const localPages = model.states.filter(state => state.sourceKind === 'local-page');
|
|
33
|
+
const wholeLocalPages = localPages.length === model.states.length;
|
|
31
34
|
const here = path.dirname(new URL(import.meta.url).pathname);
|
|
32
35
|
fs.mkdirSync(path.join(outDir, 'content'), { recursive: true });
|
|
33
36
|
fs.copyFileSync(path.join(here, 'runtime/proto.js'), path.join(outDir, 'proto.js'));
|
|
@@ -81,7 +84,7 @@ const reviewMissingByHolding = new Map(reviewMissingRoutes.map((route) => [route
|
|
|
81
84
|
const reviewMissingForTitle = (title) => reviewMissingRoutes.find((route) => (
|
|
82
85
|
norm(route.title) === norm(title) || routeKey(route.id) === routeKey(title)
|
|
83
86
|
));
|
|
84
|
-
for (const route of reviewMissingRoutes) {
|
|
87
|
+
for (const route of (wholeLocalPages ? [] : reviewMissingRoutes)) {
|
|
85
88
|
holdings.set(route.holding, route.title);
|
|
86
89
|
usedHoldings.set(route.holding, route.title);
|
|
87
90
|
}
|
|
@@ -168,6 +171,7 @@ const report = {
|
|
|
168
171
|
canonicalShellPage: model.canonicalShellPage || null,
|
|
169
172
|
shellConsistency: { changes: 0, decisions: [] },
|
|
170
173
|
holdings: [...holdings.values()],
|
|
174
|
+
...(wholeLocalPages && reviewMissingRoutes.length ? { unresolvedNavigation: reviewMissingRoutes.map(route => ({ route: route.id, title: route.title, reason: 'No converted page; existing navigation retained' })) } : {}),
|
|
171
175
|
counts: { navigate: 0, dropdown: 0, modal: 0, field: 0, none: 0, lunaOnly: 0, detOnly: 0, agree: 0, disagree: 0 },
|
|
172
176
|
};
|
|
173
177
|
function resolveTarget(target, currentStateId) {
|
|
@@ -187,6 +191,7 @@ function resolveTarget(target, currentStateId) {
|
|
|
187
191
|
return null;
|
|
188
192
|
}
|
|
189
193
|
function actionsFor(s) {
|
|
194
|
+
if (s.sourceKind === 'local-page') return new Map();
|
|
190
195
|
const acts = new Map(); // elementId -> {action, ...}
|
|
191
196
|
const luna = labels[s.stateId] || [];
|
|
192
197
|
const lunaById = new Map(luna.map((a) => [a.id, a]));
|
|
@@ -274,6 +279,24 @@ for (const [region, canonical] of Object.entries(model.canonicalShell)) {
|
|
|
274
279
|
// ---- build each unit
|
|
275
280
|
for (const u of units) {
|
|
276
281
|
const { document } = loadDoc(u.file);
|
|
282
|
+
if (isLocalPage(document)) {
|
|
283
|
+
const assetDirectory = document.body.getAttribute('data-12ui-local-assets');
|
|
284
|
+
if (assetDirectory && assetDirectory !== 'embedded') {
|
|
285
|
+
if (assetDirectory !== path.basename(assetDirectory) || assetDirectory.startsWith('.')) throw new Error('Local page asset directory must be a namespaced sibling');
|
|
286
|
+
fs.cpSync(path.join(runDir, 'pages', assetDirectory), path.join(outDir, assetDirectory), { recursive: true });
|
|
287
|
+
}
|
|
288
|
+
const built = buildLocalPage({ document, unit: u, labels, fileOf, stateById: byState,
|
|
289
|
+
pageFiles: new Map(units.map(unit => [unit.file, outputFileOfUnit(unit)])) });
|
|
290
|
+
report.unbound.push(...built.unbound);
|
|
291
|
+
report.counts.navigate += built.actions.length;
|
|
292
|
+
report.counts.none += built.unbound.length;
|
|
293
|
+
fs.writeFileSync(path.join(outDir, outputFileOfUnit(u)), '<!doctype html>\n' + document.documentElement.outerHTML);
|
|
294
|
+
fs.writeFileSync(path.join(outDir, 'content', u.id + '.json'), '{}');
|
|
295
|
+
report.units.push({ id: u.id, states: u.states.map(state => state.stateId), actions: built.actions.length,
|
|
296
|
+
fields: 0, unbound: built.unbound.length, sourceKind: 'local-page', viewportCoverage: 'not-claimed',
|
|
297
|
+
nativeScripts: document.querySelectorAll('script:not([data-12ui-prototype-navigation])').length });
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
277
300
|
const keep = new Set(u.states.map((s) => s.sectionId));
|
|
278
301
|
for (const sec of [...document.querySelectorAll('section[id^="viewport-"]')]) if (/^viewport-\d+-[A-Za-z0-9]+$/.test(sec.id) && !keep.has(sec.id)) sec.remove();
|
|
279
302
|
for (const sc of [...document.querySelectorAll('script')]) sc.remove();
|
|
@@ -472,7 +495,7 @@ for (const u of units) {
|
|
|
472
495
|
}
|
|
473
496
|
|
|
474
497
|
// ---- holding pages: fresh per-band composition from measured shells + neutral surface + holding block
|
|
475
|
-
{
|
|
498
|
+
if (!wholeLocalPages) {
|
|
476
499
|
const primaryRegion = model.canonicalShell.sidebar ? 'sidebar' : model.canonicalShell.header ? 'header' : Object.keys(model.canonicalShell)[0];
|
|
477
500
|
const can = primaryRegion ? shell[primaryRegion] : null;
|
|
478
501
|
const base = can ? byState[can.stateId] : (states.find((s) => s.isSource) || states[0]);
|
|
@@ -669,10 +692,12 @@ for (const u of units) {
|
|
|
669
692
|
}
|
|
670
693
|
|
|
671
694
|
// index -> source
|
|
672
|
-
const
|
|
695
|
+
const requestedHome = review?.entry?.file;
|
|
696
|
+
const home = requestedHome && (!wholeLocalPages || units.some(unit => outputFileOfUnit(unit) === requestedHome))
|
|
697
|
+
? requestedHome : fileOf((states.find((s) => s.isSource) || states[0]).stateId);
|
|
673
698
|
fs.writeFileSync(path.join(outDir, 'index.html'), `<!doctype html><meta http-equiv="refresh" content="0;url=${home}"><a href="${home}">${home}</a>`);
|
|
674
699
|
const manifestHoldings = review
|
|
675
700
|
? [...usedHoldings.entries()].map(([holding, title]) => [holding.replace(/\.html$/, ''), title])
|
|
676
701
|
: [...usedHoldings.entries()];
|
|
677
|
-
fs.writeFileSync(path.join(outDir, 'proto-manifest.json'), JSON.stringify({ units: report.units, nav: navRows.map((n) => ({ text: n.text, target: n.target, holding: n.holding, rowId: n.rowId })), holdings: manifestHoldings, counts: report.counts, unbound: report.unbound, invalidDropdowns: report.invalidDropdowns, ...(report.actionDemotions.length > 0 ? { actionDemotions: report.actionDemotions } : {}), ...(report.inertActionCandidates.length > 0 ? { inertActionCandidates: report.inertActionCandidates } : {}), ...(report.duplicateActionOwners.length > 0 ? { duplicateActionOwners: report.duplicateActionOwners } : {}), shellSizeDelta: report.shellSizeDelta, shellAmbiguities: report.shellAmbiguities, suppressedShellOverlaps: report.suppressedShellOverlaps, skippedShellTransplants: report.skippedShellTransplants, replacedShellActions: report.replacedShellActions, shellActionRemaps: report.shellActionRemaps, scriptDirections: states.map(({ stateId, scriptDirection, writingMode }) => ({ stateId, scriptDirection, writingMode })), canonicalShell: model.canonicalShell, canonicalShellPage: report.canonicalShellPage, shellConsistency: report.shellConsistency, ...(review ? { review } : {}) }, null, 1));
|
|
702
|
+
fs.writeFileSync(path.join(outDir, 'proto-manifest.json'), JSON.stringify({ units: report.units, ...(report.unresolvedNavigation ? { unresolvedNavigation: report.unresolvedNavigation } : {}), nav: navRows.map((n) => ({ text: n.text, target: n.target, holding: n.holding, rowId: n.rowId })), holdings: manifestHoldings, counts: report.counts, unbound: report.unbound, invalidDropdowns: report.invalidDropdowns, ...(report.actionDemotions.length > 0 ? { actionDemotions: report.actionDemotions } : {}), ...(report.inertActionCandidates.length > 0 ? { inertActionCandidates: report.inertActionCandidates } : {}), ...(report.duplicateActionOwners.length > 0 ? { duplicateActionOwners: report.duplicateActionOwners } : {}), shellSizeDelta: report.shellSizeDelta, shellAmbiguities: report.shellAmbiguities, suppressedShellOverlaps: report.suppressedShellOverlaps, skippedShellTransplants: report.skippedShellTransplants, replacedShellActions: report.replacedShellActions, shellActionRemaps: report.shellActionRemaps, scriptDirections: states.map(({ stateId, scriptDirection, writingMode }) => ({ stateId, scriptDirection, writingMode })), canonicalShell: model.canonicalShell, canonicalShellPage: report.canonicalShellPage, shellConsistency: report.shellConsistency, ...(review ? { review } : {}) }, null, 1));
|
|
678
703
|
console.error('counts', JSON.stringify(report.counts), 'unbound', report.unbound.length);
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { chromium } from '@playwright/test';
|
|
5
5
|
import fs from 'node:fs';
|
|
6
6
|
import path from 'node:path';
|
|
7
|
+
import { startStaticServer } from './lib/static-server.mjs';
|
|
7
8
|
|
|
8
9
|
const [runDir, outFile] = process.argv.slice(2);
|
|
9
10
|
if (!runDir || !outFile) throw new Error('usage: inventory.mjs <run-dir> <out.json>');
|
|
@@ -22,6 +23,7 @@ if (!fs.existsSync(pagesDir)) throw new Error(`Prototype input error: missing pa
|
|
|
22
23
|
const files = fs.readdirSync(pagesDir).filter((f) => f.endsWith('.html')).sort();
|
|
23
24
|
if (!files.length) throw new Error(`Prototype input error: no exported HTML pages in ${pagesDir}`);
|
|
24
25
|
|
|
26
|
+
const localServer = await startStaticServer(pagesDir);
|
|
25
27
|
const browser = await chromium.launch();
|
|
26
28
|
const ctx = await browser.newContext({ viewport: { width: 1536, height: 1024 }, deviceScaleFactor: 1 });
|
|
27
29
|
const page = await ctx.newPage();
|
|
@@ -31,9 +33,11 @@ const result = { runDir, plan, pages: [] };
|
|
|
31
33
|
for (const file of files) {
|
|
32
34
|
const pageId = file.replace(/\.html$/, '');
|
|
33
35
|
const planPage = planPages.find((p) => p.id === pageId);
|
|
34
|
-
|
|
36
|
+
const isLocalDocument = /data-12ui-local-page/.test(fs.readFileSync(path.join(pagesDir, file), 'utf8'));
|
|
37
|
+
await page.goto(isLocalDocument ? localServer.baseUrl + '/' + encodeURIComponent(file) : 'file://' + path.resolve(pagesDir, file), { waitUntil: 'load' });
|
|
35
38
|
await page.evaluate(() => document.fonts.ready);
|
|
36
39
|
const declaredBands = await page.evaluate(() => {
|
|
40
|
+
if (document.body.hasAttribute('data-12ui-local-page')) return [];
|
|
37
41
|
const roots = [...document.querySelectorAll('.ly-band[data-ly-band]')];
|
|
38
42
|
if (roots.length === 0) return [{ key: 'native', conditions: [] }];
|
|
39
43
|
const out = new Map(roots.map((root) => [root.getAttribute('data-ly-band'), []]));
|
|
@@ -322,12 +326,15 @@ for (const file of files) {
|
|
|
322
326
|
}
|
|
323
327
|
await page.setViewportSize({ width: 1536, height: 1024 });
|
|
324
328
|
const sections = await page.evaluate(() => {
|
|
325
|
-
const
|
|
329
|
+
const localPage = document.body.hasAttribute('data-12ui-local-page');
|
|
330
|
+
if (localPage && !document.body.id) throw new Error('Local page body requires a stable id');
|
|
331
|
+
const secs = localPage ? [document.body] : [...document.querySelectorAll('section[id^="viewport-"]')].filter((s) => /^viewport-\d+-[A-Za-z0-9]+$/.test(s.id));
|
|
326
332
|
const out = [];
|
|
327
333
|
for (const sec of secs) {
|
|
328
334
|
const sb = sec.getBoundingClientRect();
|
|
329
335
|
const sectionStyle = getComputedStyle(sec);
|
|
330
336
|
const els = [...sec.querySelectorAll('.text, h1, h2, h3, h4, h5, h6, button, .icon, img, .divider, [class*="input"], [class*="field"]')];
|
|
337
|
+
if (localPage) for (const el of sec.querySelectorAll('a,p,label,input,select,textarea')) if (!els.includes(el)) els.push(el);
|
|
331
338
|
const items = [];
|
|
332
339
|
for (const el of els) {
|
|
333
340
|
const r = el.getBoundingClientRect();
|
|
@@ -373,6 +380,7 @@ for (const file of files) {
|
|
|
373
380
|
}).filter((c) => c.w > 0 && c.h > 0);
|
|
374
381
|
out.push({
|
|
375
382
|
sectionId: sec.id,
|
|
383
|
+
...(localPage ? { sourceKind: 'local-page', viewportCoverage: 'not-claimed' } : {}),
|
|
376
384
|
width: sb.width,
|
|
377
385
|
height: sb.height,
|
|
378
386
|
scriptDirection: sectionStyle.direction,
|
|
@@ -388,5 +396,6 @@ for (const file of files) {
|
|
|
388
396
|
}
|
|
389
397
|
|
|
390
398
|
await browser.close();
|
|
399
|
+
await localServer.close();
|
|
391
400
|
fs.writeFileSync(outFile, JSON.stringify(result, null, 1));
|
|
392
401
|
console.error('wrote', outFile);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** A local converted document is one page, not a set of measured viewport exports. */
|
|
2
|
+
export function isLocalPage(document) {
|
|
3
|
+
return document.body?.hasAttribute('data-12ui-local-page') || false;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/** Keep existing DOM, CSS and scripts authoritative. Only real-route navigation is added. */
|
|
7
|
+
export function buildLocalPage({ document, unit, labels, fileOf, stateById, pageFiles }) {
|
|
8
|
+
if (!isLocalPage(document) || !document.body.id) throw new Error('Local prototype pages require an explicitly marked body with a stable id');
|
|
9
|
+
const localAssets = document.body.getAttribute('data-12ui-local-assets');
|
|
10
|
+
const localBase = document.querySelector('base')?.getAttribute('href');
|
|
11
|
+
const destination = file => {
|
|
12
|
+
if (!localAssets || localAssets === 'embedded' || !localBase?.startsWith(localAssets + '/')) return file;
|
|
13
|
+
const base = new URL(localBase, 'https://local.invalid/');
|
|
14
|
+
const depth = base.pathname.split('/').filter(Boolean).length - (base.pathname.endsWith('/') ? 0 : 1);
|
|
15
|
+
return '../'.repeat(depth) + file;
|
|
16
|
+
};
|
|
17
|
+
const actions = [];
|
|
18
|
+
const unbound = [];
|
|
19
|
+
// Preserve native anchors while relocating only exact source-page destinations.
|
|
20
|
+
for (const anchor of document.querySelectorAll('a[href]')) {
|
|
21
|
+
const href = anchor.getAttribute('href');
|
|
22
|
+
const match = href.match(/^(?:(?:\.\.?\/)*)?([^/?#]+\.html)([?#].*)?$/);
|
|
23
|
+
if (match && pageFiles.has(match[1])) anchor.setAttribute('href', destination(pageFiles.get(match[1])) + (match[2] || ''));
|
|
24
|
+
}
|
|
25
|
+
const scripted = [...document.querySelectorAll('script')].some(script => !['application/json', 'application/ld+json'].includes(script.getAttribute('type') || ''));
|
|
26
|
+
let needsListener = false;
|
|
27
|
+
for (const state of unit.states) for (const action of labels[state.stateId] || []) {
|
|
28
|
+
if (action.action === 'none') continue;
|
|
29
|
+
const target = stateById[action.target] ? destination(fileOf(action.target)) : null;
|
|
30
|
+
const element = document.getElementById(action.id);
|
|
31
|
+
if (action.action !== 'navigate' || !target || !element) {
|
|
32
|
+
unbound.push({ state: state.stateId, id: action.id, action: action.action, reason: 'local-page-requires-existing-route-navigation' }); continue;
|
|
33
|
+
}
|
|
34
|
+
const anchor = element.closest('a');
|
|
35
|
+
const nativeHref = anchor?.getAttribute('href');
|
|
36
|
+
if (nativeHref && nativeHref !== '#') continue; // Existing destination and event behavior wins.
|
|
37
|
+
if (scripted || element.closest('[onclick],[disabled],[aria-disabled="true"],form,[inert]')) {
|
|
38
|
+
unbound.push({ state: state.stateId, id: action.id, action: action.action, reason: 'local-page-preserves-existing-behavior' }); continue;
|
|
39
|
+
}
|
|
40
|
+
if (anchor) anchor.setAttribute('href', target);
|
|
41
|
+
else if (element.tagName.toLowerCase() === 'button') {
|
|
42
|
+
element.setAttribute('data-12ui-navigation-target', target); needsListener = true;
|
|
43
|
+
} else {
|
|
44
|
+
unbound.push({ state: state.stateId, id: action.id, action: action.action, reason: 'local-page-navigation-needs-native-control' }); continue;
|
|
45
|
+
}
|
|
46
|
+
actions.push({ id: action.id, action: 'navigate', target });
|
|
47
|
+
}
|
|
48
|
+
if (needsListener) document.head.insertAdjacentHTML('beforeend', `<script data-12ui-prototype-navigation>document.addEventListener('click',function(event){if(event.defaultPrevented||event.button!==0||event.metaKey||event.ctrlKey||event.shiftKey||event.altKey)return;var control=event.target.closest('[data-12ui-navigation-target]');if(!control||control.disabled)return;event.preventDefault();location.href=control.getAttribute('data-12ui-navigation-target');});</script>`);
|
|
49
|
+
return { actions, unbound };
|
|
50
|
+
}
|
|
@@ -6,6 +6,7 @@ const TYPES = new Map([
|
|
|
6
6
|
['.css', 'text/css; charset=utf-8'],
|
|
7
7
|
['.html', 'text/html; charset=utf-8'],
|
|
8
8
|
['.js', 'text/javascript; charset=utf-8'],
|
|
9
|
+
['.mjs', 'text/javascript; charset=utf-8'],
|
|
9
10
|
['.json', 'application/json; charset=utf-8'],
|
|
10
11
|
['.png', 'image/png'],
|
|
11
12
|
['.svg', 'image/svg+xml'],
|
|
@@ -1,73 +1,75 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: 12ui-design
|
|
3
|
-
description: "
|
|
3
|
+
description: "Design interfaces with 12ui, expand an approved screen into pages or app states, convert design images into editable code and assets, and improve existing applications. Use for non-trivial UI creation, image-to-code, and visual redesign."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# 12ui Design
|
|
7
7
|
|
|
8
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
|
-
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, and reference imagery as the deliverable to §5. Each command prints the next, and `12ui <command> --help` prints every
|
|
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, and reference imagery as the deliverable to §5. 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
|
-
The draft command uses
|
|
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
|
-
12ui draft --concept "<product, audience, surface, goal, personality;
|
|
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.
|
|
23
23
|
|
|
24
|
-
Draft
|
|
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
25
|
|
|
26
|
-
Only if needed, read
|
|
26
|
+
Only if needed, read [inspire.md](inspire.md) for direct corpus search.
|
|
27
27
|
|
|
28
28
|
## 2. Branch
|
|
29
29
|
|
|
30
|
-
|
|
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
31
|
|
|
32
|
-
12ui branch execute --start <image.png> --scope page|site --convert html --prototype --concept "<what the rest of the surface must cover
|
|
32
|
+
12ui branch execute --start <image.png> --scope page|site --convert html --prototype --concept "<what the rest of the surface must cover>"
|
|
33
33
|
|
|
34
|
-
`--scope page` grows
|
|
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
35
|
|
|
36
36
|
12ui next <run-dir> --wait
|
|
37
37
|
|
|
38
|
-
Execute stays in the foreground through its
|
|
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
39
|
|
|
40
|
-
Use `--prototype` with `--convert html`
|
|
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
41
|
|
|
42
|
-
Add `--polish` only when the user wants the
|
|
43
|
-
|
|
44
|
-
For a completed branch that was exported without the flag, run:
|
|
42
|
+
Add `--polish` only when the user wants the optional design-improvement pass. For an already converted branch:
|
|
45
43
|
|
|
46
44
|
12ui prototype <run-dir>
|
|
47
45
|
|
|
48
|
-
The same opt-in is available
|
|
46
|
+
The same opt-in is available as `12ui prototype <run-dir> --polish`.
|
|
49
47
|
|
|
50
48
|
## 3. Convert
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
For a single approved image, convert directly rather than branching.
|
|
53
51
|
|
|
54
|
-
12ui convert <source-image> --output
|
|
52
|
+
12ui convert <source-image> --output html --out-dir <run-dir>
|
|
55
53
|
|
|
56
|
-
|
|
54
|
+
Use the returned editable HTML/CSS and assets as the implementation baseline. Derive another supported output from the saved run or its output directory:
|
|
57
55
|
|
|
58
|
-
12ui convert <
|
|
56
|
+
12ui convert <run-dir-or-output-dir> --output assets|png|jpg|webp|pdf|react --out-dir <dir>
|
|
59
57
|
|
|
60
|
-
|
|
58
|
+
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.
|
|
61
59
|
|
|
62
60
|
## 4. Integrate and close
|
|
63
61
|
|
|
64
|
-
|
|
62
|
+
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.
|
|
63
|
+
|
|
64
|
+
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.
|
|
65
|
+
|
|
66
|
+
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:
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
12ui improve <implemented-url> --target <approved-screen.png> --repo <repo> --apply --out-dir <directory-outside-repo>
|
|
67
69
|
|
|
68
|
-
|
|
70
|
+
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.
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
Deliver openable code, assets, and observed limitations. State when rendering or application behavior remains unverified.
|
|
71
73
|
|
|
72
74
|
## 5. Search
|
|
73
75
|
|
|
@@ -75,20 +77,20 @@ Use this when reference imagery itself is the deliverable.
|
|
|
75
77
|
|
|
76
78
|
12ui corpus inspire --query "<product, audience, surface, goal, personality>" --out-dir <directory> --count 4 --reference-image <image.png>
|
|
77
79
|
|
|
78
|
-
Read
|
|
80
|
+
Read [inspire.md](inspire.md) for search modes, ranked manifest order, and interrupted-search recovery.
|
|
79
81
|
|
|
80
82
|
## 6. Improve
|
|
81
83
|
|
|
82
|
-
Use
|
|
84
|
+
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:
|
|
83
85
|
|
|
84
|
-
12ui improve <url
|
|
86
|
+
12ui improve <url> --repo <repo> --apply --out-dir <directory-outside-repo>
|
|
85
87
|
|
|
86
|
-
|
|
88
|
+
Without `--target`, the command drafts candidates and stops for a choice. Inspect the PNGs, choose the strongest fit, then continue the same run:
|
|
87
89
|
|
|
88
|
-
|
|
90
|
+
12ui improve <url> --repo <repo> --apply --out-dir <directory-outside-repo> --from pick --pick <slot>
|
|
89
91
|
|
|
90
|
-
|
|
92
|
+
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.
|
|
91
93
|
|
|
92
|
-
|
|
94
|
+
Only if needed, read [improve.md](improve.md) for controls, target preparation, site work, and kit use.
|
|
93
95
|
|
|
94
|
-
|
|
96
|
+
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.
|