@12ui/design 0.2.90 → 0.2.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/README.md +3 -3
  2. package/SKILL.md +1 -1
  3. package/codex-plugin/plugin.json +14 -14
  4. package/dist/agent-plugin-step.d.ts +3 -1
  5. package/dist/agent-plugin-step.d.ts.map +1 -1
  6. package/dist/agent-plugin-step.js +35 -6
  7. package/dist/agent-plugin-step.js.map +1 -1
  8. package/dist/branch-client.d.ts +8 -0
  9. package/dist/branch-client.d.ts.map +1 -1
  10. package/dist/branch-client.js.map +1 -1
  11. package/dist/branch-core/branch-canvas.d.ts +41 -0
  12. package/dist/branch-core/branch-canvas.d.ts.map +1 -0
  13. package/dist/branch-core/branch-canvas.js +87 -0
  14. package/dist/branch-core/branch-canvas.js.map +1 -0
  15. package/dist/branch-core/branch-gates.d.ts +62 -0
  16. package/dist/branch-core/branch-gates.d.ts.map +1 -0
  17. package/dist/branch-core/branch-gates.js +56 -0
  18. package/dist/branch-core/branch-gates.js.map +1 -0
  19. package/dist/branch-core/branch-plan-model.d.ts +115 -0
  20. package/dist/branch-core/branch-plan-model.d.ts.map +1 -0
  21. package/dist/branch-core/branch-plan-model.js +75 -0
  22. package/dist/branch-core/branch-plan-model.js.map +1 -0
  23. package/dist/branch-core/branch-planner.d.ts +78 -0
  24. package/dist/branch-core/branch-planner.d.ts.map +1 -0
  25. package/dist/branch-core/branch-planner.js +441 -0
  26. package/dist/branch-core/branch-planner.js.map +1 -0
  27. package/dist/branch-core/branch-prompt.d.ts +40 -0
  28. package/dist/branch-core/branch-prompt.d.ts.map +1 -0
  29. package/dist/branch-core/branch-prompt.js +180 -0
  30. package/dist/branch-core/branch-prompt.js.map +1 -0
  31. package/dist/branch-core/index.d.ts +17 -0
  32. package/dist/branch-core/index.d.ts.map +1 -0
  33. package/dist/branch-core/index.js +19 -0
  34. package/dist/branch-core/index.js.map +1 -0
  35. package/dist/branch-dispatch-loop.d.ts +2 -2
  36. package/dist/branch-dispatch-loop.d.ts.map +1 -1
  37. package/dist/branch-dispatch-loop.js +4 -0
  38. package/dist/branch-dispatch-loop.js.map +1 -1
  39. package/dist/branch-downloads.d.ts +2 -2
  40. package/dist/branch-downloads.d.ts.map +1 -1
  41. package/dist/branch-engine.d.ts +61 -0
  42. package/dist/branch-engine.d.ts.map +1 -0
  43. package/dist/branch-engine.js +94 -0
  44. package/dist/branch-engine.js.map +1 -0
  45. package/dist/branch-execution-types.d.ts +5 -0
  46. package/dist/branch-execution-types.d.ts.map +1 -1
  47. package/dist/branch-execution.d.ts +2 -2
  48. package/dist/branch-execution.d.ts.map +1 -1
  49. package/dist/branch-execution.js +27 -4
  50. package/dist/branch-execution.js.map +1 -1
  51. package/dist/branch-local-call-wait.d.ts +58 -0
  52. package/dist/branch-local-call-wait.d.ts.map +1 -0
  53. package/dist/branch-local-call-wait.js +122 -0
  54. package/dist/branch-local-call-wait.js.map +1 -0
  55. package/dist/branch-local-client.d.ts +108 -0
  56. package/dist/branch-local-client.d.ts.map +1 -0
  57. package/dist/branch-local-client.js +477 -0
  58. package/dist/branch-local-client.js.map +1 -0
  59. package/dist/branch-local-plan.d.ts +64 -0
  60. package/dist/branch-local-plan.d.ts.map +1 -0
  61. package/dist/branch-local-plan.js +281 -0
  62. package/dist/branch-local-plan.js.map +1 -0
  63. package/dist/branch-local-session-adoption.d.ts +35 -0
  64. package/dist/branch-local-session-adoption.d.ts.map +1 -0
  65. package/dist/branch-local-session-adoption.js +185 -0
  66. package/dist/branch-local-session-adoption.js.map +1 -0
  67. package/dist/branch-materialize.d.ts +2 -2
  68. package/dist/branch-materialize.d.ts.map +1 -1
  69. package/dist/branch-run-observation.d.ts +2 -2
  70. package/dist/branch-run-observation.d.ts.map +1 -1
  71. package/dist/branch-run-observation.js.map +1 -1
  72. package/dist/branch-run-record.d.ts +8 -0
  73. package/dist/branch-run-record.d.ts.map +1 -1
  74. package/dist/branch-run-record.js.map +1 -1
  75. package/dist/branch-schedule.d.ts +1 -1
  76. package/dist/branch-schedule.js +1 -1
  77. package/dist/cli-branch-command.d.ts +9 -2
  78. package/dist/cli-branch-command.d.ts.map +1 -1
  79. package/dist/cli-branch-command.js +61 -16
  80. package/dist/cli-branch-command.js.map +1 -1
  81. package/dist/cli-help/design.d.ts +1 -1
  82. package/dist/cli-help/design.d.ts.map +1 -1
  83. package/dist/cli-help/design.js +1 -0
  84. package/dist/cli-help/design.js.map +1 -1
  85. package/dist/cli-help/index.d.ts +1 -1
  86. package/dist/cli-local-dispatch.d.ts.map +1 -1
  87. package/dist/cli-local-dispatch.js +6 -2
  88. package/dist/cli-local-dispatch.js.map +1 -1
  89. package/dist/cli-next-command.d.ts.map +1 -1
  90. package/dist/cli-next-command.js +3 -1
  91. package/dist/cli-next-command.js.map +1 -1
  92. package/dist/cli-skill-command.d.ts.map +1 -1
  93. package/dist/cli-skill-command.js +3 -0
  94. package/dist/cli-skill-command.js.map +1 -1
  95. package/dist/cli-usage.js +1 -1
  96. package/dist/codex-plugin-installer.d.ts +7 -1
  97. package/dist/codex-plugin-installer.d.ts.map +1 -1
  98. package/dist/codex-plugin-installer.js +39 -63
  99. package/dist/codex-plugin-installer.js.map +1 -1
  100. package/dist/codex-skill-config.d.ts +33 -9
  101. package/dist/codex-skill-config.d.ts.map +1 -1
  102. package/dist/codex-skill-config.js +271 -104
  103. package/dist/codex-skill-config.js.map +1 -1
  104. package/dist/codex-toml.d.ts +15 -0
  105. package/dist/codex-toml.d.ts.map +1 -0
  106. package/dist/codex-toml.js +45 -0
  107. package/dist/codex-toml.js.map +1 -0
  108. package/dist/legacy-codex-cleanup.d.ts +4 -0
  109. package/dist/legacy-codex-cleanup.d.ts.map +1 -1
  110. package/dist/legacy-codex-cleanup.js +53 -32
  111. package/dist/legacy-codex-cleanup.js.map +1 -1
  112. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  113. package/dist/legacy-skill-catalog.js +10 -0
  114. package/dist/legacy-skill-catalog.js.map +1 -1
  115. package/dist/slate-branch-runner.d.ts +9 -3
  116. package/dist/slate-branch-runner.d.ts.map +1 -1
  117. package/dist/slate-branch-runner.js +22 -6
  118. package/dist/slate-branch-runner.js.map +1 -1
  119. package/dist/slate-image-executor.d.ts +1 -0
  120. package/dist/slate-image-executor.d.ts.map +1 -1
  121. package/dist/slate-image-executor.js +1 -1
  122. package/dist/slate-image-executor.js.map +1 -1
  123. package/dist/slate-runner-context.d.ts +6 -0
  124. package/dist/slate-runner-context.d.ts.map +1 -1
  125. package/dist/slate-runner-context.js.map +1 -1
  126. package/dist/slate-runner-main.d.ts +3 -0
  127. package/dist/slate-runner-main.d.ts.map +1 -1
  128. package/dist/slate-runner-main.js +4 -0
  129. package/dist/slate-runner-main.js.map +1 -1
  130. package/dist/workspace-draw-branch.d.ts +5 -2
  131. package/dist/workspace-draw-branch.d.ts.map +1 -1
  132. package/dist/workspace-draw-branch.js +28 -22
  133. package/dist/workspace-draw-branch.js.map +1 -1
  134. package/dist/workspace-draw-codex.d.ts +5 -1
  135. package/dist/workspace-draw-codex.d.ts.map +1 -1
  136. package/dist/workspace-draw-codex.js +1 -0
  137. package/dist/workspace-draw-codex.js.map +1 -1
  138. package/dist/workspace-draw-run.d.ts +2 -1
  139. package/dist/workspace-draw-run.d.ts.map +1 -1
  140. package/dist/workspace-draw-run.js +7 -2
  141. package/dist/workspace-draw-run.js.map +1 -1
  142. package/open-design.json +2 -2
  143. package/package.json +3 -2
  144. package/skills/12ui-design/outputs.md +1 -1
