brand-intent 0.4.4 → 0.5.0
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/package.json +1 -1
- package/parser/purposeParser.ts +25 -2
package/package.json
CHANGED
package/parser/purposeParser.ts
CHANGED
|
@@ -35,6 +35,8 @@ export interface ParsedPurpose {
|
|
|
35
35
|
defaultVideo?: string;
|
|
36
36
|
/** When false, hides Take Photo / Upload buttons for this purpose. Default: true. */
|
|
37
37
|
camera?: boolean;
|
|
38
|
+
/** When false, photo/video analysis skips this purpose (no AI text generation). Default: true. */
|
|
39
|
+
analyze?: boolean;
|
|
38
40
|
/** Default icon (Phosphor PascalCase name, e.g. "ArrowRight"). */
|
|
39
41
|
defaultIcon?: string;
|
|
40
42
|
/** Default icon weight. */
|
|
@@ -48,6 +50,8 @@ export interface ParsedPurposeSlot {
|
|
|
48
50
|
label: string;
|
|
49
51
|
/** Sample text variants for this slot. Picked randomly on page creation. */
|
|
50
52
|
samples: string[];
|
|
53
|
+
/** Fixed value — when set, this slot is never AI-generated or shuffled. Mutually exclusive with samples. */
|
|
54
|
+
value?: string;
|
|
51
55
|
maxLength: number;
|
|
52
56
|
/** 'text' (default) or 'list'. */
|
|
53
57
|
slotType?: 'text' | 'list';
|
|
@@ -63,6 +67,8 @@ export interface ParsedPurposeSlot {
|
|
|
63
67
|
itemGap?: number;
|
|
64
68
|
/** List layout direction: 'vertical' (default) or 'horizontal'. */
|
|
65
69
|
listDirection?: 'vertical' | 'horizontal';
|
|
70
|
+
/** When true, this slot is editable by the user in consume mode. Default: false. */
|
|
71
|
+
editable?: boolean;
|
|
66
72
|
typography: {
|
|
67
73
|
fontFamily: string;
|
|
68
74
|
fontWeight: number;
|
|
@@ -122,6 +128,7 @@ export function parsePurposeFile(content: string, fileName: string): ParsedPurpo
|
|
|
122
128
|
let defaultPhoto: string | undefined;
|
|
123
129
|
let defaultVideo: string | undefined;
|
|
124
130
|
let camera: boolean | undefined;
|
|
131
|
+
let analyze: boolean | undefined;
|
|
125
132
|
let defaultIcon: string | undefined;
|
|
126
133
|
let defaultIconWeight: string | undefined;
|
|
127
134
|
let bgPrompt: string | undefined;
|
|
@@ -143,7 +150,7 @@ export function parsePurposeFile(content: string, fileName: string): ParsedPurpo
|
|
|
143
150
|
const s = currentSlot;
|
|
144
151
|
if (!s.id) throw new Error(`${fileName}:${lineNum}: slot missing id`);
|
|
145
152
|
if (!s.label) throw new Error(`${fileName}:${lineNum}: slot "${s.id}" missing label`);
|
|
146
|
-
if ((!s.samples || s.samples.length === 0) && !s.iconOnly) throw new Error(`${fileName}:${lineNum}: slot "${s.id}" missing samples`);
|
|
153
|
+
if ((!s.samples || s.samples.length === 0) && !s.iconOnly && !s.value) throw new Error(`${fileName}:${lineNum}: slot "${s.id}" missing samples or value`);
|
|
147
154
|
if (!s.maxLength) throw new Error(`${fileName}:${lineNum}: slot "${s.id}" missing maxLength`);
|
|
148
155
|
const t = s.typography as ParsedPurposeSlot['typography'];
|
|
149
156
|
if (!s.typographyRef) {
|
|
@@ -296,6 +303,12 @@ export function parsePurposeFile(content: string, fileName: string): ParsedPurpo
|
|
|
296
303
|
continue;
|
|
297
304
|
}
|
|
298
305
|
|
|
306
|
+
// Photo/video analysis control
|
|
307
|
+
if (line.startsWith('analyze:')) {
|
|
308
|
+
analyze = line.slice(8).trim() !== 'false';
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
|
|
299
312
|
// Background placeholder prompt: "bg-prompt: Mach dein Selfie"
|
|
300
313
|
if (line.startsWith('bg-prompt:')) {
|
|
301
314
|
bgPrompt = line.slice(10).trim().replace(/^["']|["']$/g, '');
|
|
@@ -501,6 +514,14 @@ export function parsePurposeFile(content: string, fileName: string): ParsedPurpo
|
|
|
501
514
|
currentSlot.label = prop.slice(6).trim();
|
|
502
515
|
continue;
|
|
503
516
|
}
|
|
517
|
+
if (prop.startsWith('value:')) {
|
|
518
|
+
const val = prop.slice(6).trim();
|
|
519
|
+
if (!val) throw new Error(`${fileName}:${lineNum}: empty value`);
|
|
520
|
+
currentSlot.value = val;
|
|
521
|
+
// value implies a single-entry samples array for backward compat
|
|
522
|
+
currentSlot.samples = [val];
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
504
525
|
if (prop.startsWith('samples:')) {
|
|
505
526
|
const raw = prop.slice(8).trim();
|
|
506
527
|
if (!raw) {
|
|
@@ -526,6 +547,8 @@ export function parsePurposeFile(content: string, fileName: string): ParsedPurpo
|
|
|
526
547
|
currentSlot.colorRef = prop.slice(6).trim();
|
|
527
548
|
continue;
|
|
528
549
|
}
|
|
550
|
+
if (prop === 'editable' || prop === 'editable: true' || prop === 'editable:true') { currentSlot.editable = true; continue; }
|
|
551
|
+
if (prop === 'editable: false' || prop === 'editable:false') { currentSlot.editable = false; continue; }
|
|
529
552
|
if (prop.startsWith('font:')) {
|
|
530
553
|
// "Die Grotesk 800" → family="Die Grotesk", weight=800 (legacy direct path)
|
|
531
554
|
const value = prop.slice(5).trim();
|
|
@@ -601,5 +624,5 @@ export function parsePurposeFile(content: string, fileName: string): ParsedPurpo
|
|
|
601
624
|
context = contextLines.join('\n').trim();
|
|
602
625
|
}
|
|
603
626
|
|
|
604
|
-
return { id, name, description, preferredCompositions: compositions, slots, density, palette, scope, context, voice, defaultLogo, defaultPhoto, defaultVideo, camera, defaultIcon, defaultIconWeight, bgPrompt };
|
|
627
|
+
return { id, name, description, preferredCompositions: compositions, slots, density, palette, scope, context, voice, defaultLogo, defaultPhoto, defaultVideo, camera, analyze, defaultIcon, defaultIconWeight, bgPrompt };
|
|
605
628
|
}
|