~cytrogen/gstack

ref: 9c5f479745acc90533a7ff75a00771b9056c43ef gstack/design/src/brief.ts -rw-r--r-- 1.9 KiB
9c5f4797 — Cytrogen fork: 频率分级路由 + 触发式描述符重写 2 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
 * Structured design brief — the interface between skill prose and image generation.
 */

export interface DesignBrief {
  goal: string;           // "Dashboard for coding assessment tool"
  audience: string;       // "Technical users, YC partners"
  style: string;          // "Dark theme, cream accents, minimal"
  elements: string[];     // ["builder name", "score badge", "narrative letter"]
  constraints?: string;   // "Max width 1024px, mobile-first"
  reference?: string;     // DESIGN.md excerpt or style reference text
  screenType: string;     // "desktop-dashboard" | "mobile-app" | "landing-page" | etc.
}

/**
 * Convert a structured brief to a prompt string for image generation.
 */
export function briefToPrompt(brief: DesignBrief): string {
  const lines: string[] = [
    `Generate a pixel-perfect UI mockup of a ${brief.screenType} for: ${brief.goal}.`,
    `Target audience: ${brief.audience}.`,
    `Visual style: ${brief.style}.`,
    `Required elements: ${brief.elements.join(", ")}.`,
  ];

  if (brief.constraints) {
    lines.push(`Constraints: ${brief.constraints}.`);
  }

  if (brief.reference) {
    lines.push(`Design reference: ${brief.reference}`);
  }

  lines.push(
    "The mockup should look like a real production UI, not a wireframe or concept art.",
    "All text must be readable. Layout must be clean and intentional.",
    "1536x1024 pixels."
  );

  return lines.join(" ");
}

/**
 * Parse a brief from either a plain text string or a JSON file path.
 */
export function parseBrief(input: string, isFile: boolean): string {
  if (!isFile) {
    // Plain text prompt — use directly
    return input;
  }

  // JSON file — parse and convert to prompt
  const raw = Bun.file(input);
  // We'll read it synchronously via fs since Bun.file is async
  const fs = require("fs");
  const content = fs.readFileSync(input, "utf-8");
  const brief: DesignBrief = JSON.parse(content);
  return briefToPrompt(brief);
}