@@ -0,0 +1,441 @@
1
+ // GENERATED — do not edit. Copied verbatim from
2
+ // packages/layerdoc/src/branch-core by scripts/sync-improve-core.mjs.
3
+ /**
4
+ * The branch director, ported from Design Lab's `branchPlanner.ts`. One strict
5
+ * JSON call over the approved design decides the semantic structure of the
6
+ * branch: what the product is for, what the approved screen already says,
7
+ * whether that screen already ends, and which pages or routes complete it.
8
+ *
9
+ * Header, footer, and page-ending chrome are NEVER asked of the model — they
10
+ * are derived here from the surface type and the screen's position, so the
11
+ * model spends its inference on the design problem alone.
12
+ */
13
+ import { BRANCH_PAGE_TYPES, BRANCH_PLAN_SCHEMA_VERSION, BRANCH_SURFACE_TYPES, BRANCH_VIEWPORT_SLOT_TYPES, } from './branch-plan-model.js';
14
+ /** The branch planner's model: one low-effort structured call per run (owner rule 2026-10-03: GPT-6.1 Sol, never GPT-6 Sol). */
15
+ export const BUILD_PLAN_MODEL = 'gpt-6.1-sol';
16
+ /** The planner's fixed system text, sent ahead of `buildBranchPlannerPrompt`. */
17
+ export const BRANCH_PLANNER_SYSTEM_PROMPT = 'Plan the semantic structure of a website or application branched from one approved design. Obey the supplied JSON schema exactly and add no commentary.';
18
+ /**
19
+ * The brief as the planner reads it: whitespace runs collapsed and the ends
20
+ * trimmed, exactly as the create route cleans a build request's concept.
21
+ */
22
+ export const branchConceptText = (concept) => concept.replace(/\s+/gu, ' ').trim();
23
+ export const MIN_BRANCH_ADDITIONAL_PAGES = 0;
24
+ /** 12ui caps total cells at eight slots (a-h), so four pages of two fit. */
25
+ export const MAX_BRANCH_ADDITIONAL_PAGES = 4;
26
+ export const MIN_BRANCH_VIEWPORTS = 1;
27
+ export const MAX_BRANCH_VIEWPORTS = 2;
28
+ export const MAX_BRANCH_SOURCE_CONTINUATIONS = 2;
29
+ export const MAX_EDITORIAL_BRANCH_SOURCE_CONTINUATIONS = 4;
30
+ /** Slots a-h. The parser trims any plan that would exceed this. */
31
+ export const MAX_BRANCH_CELLS = 8;
32
+ const MAX_SITE_PURPOSE_TEXT = 240;
33
+ const MAX_BRANCH_STATUS_UPDATE_TEXT = 500;
34
+ const MAX_APPROVED_SUMMARY_TEXT = 600;
35
+ const MAX_PAGE_PURPOSE_TEXT = 240;
36
+ const MAX_PAGE_TITLE_TEXT = 120;
37
+ const MAX_SCREEN_CONTENT_TEXT = 480;
38
+ const viewportSchema = () => ({
39
+ type: 'object',
40
+ additionalProperties: false,
41
+ properties: {
42
+ content: {
43
+ type: 'string',
44
+ description: 'Concise semantic direction: what this screen contains and enables. Do not prescribe appearance, layout, colors, typography, spacing, imagery treatment, or composition.',
45
+ },
46
+ slotType: {
47
+ type: ['string', 'null'],
48
+ enum: [...BRANCH_VIEWPORT_SLOT_TYPES, null],
49
+ description: 'Editorial content role. Use text-column for sustained prose, text-with-graphic for prose with one necessary subject-specific diagram, conclusion-footer for closing prose plus one summary graphic and footer, and other only when those do not fit. Use null for non-editorial pages.',
50
+ },
51
+ targetWords: {
52
+ type: ['integer', 'null'],
53
+ description: 'Approximate replaceable prose capacity for an editorial viewport. Use null for non-editorial pages or when slotType is null.',
54
+ },
55
+ },
56
+ required: ['content', 'slotType', 'targetWords'],
57
+ });
58
+ const pageSchema = (maxViewports, source) => ({
59
+ type: 'object',
60
+ additionalProperties: false,
61
+ properties: {
62
+ title: { type: 'string' },
63
+ pageType: {
64
+ type: 'string',
65
+ enum: BRANCH_PAGE_TYPES,
66
+ description: 'Semantic page classification used to choose an appropriate information density.',
67
+ },
68
+ surfaceType: {
69
+ type: 'string',
70
+ enum: BRANCH_SURFACE_TYPES,
71
+ description: 'Structural screen model: a continuous webpage, a desktop web application, a mobile application, or an immersive full-screen experience.',
72
+ },
73
+ ...(source
74
+ ? {
75
+ sourceEndsHere: {
76
+ type: 'boolean',
77
+ description: 'Whether the approved source already reaches its natural ending. Use true when a webpage visibly closes with its footer, unless the original brief explicitly requests a long-form continuation on this same page; true otherwise requires no source continuations.',
78
+ },
79
+ }
80
+ : {}),
81
+ purpose: {
82
+ type: 'string',
83
+ description: 'The distinct job this page or application route performs, without visual direction.',
84
+ },
85
+ viewports: {
86
+ type: 'array',
87
+ description: source
88
+ ? `Continuations below the approved screen: up to ${MAX_EDITORIAL_BRANCH_SOURCE_CONTINUATIONS} when pageType is editorial, otherwise up to ${MAX_BRANCH_SOURCE_CONTINUATIONS}; empty when sourceEndsHere is true.`
89
+ : `${MIN_BRANCH_VIEWPORTS} to ${maxViewports} screens for this page or route.`,
90
+ items: viewportSchema(),
91
+ },
92
+ },
93
+ required: [
94
+ 'title',
95
+ 'pageType',
96
+ 'surfaceType',
97
+ ...(source ? ['sourceEndsHere'] : []),
98
+ 'purpose',
99
+ 'viewports',
100
+ ],
101
+ });
102
+ export const branchPlanResponseSchema = () => ({
103
+ type: 'json_schema',
104
+ name: 'create_branch_plan',
105
+ strict: true,
106
+ schema: {
107
+ type: 'object',
108
+ additionalProperties: false,
109
+ properties: {
110
+ sitePurpose: {
111
+ type: 'string',
112
+ description: 'The core visitor or user value in one short sentence.',
113
+ },
114
+ statusUpdate: {
115
+ type: 'string',
116
+ description: 'One or two concise first-person sentences for the user explaining what this branch will build and how the planned pages or routes form a coherent site or app. Do not mention internal planning, models, generation mechanics, implementation, or visual details.',
117
+ },
118
+ approvedScreenSummary: {
119
+ type: 'string',
120
+ description: 'Semantic summary of content and actions already present in the approved source. This is context to subtract, not content to repeat.',
121
+ },
122
+ sourcePage: pageSchema(MAX_EDITORIAL_BRANCH_SOURCE_CONTINUATIONS, true),
123
+ additionalPages: {
124
+ type: 'array',
125
+ description: `${MIN_BRANCH_ADDITIONAL_PAGES} to ${MAX_BRANCH_ADDITIONAL_PAGES} further pages or routes, each performing a distinct job. Return an empty list for a source-only continuation; at least one generated viewport is required across the whole plan.`,
126
+ items: pageSchema(MAX_BRANCH_VIEWPORTS, false),
127
+ },
128
+ },
129
+ required: ['sitePurpose', 'statusUpdate', 'approvedScreenSummary', 'sourcePage', 'additionalPages'],
130
+ },
131
+ });
132
+ /**
133
+ * The screen cap the caller asked for, clamped to what 12ui can dispatch.
134
+ * `maxScreens` is a plan-shaping hint (the CLI's `--max-screens`), so an
135
+ * absent or out-of-range value simply falls back to the eight-slot ceiling.
136
+ */
137
+ export const branchScreenCap = (maxScreens) => (Number.isSafeInteger(maxScreens) && maxScreens >= 1
138
+ ? Math.min(maxScreens, MAX_BRANCH_CELLS)
139
+ : MAX_BRANCH_CELLS);
140
+ const oneScreenPlanShape = (maxScreens) => (branchScreenCap(maxScreens) === 1
141
+ ? [
142
+ 'Exactly one generated screen can fit. Choose one source continuation with no additionalPages, or no source continuations and one additional page with one viewport, according to the brief.',
143
+ ]
144
+ : []);
145
+ /** A footer is not an ending when the brief explicitly keeps one long article on this page. */
146
+ export const branchBriefRequestsLongFormSamePage = (concept) => {
147
+ const normalized = concept.replace(/[‐‑‒–—]/gu, '-').replace(/\s+/gu, ' ').trim();
148
+ return (/\blong[- ]form\b.*\b(?:same|single)[ -]page\b/iu.test(normalized)
149
+ || /\b(?:same|single)[ -]page\b.*\blong[- ]form\b/iu.test(normalized));
150
+ };
151
+ export const buildBranchPlannerPrompt = (args) => {
152
+ if (branchBriefRequestsLongFormSamePage(args.concept) && branchScreenCap(args.maxScreens) === 1) {
153
+ throw new Error('An explicit long-form same-page branch needs more than the one-screen planning floor.');
154
+ }
155
+ return [
156
+ 'The attached image is the complete approved source design for one website or application.',
157
+ `Original brief: ${args.concept.trim() || '(not available; infer the product purpose from the approved source)'}`,
158
+ 'Plan a compact, coherent branch from that source. First decide whether the approved source already reaches its natural ending. If it visibly closes with a webpage footer, set sourceEndsHere to true and return no source continuations, unless the original brief explicitly requests a long-form continuation on this same page. Each additional page or route must perform a distinct job.',
159
+ ...(branchBriefRequestsLongFormSamePage(args.concept)
160
+ ? [
161
+ 'The original brief explicitly requests a long-form continuation on the same editorial page. A visible footer in the approved source is not the ending: set sourceEndsHere to false and plan the requested source continuations below it.',
162
+ 'When that brief calls for a prose section, a prose-with-graphic section, more sustained prose, and a conclusion with the real footer, keep them as four source continuations in this order: text-column, text-with-graphic, text-column, conclusion-footer. Do not combine the later prose and conclusion merely because the brief describes them together.',
163
+ ]
164
+ : []),
165
+ 'Set statusUpdate to one or two concise first-person sentences explaining what you chose to build out from the approved screen and how the pages or routes form a coherent site or app. Speak directly to the user. Do not mention internal planning, models, generation mechanics, implementation details, or visual decisions.',
166
+ 'The JSON schema separates content density, structural surface type, source completion, and short semantic content. Fill those fields only. Header, footer, and application-shell behavior will be derived deterministically from surfaceType.',
167
+ 'Use web_page for one continuous scrolling document, web_app for complete desktop application routes or states with a recurring application shell, mobile_app for complete mobile application screens or states, and immersive for full-screen editors, canvases, maps, media, games, or kiosks without assumed global chrome.',
168
+ 'Keep the branch on the form factor established by the approved source. Use mobile_app only when the approved source or original brief establishes a mobile product, not merely because one route could be imagined on a phone.',
169
+ `Plan at most ${branchScreenCap(args.maxScreens)} screens in total across the source continuations and the additional pages. Prefer fewer, stronger screens over filling the budget.`,
170
+ ...oneScreenPlanShape(args.maxScreens),
171
+ 'The image generator will separately receive the complete approved source and will decide how every screen looks. Never prescribe visual style, layout, component appearance, colors, typography, materials, spacing, atmosphere, camera choices, image treatment, or composition. Do not put header, footer, or application-shell instructions inside content.',
172
+ 'Treat the approved source as content already seen. Summarize it accurately, then avoid presenting its main promise, example subject, action, or featured image as new body content.',
173
+ 'Give each page or route a distinct purpose and each screen one main concept or one necessary task state. Do not pack a complete mini-site or whole workflow into every screen.',
174
+ 'Keep marketing and editorial screens restrained in information terms. Explanatory screens may contain one compact sequence. Directories, documentation, and applications may be denser only when choices, controls, results, evidence, or feedback are necessary to complete the task.',
175
+ `Editorial source pages may use up to ${MAX_EDITORIAL_BRANCH_SOURCE_CONTINUATIONS} continuations; every other source page remains limited to ${MAX_BRANCH_SOURCE_CONTINUATIONS}. For editorial viewports, set slotType and targetWords as a content-capacity contract. Use text-column for one sustained reading section, text-with-graphic only when the content names one concrete subject for a single diagram, conclusion-footer only for the closing passage and footer, and other only when none fits. For non-editorial viewports set both fields to null.`,
176
+ 'When an explicit long-form same-page brief asks for several reading regions, keep each sustained prose section in its own text-column viewport, keep any one subject-specific diagram in a text-with-graphic viewport, and reserve conclusion-footer for the final closing passage. Preserve the requested prose capacity in targetWords rather than converting it into cards, dashboards, feature grids, or callouts.',
177
+ 'Consecutive web_page sections must continue without repeating what was above. Consecutive web_app, mobile_app, or immersive states must preserve the selected item and entered context without restating the entire preceding state.',
178
+ 'For a two-screen directory, first support browsing with a concrete representative inventory, then carry one explicitly named selection forward. Name the inventory whenever the image model would otherwise have to invent it.',
179
+ 'When an ending routes into another page, explain why to continue and provide the onward action, but do not perform or preview the destination page\'s main task.',
180
+ 'Use concrete example subjects, records, destinations, projects, or result sets when the screen needs them. Choose new examples instead of defaulting to a subject prominently featured in the approved source. A genuinely necessary recurring subject still requires newly generated page-specific imagery later.',
181
+ 'Write each content field as one short natural paragraph, normally 20 to 45 words. Use ordinary language and never refer to page numbers, screen numbers, viewport ordinals, pixel coordinates, or visual layout.',
182
+ branchBriefRequestsLongFormSamePage(args.concept)
183
+ ? 'Follow the explicit same-page editorial direction in the original brief.'
184
+ : 'Follow the original brief when it specifies the expansion. For same-page continuations, keep additionalPages empty; choose additional routes only when they serve the requested product intent.',
185
+ 'Return the exact JSON schema with no commentary.',
186
+ ].join('\n\n');
187
+ };
188
+ const record = (value, label) => {
189
+ if (!value || typeof value !== 'object' || Array.isArray(value))
190
+ throw new Error(`${label} must be an object.`);
191
+ return value;
192
+ };
193
+ const text = (value, label, maximum) => {
194
+ if (typeof value !== 'string')
195
+ throw new Error(`${label} must be a string.`);
196
+ const normalized = value.replace(/\s+/gu, ' ').trim();
197
+ if (!normalized)
198
+ throw new Error(`${label} must not be empty.`);
199
+ // Over-length text is a recoverable representation defect: the decision the
200
+ // model made is intact, only its verbosity is not. Truncate rather than
201
+ // spend another paid call.
202
+ return normalized.length > maximum ? normalized.slice(0, maximum).trim() : normalized;
203
+ };
204
+ const pageTypeOf = (value) => (typeof value === 'string' && BRANCH_PAGE_TYPES.includes(value)
205
+ ? value
206
+ : 'other');
207
+ const surfaceTypeOf = (value, label) => {
208
+ if (typeof value !== 'string' || !BRANCH_SURFACE_TYPES.includes(value)) {
209
+ throw new Error(`${label} must be a supported surface type.`);
210
+ }
211
+ return value;
212
+ };
213
+ const editorialSlotContract = (item, label) => {
214
+ if ((item.slotType === undefined && item.targetWords === undefined)
215
+ || (item.slotType === null && item.targetWords === null))
216
+ return {};
217
+ if (typeof item.slotType !== 'string'
218
+ || !BRANCH_VIEWPORT_SLOT_TYPES.includes(item.slotType)) {
219
+ throw new Error(`${label}.slotType must be a supported editorial slot type or null.`);
220
+ }
221
+ if (!Number.isSafeInteger(item.targetWords) || item.targetWords < 1) {
222
+ throw new Error(`${label}.targetWords must be a positive whole number when slotType is set.`);
223
+ }
224
+ return {
225
+ slotType: item.slotType,
226
+ targetWords: item.targetWords,
227
+ };
228
+ };
229
+ const parseViewports = (value, label, maximum, pageType, anomalies) => {
230
+ if (!Array.isArray(value))
231
+ throw new Error(`${label} must be an array.`);
232
+ const viewports = value.map((entry, index) => {
233
+ const item = record(entry, `${label}[${index}]`);
234
+ return {
235
+ content: text(item.content, `${label}[${index}].content`, MAX_SCREEN_CONTENT_TEXT),
236
+ ...(pageType === 'editorial'
237
+ ? editorialSlotContract(item, `${label}[${index}]`)
238
+ : {}),
239
+ };
240
+ });
241
+ if (viewports.length > maximum) {
242
+ anomalies.push(`${label} returned ${viewports.length} screens; kept the first ${maximum}.`);
243
+ return viewports.slice(0, maximum);
244
+ }
245
+ return viewports;
246
+ };
247
+ const parseRawPage = (value, kind, label, anomalies, longFormSamePage) => {
248
+ const item = record(value, label);
249
+ const title = text(item.title, `${label}.title`, MAX_PAGE_TITLE_TEXT);
250
+ const purpose = text(item.purpose, `${label}.purpose`, MAX_PAGE_PURPOSE_TEXT);
251
+ const pageType = pageTypeOf(item.pageType);
252
+ const surfaceType = surfaceTypeOf(item.surfaceType, `${label}.surfaceType`);
253
+ const maximum = kind === 'source' && pageType === 'editorial'
254
+ ? MAX_EDITORIAL_BRANCH_SOURCE_CONTINUATIONS
255
+ : kind === 'source'
256
+ ? MAX_BRANCH_SOURCE_CONTINUATIONS
257
+ : MAX_BRANCH_VIEWPORTS;
258
+ const viewports = parseViewports(item.viewports, `${label}.viewports`, maximum, pageType, anomalies);
259
+ if (kind === 'additional' && viewports.length < MIN_BRANCH_VIEWPORTS) {
260
+ throw new Error(`${label}.viewports must contain at least ${MIN_BRANCH_VIEWPORTS} screen.`);
261
+ }
262
+ if (kind === 'source') {
263
+ if (longFormSamePage) {
264
+ if (pageType !== 'editorial') {
265
+ throw new Error(`${label}.pageType must be editorial for an explicit long-form same-page brief.`);
266
+ }
267
+ if (viewports.length === 0) {
268
+ throw new Error(`${label}.viewports must continue an explicit long-form same-page brief.`);
269
+ }
270
+ if (viewports.some((viewport) => viewport.slotType === undefined || viewport.targetWords === undefined)) {
271
+ throw new Error(`${label}.viewports must carry slotType and targetWords for an explicit long-form same-page brief.`);
272
+ }
273
+ }
274
+ // Cross-field invariant resolved deterministically rather than rejected:
275
+ // the boolean is the model's decision, the array is its representation.
276
+ const declaredEnd = item.sourceEndsHere === true;
277
+ if (declaredEnd && viewports.length > 0 && !longFormSamePage) {
278
+ anomalies.push('sourcePage.sourceEndsHere was true with continuations; dropped the continuations.');
279
+ viewports.length = 0;
280
+ }
281
+ else if (declaredEnd && longFormSamePage) {
282
+ anomalies.push('sourcePage.sourceEndsHere was true but the explicit long-form same-page brief overrides the visible-footer shortcut.');
283
+ }
284
+ const sourceEndsHere = longFormSamePage ? false : declaredEnd || viewports.length === 0;
285
+ if (!declaredEnd && sourceEndsHere) {
286
+ anomalies.push('sourcePage returned no continuations; treated the approved screen as already complete.');
287
+ }
288
+ return {
289
+ kind,
290
+ title,
291
+ pageType,
292
+ surfaceType,
293
+ purpose,
294
+ sourceEndsHere,
295
+ viewports,
296
+ };
297
+ }
298
+ return { kind, title, pageType, surfaceType, purpose, viewports };
299
+ };
300
+ /**
301
+ * ARBITRATION: the branch may plan more screens than the run has slots — the
302
+ * eight-slot ceiling, or a smaller cap the caller asked for. This is the ONE
303
+ * trim policy; it removes trailing screens — the last viewport of the latest
304
+ * multi-viewport page first, then whole trailing pages — so every surviving
305
+ * page keeps at least one screen and the earliest, most load-bearing screens
306
+ * are preserved. The floor is the source page plus one further page, so a cap
307
+ * below that floor leaves the floor standing. Plans at or below the cap are
308
+ * returned untouched.
309
+ */
310
+ const trimBranchPlanToCellCap = (pages, maxCells = MAX_BRANCH_CELLS) => {
311
+ const trimmed = pages.map((page) => ({ ...page, viewports: [...page.viewports] }));
312
+ const total = () => trimmed.reduce((sum, page) => sum + page.viewports.length, 0);
313
+ let removed = 0;
314
+ while (total() > maxCells) {
315
+ const multi = [...trimmed].reverse().find((page) => page.viewports.length > 1);
316
+ if (multi) {
317
+ multi.viewports.pop();
318
+ removed += 1;
319
+ continue;
320
+ }
321
+ // Every surviving page holds a single screen: drop whole trailing pages,
322
+ // never the source page and never the last remaining additional page.
323
+ if (trimmed.length <= 2)
324
+ break;
325
+ removed += trimmed[trimmed.length - 1].viewports.length;
326
+ trimmed.pop();
327
+ }
328
+ return { pages: trimmed, removed };
329
+ };
330
+ /**
331
+ * DERIVED CHROME. For web_page surfaces the header belongs to the first
332
+ * viewport of an ADDITIONAL page only (source continuations sit below an
333
+ * approved screen that already drew it), the footer belongs to the last
334
+ * viewport of every page, and pageEndsHere marks the last viewport of every
335
+ * page on every surface. Non-webpage surfaces carry null chrome.
336
+ */
337
+ const withDerivedChrome = (page, index) => {
338
+ const webpage = page.surfaceType === 'web_page';
339
+ const startOrdinal = page.kind === 'source' ? 2 : 1;
340
+ return {
341
+ index,
342
+ kind: page.kind,
343
+ title: page.title,
344
+ pageType: page.pageType,
345
+ surfaceType: page.surfaceType,
346
+ purpose: page.purpose,
347
+ ...(page.kind === 'source' ? { sourceEndsHere: page.sourceEndsHere === true } : {}),
348
+ viewports: page.viewports.map((viewport, viewportIndex) => ({
349
+ viewportOrdinal: startOrdinal + viewportIndex,
350
+ content: viewport.content,
351
+ ...(viewport.slotType
352
+ ? { contentSlotId: `content-p${index}-v${startOrdinal + viewportIndex}` }
353
+ : {}),
354
+ ...(viewport.slotType ? { slotType: viewport.slotType } : {}),
355
+ ...(viewport.targetWords !== undefined ? { targetWords: viewport.targetWords } : {}),
356
+ header: webpage ? startOrdinal === 1 && viewportIndex === 0 : null,
357
+ footer: webpage ? viewportIndex === page.viewports.length - 1 : null,
358
+ pageEndsHere: viewportIndex === page.viewports.length - 1,
359
+ })),
360
+ };
361
+ };
362
+ /**
363
+ * Deterministic parse of the director's JSON. Structural defects (not JSON,
364
+ * missing required decisions, no generated screens) reject so the bounded
365
+ * retry can run; recoverable representation defects (over-length text or
366
+ * arrays, contradictory sourceEndsHere, more screens than slots) are
367
+ * canonicalized here and recorded in `anomalies`.
368
+ *
369
+ * The SOURCE PAGE IS ALWAYS PLAN POSITION 0, including when the approved
370
+ * screen already ends: it names the design the branch grew from, so the board
371
+ * and the site export can place that approved screen at index.html. When it
372
+ * ends it carries `viewports: []` and `sourceEndsHere: true` while keeping the
373
+ * model's own title, pageType, surfaceType, and purpose. (A page dropped here
374
+ * cost the site its winner page: the export refused, or the run reported
375
+ * success with the approved design missing.) Additional pages still require at
376
+ * least one screen each.
377
+ *
378
+ * `maxCells` is the caller's screen cap (the CLI's `--max-screens`), clamped
379
+ * to the eight dispatchable slots. Trimming to it happens BEFORE chrome
380
+ * derivation and slot assignment, so every surviving page keeps at least one
381
+ * screen and the footer seed and dependency chains are computed on the plan
382
+ * that actually ships.
383
+ */
384
+ export const parseBranchPlan = (raw, options) => {
385
+ let parsed;
386
+ try {
387
+ parsed = JSON.parse(raw);
388
+ }
389
+ catch (error) {
390
+ throw new Error(`Branch planner returned invalid JSON: ${error instanceof Error ? error.message : String(error)}`);
391
+ }
392
+ const root = record(parsed, 'Branch plan');
393
+ const anomalies = [];
394
+ if (!Array.isArray(root.additionalPages)) {
395
+ throw new Error('additionalPages must be an array.');
396
+ }
397
+ let additional = root.additionalPages;
398
+ if (additional.length > MAX_BRANCH_ADDITIONAL_PAGES) {
399
+ anomalies.push(`additionalPages returned ${additional.length} pages; kept the first ${MAX_BRANCH_ADDITIONAL_PAGES}.`);
400
+ additional = additional.slice(0, MAX_BRANCH_ADDITIONAL_PAGES);
401
+ }
402
+ const longFormSamePage = options?.longFormSamePage === true;
403
+ const rawPages = [
404
+ parseRawPage(root.sourcePage, 'source', 'sourcePage', anomalies, longFormSamePage),
405
+ ...additional.map((page, index) => parseRawPage(page, 'additional', `additionalPages[${index}]`, anomalies, false)),
406
+ ];
407
+ const maxCells = branchScreenCap(options?.maxCells);
408
+ const trim = trimBranchPlanToCellCap(rawPages, maxCells);
409
+ if (trim.removed > 0) {
410
+ anomalies.push(`Trimmed ${trim.removed} planned screen(s) to the ${maxCells}-screen cap.`);
411
+ }
412
+ // `index` is the plan position, and position 0 is the source page whether or
413
+ // not it contributes screens of its own.
414
+ const pages = trim.pages.map((page, index) => withDerivedChrome(page, index));
415
+ const cellCount = pages.reduce((sum, page) => sum + page.viewports.length, 0);
416
+ if (cellCount < 1)
417
+ throw new Error('Branch plan contains no screens to generate.');
418
+ if (cellCount > maxCells) {
419
+ // The trim's floor — the source page plus one further page — outranks the
420
+ // requested cap; the caller's own guard may trim the dispatch further.
421
+ anomalies.push(`The ${maxCells}-screen cap is below the ${cellCount}-screen floor of a source page plus one further page; kept the floor.`);
422
+ }
423
+ return {
424
+ schemaVersion: BRANCH_PLAN_SCHEMA_VERSION,
425
+ sitePurpose: text(root.sitePurpose, 'sitePurpose', MAX_SITE_PURPOSE_TEXT),
426
+ statusUpdate: text(root.statusUpdate, 'statusUpdate', MAX_BRANCH_STATUS_UPDATE_TEXT),
427
+ approvedScreenSummary: text(root.approvedScreenSummary, 'approvedScreenSummary', MAX_APPROVED_SUMMARY_TEXT),
428
+ pages,
429
+ anomalies,
430
+ };
431
+ };
432
+ /**
433
+ * The options the planner's answer is parsed with for one brief and screen cap:
434
+ * the cap the director was asked for, and the long-form same-page rule the
435
+ * brief itself triggers.
436
+ */
437
+ export const branchPlanParseOptions = (concept, maxScreens) => ({
438
+ ...(maxScreens === undefined ? {} : { maxCells: maxScreens }),
439
+ ...(branchBriefRequestsLongFormSamePage(concept) ? { longFormSamePage: true } : {}),
440
+ });
441
+ //# sourceMappingURL=branch-planner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-planner.js","sourceRoot":"","sources":["../../src/branch-core/branch-planner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The per-screen image prompt, ported from Design Lab's
3
+ * `sessionBranchPrompt.ts`. It names what each attached image IS, states where
4
+ * the new screen sits in the page or application flow, carries the plan's
5
+ * semantic content, states the derived chrome contract, and forbids pasting
6
+ * reference pixels. It deliberately prescribes nothing visual: the approved
7
+ * source is the entire visual system.
8
+ */
9
+ import type { BranchCellPlacement, BranchPlan, BranchSurfaceType, BranchViewportSlotType } from './branch-plan-model.js';
10
+ export type BranchGenerationPromptInput = {
11
+ /** The plan's semantic direction for this one screen. */
12
+ content: string;
13
+ /** Editorial content role; absent on legacy and non-editorial plans. */
14
+ slotType?: BranchViewportSlotType;
15
+ /** Approximate replaceable prose capacity requested by the planner. */
16
+ targetWords?: number;
17
+ productPurpose: string;
18
+ pagePurpose: string;
19
+ pageKind: 'source' | 'additional';
20
+ pageTitle: string;
21
+ surfaceType: BranchSurfaceType;
22
+ viewportOrdinal: number;
23
+ lastViewportOrdinal: number;
24
+ pageEndsHere: boolean;
25
+ header: boolean | null;
26
+ footer: boolean | null;
27
+ hasDependencyReference: boolean;
28
+ hasFooterReference: boolean;
29
+ };
30
+ export declare const buildBranchGenerationPrompt: (input: BranchGenerationPromptInput) => string;
31
+ /**
32
+ * One branch screen's image prompt from the plan and its placement. The
33
+ * reference flags say which images actually arrive with the call, so the
34
+ * dispatcher rebuilds this from the references the gate released.
35
+ */
36
+ export declare const branchPromptFor: (plan: Pick<BranchPlan, "sitePurpose">, placement: BranchCellPlacement, references: {
37
+ hasDependencyReference: boolean;
38
+ hasFooterReference: boolean;
39
+ }) => string;
40
+ //# sourceMappingURL=branch-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-prompt.d.ts","sourceRoot":"","sources":["../../src/branch-core/branch-prompt.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,mBAAmB,EACnB,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,2BAA2B,GAAG;IACxC,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAClC,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,GAAG,YAAY,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,sBAAsB,EAAE,OAAO,CAAC;IAChC,kBAAkB,EAAE,OAAO,CAAC;CAC7B,CAAC;AAmJF,eAAO,MAAM,2BAA2B,GAAI,OAAO,2BAA2B,KAAG,MAgBhF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC1B,MAAM,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,EACrC,WAAW,mBAAmB,EAC9B,YAAY;IAAE,sBAAsB,EAAE,OAAO,CAAC;IAAC,kBAAkB,EAAE,OAAO,CAAA;CAAE,KAC3E,MAeD,CAAC"}