maestro-flow 0.3.47 → 0.3.49

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 (94) hide show
  1. package/.claude/agents/impeccable-agent.md +99 -0
  2. package/.claude/commands/maestro-analyze.md +2 -2
  3. package/.claude/commands/maestro-brainstorm.md +116 -112
  4. package/.claude/commands/maestro-composer.md +5 -0
  5. package/.claude/commands/maestro-impeccable.md +46 -9
  6. package/.claude/commands/maestro-merge.md +3 -0
  7. package/.claude/commands/maestro-roadmap.md +5 -1
  8. package/.claude/commands/maestro-ui-craft.md +56 -4
  9. package/.claude/commands/maestro.md +1 -1
  10. package/.claude/commands/manage-issue-discover.md +4 -0
  11. package/.claude/commands/quality-refactor.md +3 -0
  12. package/.claude/skills/maestro-help/index/catalog.json +1 -1
  13. package/.claude/skills/maestro-help/phases/01-parse-intent.md +1 -1
  14. package/.claude/skills/maestro-impeccable/SKILL.md +3 -1
  15. package/.codex/skills/maestro/SKILL.md +167 -25
  16. package/.codex/skills/maestro-brainstorm/SKILL.md +19 -2
  17. package/.codex/skills/maestro-composer/SKILL.md +5 -0
  18. package/.codex/skills/maestro-help/catalog.json +1 -1
  19. package/.codex/skills/maestro-impeccable/SKILL.md +24 -5
  20. package/.codex/skills/maestro-merge/SKILL.md +3 -0
  21. package/.codex/skills/maestro-milestone-audit/SKILL.md +64 -7
  22. package/.codex/skills/maestro-quick/SKILL.md +1 -1
  23. package/.codex/skills/maestro-ralph/SKILL.md +45 -25
  24. package/.codex/skills/maestro-roadmap/SKILL.md +1 -1
  25. package/.codex/skills/maestro-tools-execute/SKILL.md +1 -1
  26. package/.codex/skills/maestro-tools-register/SKILL.md +1 -1
  27. package/.codex/skills/maestro-ui-craft/SKILL.md +51 -6
  28. package/.codex/skills/quality-refactor/SKILL.md +114 -22
  29. package/chains/_intent-map.json +1 -1
  30. package/chains/singles/ui-design.json +4 -4
  31. package/chains/{ui-design-driven.json → ui-craft-build.json} +8 -8
  32. package/dashboard/dist-server/dashboard/src/server/coordinator/chain-map.js +3 -3
  33. package/dashboard/dist-server/dashboard/src/server/coordinator/chain-map.js.map +1 -1
  34. package/dist/src/commands/delegate.d.ts.map +1 -1
  35. package/dist/src/commands/delegate.js +12 -7
  36. package/dist/src/commands/delegate.js.map +1 -1
  37. package/dist/src/commands/impeccable.d.ts +2 -1
  38. package/dist/src/commands/impeccable.d.ts.map +1 -1
  39. package/dist/src/commands/impeccable.js +80 -1
  40. package/dist/src/commands/impeccable.js.map +1 -1
  41. package/package.json +1 -1
  42. package/templates/planning-roles/ui-designer.md +86 -99
  43. package/templates/workflows/specs/node-catalog.md +1 -1
  44. package/workflows/brainstorm.md +26 -0
  45. package/workflows/cli-tools-usage.md +9 -26
  46. package/workflows/delegate-usage.md +301 -343
  47. package/workflows/impeccable/design.md +462 -0
  48. package/workflows/impeccable/explore.md +157 -0
  49. package/workflows/impeccable/shape.md +4 -0
  50. package/workflows/impeccable/ui-search/__pycache__/core.cpython-313.pyc +0 -0
  51. package/workflows/impeccable/ui-search/__pycache__/design_system.cpython-313.pyc +0 -0
  52. package/workflows/impeccable/ui-search/core.py +262 -0
  53. package/workflows/impeccable/ui-search/data/app-interface.csv +31 -0
  54. package/workflows/impeccable/ui-search/data/charts.csv +26 -0
  55. package/workflows/impeccable/ui-search/data/colors.csv +162 -0
  56. package/workflows/impeccable/ui-search/data/design.csv +1776 -0
  57. package/workflows/impeccable/ui-search/data/draft.csv +1779 -0
  58. package/workflows/impeccable/ui-search/data/google-fonts.csv +1924 -0
  59. package/workflows/impeccable/ui-search/data/icons.csv +106 -0
  60. package/workflows/impeccable/ui-search/data/landing.csv +35 -0
  61. package/workflows/impeccable/ui-search/data/products.csv +162 -0
  62. package/workflows/impeccable/ui-search/data/react-performance.csv +45 -0
  63. package/workflows/impeccable/ui-search/data/stacks/angular.csv +51 -0
  64. package/workflows/impeccable/ui-search/data/stacks/astro.csv +54 -0
  65. package/workflows/impeccable/ui-search/data/stacks/flutter.csv +53 -0
  66. package/workflows/impeccable/ui-search/data/stacks/html-tailwind.csv +56 -0
  67. package/workflows/impeccable/ui-search/data/stacks/jetpack-compose.csv +53 -0
  68. package/workflows/impeccable/ui-search/data/stacks/laravel.csv +51 -0
  69. package/workflows/impeccable/ui-search/data/stacks/nextjs.csv +53 -0
  70. package/workflows/impeccable/ui-search/data/stacks/nuxt-ui.csv +51 -0
  71. package/workflows/impeccable/ui-search/data/stacks/nuxtjs.csv +59 -0
  72. package/workflows/impeccable/ui-search/data/stacks/react-native.csv +52 -0
  73. package/workflows/impeccable/ui-search/data/stacks/react.csv +54 -0
  74. package/workflows/impeccable/ui-search/data/stacks/shadcn.csv +61 -0
  75. package/workflows/impeccable/ui-search/data/stacks/svelte.csv +54 -0
  76. package/workflows/impeccable/ui-search/data/stacks/swiftui.csv +51 -0
  77. package/workflows/impeccable/ui-search/data/stacks/threejs.csv +54 -0
  78. package/workflows/impeccable/ui-search/data/stacks/vue.csv +50 -0
  79. package/workflows/impeccable/ui-search/data/styles.csv +85 -0
  80. package/workflows/impeccable/ui-search/data/typography.csv +74 -0
  81. package/workflows/impeccable/ui-search/data/ui-reasoning.csv +162 -0
  82. package/workflows/impeccable/ui-search/data/ux-guidelines.csv +100 -0
  83. package/workflows/impeccable/ui-search/design_system.py +1148 -0
  84. package/workflows/impeccable/ui-search/prototype-template.html +511 -0
  85. package/workflows/impeccable/ui-search/render-prototype.js +208 -0
  86. package/workflows/impeccable/ui-search/search.py +114 -0
  87. package/workflows/maestro-chain-execute.md +2 -2
  88. package/workflows/maestro.codex.md +3 -3
  89. package/workflows/maestro.md +5 -5
  90. package/workflows/plan.md +1 -1
  91. package/workflows/ui-design.md +1 -1
  92. package/workflows/ui-style.md +1 -1
  93. package/.claude/commands/maestro-ui-design.md +0 -104
  94. package/.codex/skills/maestro-ui-design/SKILL.md +0 -242
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * render-prototype.js
4
+ *
5
+ * Reads one or more MASTER.md files and renders HTML prototypes by injecting
6
+ * extracted design tokens into prototype-template.html.
7
+ *
8
+ * Zero external dependencies — uses only Node.js built-ins.
9
+ *
10
+ * Usage:
11
+ * node render-prototype.js <master1.md> [master2.md ...] --output <dir> [--project <name>]
12
+ * node render-prototype.js --dir <folder-with-masters> --output <dir> [--project <name>]
13
+ *
14
+ * Output:
15
+ * <dir>/prototype_1.html, prototype_2.html, ...
16
+ */
17
+
18
+ const fs = require("fs");
19
+ const path = require("path");
20
+
21
+ // ---------------------------------------------------------------------------
22
+ // CLI argument parsing
23
+ // ---------------------------------------------------------------------------
24
+ function parseArgs(argv) {
25
+ const args = { files: [], output: "", project: "Project", dir: "" };
26
+ let i = 2; // skip node + script
27
+ while (i < argv.length) {
28
+ const a = argv[i];
29
+ if (a === "--output" || a === "-o") { args.output = argv[++i]; }
30
+ else if (a === "--project" || a === "-p") { args.project = argv[++i]; }
31
+ else if (a === "--dir" || a === "-d") { args.dir = argv[++i]; }
32
+ else if (!a.startsWith("-")) { args.files.push(a); }
33
+ i++;
34
+ }
35
+ // Expand --dir to individual files
36
+ if (args.dir && fs.existsSync(args.dir)) {
37
+ const entries = fs.readdirSync(args.dir)
38
+ .filter(f => f.endsWith(".md") && f.toUpperCase().includes("MASTER"))
39
+ .map(f => path.join(args.dir, f));
40
+ args.files.push(...entries);
41
+ }
42
+ return args;
43
+ }
44
+
45
+ // ---------------------------------------------------------------------------
46
+ // MASTER.md parser — extracts design tokens
47
+ // ---------------------------------------------------------------------------
48
+ function parseMaster(content) {
49
+ const tokens = {
50
+ projectName: "",
51
+ styleName: "",
52
+ colors: {},
53
+ fontHeading: "Inter",
54
+ fontBody: "Inter",
55
+ googleFontsUrl: "",
56
+ googleFontsLink: "",
57
+ };
58
+
59
+ // Project name
60
+ const projMatch = content.match(/\*\*Project:\*\*\s*(.+)/);
61
+ if (projMatch) tokens.projectName = projMatch[1].trim();
62
+
63
+ // Style name
64
+ const styleMatch = content.match(/\*\*Style:\*\*\s*(.+)/);
65
+ if (styleMatch) tokens.styleName = styleMatch[1].trim();
66
+
67
+ // Color palette table: | Role | `#hex` | `--css-var` |
68
+ const colorPattern = /\|\s*([^|]+?)\s*\|\s*`(#[0-9A-Fa-f]{3,8})`\s*\|\s*`(--[^`]+)`\s*\|/g;
69
+ let m;
70
+ while ((m = colorPattern.exec(content)) !== null) {
71
+ const cssVar = m[3].trim();
72
+ const hex = m[2].trim();
73
+ // Map --color-primary → primary
74
+ const key = cssVar.replace(/^--color-/, "");
75
+ tokens.colors[key] = hex;
76
+ }
77
+
78
+ // Typography
79
+ const headingMatch = content.match(/\*\*Heading Font:\*\*\s*(.+)/);
80
+ if (headingMatch) tokens.fontHeading = headingMatch[1].trim();
81
+
82
+ const bodyMatch = content.match(/\*\*Body Font:\*\*\s*(.+)/);
83
+ if (bodyMatch) tokens.fontBody = bodyMatch[1].trim();
84
+
85
+ // Google Fonts URL
86
+ const gfMatch = content.match(/\*\*Google Fonts:\*\*\s*\[.*?\]\((https:\/\/fonts\.googleapis\.com\/[^)]+)\)/);
87
+ if (gfMatch) {
88
+ tokens.googleFontsUrl = gfMatch[1];
89
+ tokens.googleFontsLink = `<link rel="preconnect" href="https://fonts.googleapis.com">\n <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>\n <link href="${gfMatch[1]}" rel="stylesheet">`;
90
+ } else {
91
+ // Fallback: build Google Fonts link from font names
92
+ const families = [tokens.fontHeading, tokens.fontBody]
93
+ .filter((v, i, a) => a.indexOf(v) === i) // unique
94
+ .map(f => `family=${f.replace(/\s+/g, "+")}:wght@400;500;600;700`)
95
+ .join("&");
96
+ const url = `https://fonts.googleapis.com/css2?${families}&display=swap`;
97
+ tokens.googleFontsLink = `<link rel="preconnect" href="https://fonts.googleapis.com">\n <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>\n <link href="${url}" rel="stylesheet">`;
98
+ }
99
+
100
+ // CSS import block (alternative font loading)
101
+ const cssImportMatch = content.match(/\*\*CSS Import:\*\*[\s\S]*?```css\n([\s\S]*?)```/);
102
+ if (cssImportMatch && !gfMatch) {
103
+ // Extract URL from @import
104
+ const importUrl = cssImportMatch[1].match(/url\(['"]?(https:\/\/[^'")\s]+)['"]?\)/);
105
+ if (importUrl) {
106
+ tokens.googleFontsLink = `<link rel="preconnect" href="https://fonts.googleapis.com">\n <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>\n <link href="${importUrl[1]}" rel="stylesheet">`;
107
+ }
108
+ }
109
+
110
+ return tokens;
111
+ }
112
+
113
+ // ---------------------------------------------------------------------------
114
+ // Template rendering
115
+ // ---------------------------------------------------------------------------
116
+ function render(template, tokens, projectOverride) {
117
+ const project = projectOverride || tokens.projectName || "Project";
118
+ const colors = tokens.colors;
119
+
120
+ let html = template
121
+ .replace(/\{\{PROJECT_NAME\}\}/g, project)
122
+ .replace(/\{\{STYLE_NAME\}\}/g, tokens.styleName || "Default")
123
+ .replace(/\{\{GOOGLE_FONTS_LINK\}\}/g, tokens.googleFontsLink || "")
124
+ .replace(/\{\{FONT_HEADING\}\}/g, tokens.fontHeading)
125
+ .replace(/\{\{FONT_BODY\}\}/g, tokens.fontBody)
126
+ .replace(/\{\{COLOR_PRIMARY\}\}/g, colors.primary || "#2563EB")
127
+ .replace(/\{\{COLOR_ON_PRIMARY\}\}/g, colors["on-primary"] || "#FFFFFF")
128
+ .replace(/\{\{COLOR_SECONDARY\}\}/g, colors.secondary || "#7C3AED")
129
+ .replace(/\{\{COLOR_ACCENT\}\}/g, colors["accent"] || colors["accent/cta"] || "#F97316")
130
+ .replace(/\{\{COLOR_BACKGROUND\}\}/g, colors.background || "#FFFFFF")
131
+ .replace(/\{\{COLOR_FOREGROUND\}\}/g, colors.foreground || "#1E293B")
132
+ .replace(/\{\{COLOR_MUTED\}\}/g, colors.muted || "#94A3B8")
133
+ .replace(/\{\{COLOR_BORDER\}\}/g, colors.border || "#E2E8F0")
134
+ .replace(/\{\{COLOR_DESTRUCTIVE\}\}/g, colors.destructive || "#EF4444")
135
+ .replace(/\{\{COLOR_RING\}\}/g, colors.ring || "#3B82F6");
136
+
137
+ return html;
138
+ }
139
+
140
+ // ---------------------------------------------------------------------------
141
+ // Main
142
+ // ---------------------------------------------------------------------------
143
+ function main() {
144
+ const args = parseArgs(process.argv);
145
+
146
+ if (args.files.length === 0) {
147
+ console.error("Usage: node render-prototype.js <master1.md> [master2.md ...] --output <dir> [--project <name>]");
148
+ console.error(" node render-prototype.js --dir <folder> --output <dir> [--project <name>]");
149
+ process.exit(1);
150
+ }
151
+
152
+ if (!args.output) {
153
+ console.error("Error: --output <dir> is required");
154
+ process.exit(1);
155
+ }
156
+
157
+ // Load template
158
+ const templatePath = path.join(__dirname, "prototype-template.html");
159
+ if (!fs.existsSync(templatePath)) {
160
+ console.error(`Error: Template not found at ${templatePath}`);
161
+ process.exit(1);
162
+ }
163
+ const template = fs.readFileSync(templatePath, "utf-8");
164
+
165
+ // Ensure output directory
166
+ fs.mkdirSync(args.output, { recursive: true });
167
+
168
+ const results = [];
169
+
170
+ for (let i = 0; i < args.files.length; i++) {
171
+ const file = args.files[i];
172
+ if (!fs.existsSync(file)) {
173
+ console.error(`Warning: ${file} not found, skipping`);
174
+ continue;
175
+ }
176
+
177
+ const content = fs.readFileSync(file, "utf-8");
178
+ const tokens = parseMaster(content);
179
+ const html = render(template, tokens, args.project);
180
+
181
+ const label = String.fromCharCode(65 + i); // A, B, C, ...
182
+ const outName = `prototype_${label}.html`;
183
+ const outPath = path.join(args.output, outName);
184
+ fs.writeFileSync(outPath, html, "utf-8");
185
+
186
+ results.push({
187
+ file: outName,
188
+ style: tokens.styleName,
189
+ fonts: `${tokens.fontHeading} + ${tokens.fontBody}`,
190
+ colors: Object.keys(tokens.colors).length,
191
+ });
192
+
193
+ console.log(` [${label}] ${outName} — ${tokens.styleName} (${tokens.fontHeading}/${tokens.fontBody}, ${Object.keys(tokens.colors).length} colors)`);
194
+ }
195
+
196
+ // Write manifest for downstream tools
197
+ const manifestPath = path.join(args.output, "manifest.json");
198
+ fs.writeFileSync(manifestPath, JSON.stringify({
199
+ generated: new Date().toISOString(),
200
+ project: args.project,
201
+ prototypes: results,
202
+ }, null, 2), "utf-8");
203
+
204
+ console.log(`\n ${results.length} prototype(s) written to ${args.output}/`);
205
+ console.log(` manifest: ${manifestPath}`);
206
+ }
207
+
208
+ main();
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ UI/UX Pro Max Search - BM25 search engine for UI/UX style guides
5
+ Usage: python search.py "<query>" [--domain <domain>] [--stack <stack>] [--max-results 3]
6
+ python search.py "<query>" --design-system [-p "Project Name"]
7
+ python search.py "<query>" --design-system --persist [-p "Project Name"] [--page "dashboard"]
8
+
9
+ Domains: style, prompt, color, chart, landing, product, ux, typography, google-fonts
10
+ Stacks: react, nextjs, vue, svelte, astro, swiftui, react-native, flutter, nuxtjs, nuxt-ui, html-tailwind, shadcn, jetpack-compose, threejs
11
+
12
+ Persistence (Master + Overrides pattern):
13
+ --persist Save design system to design-system/MASTER.md
14
+ --page Also create a page-specific override file in design-system/pages/
15
+ """
16
+
17
+ import argparse
18
+ import sys
19
+ import io
20
+ from core import CSV_CONFIG, AVAILABLE_STACKS, MAX_RESULTS, search, search_stack
21
+ from design_system import generate_design_system, persist_design_system
22
+
23
+ # Force UTF-8 for stdout/stderr to handle emojis on Windows (cp1252 default)
24
+ if sys.stdout.encoding and sys.stdout.encoding.lower() != 'utf-8':
25
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
26
+ if sys.stderr.encoding and sys.stderr.encoding.lower() != 'utf-8':
27
+ sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
28
+
29
+
30
+ def format_output(result):
31
+ """Format results for Claude consumption (token-optimized)"""
32
+ if "error" in result:
33
+ return f"Error: {result['error']}"
34
+
35
+ output = []
36
+ if result.get("stack"):
37
+ output.append(f"## UI Pro Max Stack Guidelines")
38
+ output.append(f"**Stack:** {result['stack']} | **Query:** {result['query']}")
39
+ else:
40
+ output.append(f"## UI Pro Max Search Results")
41
+ output.append(f"**Domain:** {result['domain']} | **Query:** {result['query']}")
42
+ output.append(f"**Source:** {result['file']} | **Found:** {result['count']} results\n")
43
+
44
+ for i, row in enumerate(result['results'], 1):
45
+ output.append(f"### Result {i}")
46
+ for key, value in row.items():
47
+ value_str = str(value)
48
+ if len(value_str) > 300:
49
+ value_str = value_str[:300] + "..."
50
+ output.append(f"- **{key}:** {value_str}")
51
+ output.append("")
52
+
53
+ return "\n".join(output)
54
+
55
+
56
+ if __name__ == "__main__":
57
+ parser = argparse.ArgumentParser(description="UI Pro Max Search")
58
+ parser.add_argument("query", help="Search query")
59
+ parser.add_argument("--domain", "-d", choices=list(CSV_CONFIG.keys()), help="Search domain")
60
+ parser.add_argument("--stack", "-s", choices=AVAILABLE_STACKS, help=f"Stack-specific search. Available: {', '.join(AVAILABLE_STACKS)}")
61
+ parser.add_argument("--max-results", "-n", type=int, default=MAX_RESULTS, help="Max results (default: 3)")
62
+ parser.add_argument("--json", action="store_true", help="Output as JSON")
63
+ # Design system generation
64
+ parser.add_argument("--design-system", "-ds", action="store_true", help="Generate complete design system recommendation")
65
+ parser.add_argument("--project-name", "-p", type=str, default=None, help="Project name for design system output")
66
+ parser.add_argument("--format", "-f", choices=["ascii", "markdown"], default="ascii", help="Output format for design system")
67
+ # Persistence (Master + Overrides pattern)
68
+ parser.add_argument("--persist", action="store_true", help="Save design system to design-system/MASTER.md (creates hierarchical structure)")
69
+ parser.add_argument("--page", type=str, default=None, help="Create page-specific override file in design-system/pages/")
70
+ parser.add_argument("--output-dir", "-o", type=str, default=None, help="Output directory for persisted files (default: current directory)")
71
+
72
+ args = parser.parse_args()
73
+
74
+ # Design system takes priority
75
+ if args.design_system:
76
+ result = generate_design_system(
77
+ args.query,
78
+ args.project_name,
79
+ args.format,
80
+ persist=args.persist,
81
+ page=args.page,
82
+ output_dir=args.output_dir
83
+ )
84
+ print(result)
85
+
86
+ # Print persistence confirmation
87
+ if args.persist:
88
+ project_slug = args.project_name.lower().replace(' ', '-') if args.project_name else "default"
89
+ print("\n" + "=" * 60)
90
+ print(f"✅ Design system persisted to design-system/{project_slug}/")
91
+ print(f" 📄 design-system/{project_slug}/MASTER.md (Global Source of Truth)")
92
+ if args.page:
93
+ page_filename = args.page.lower().replace(' ', '-')
94
+ print(f" 📄 design-system/{project_slug}/pages/{page_filename}.md (Page Overrides)")
95
+ print("")
96
+ print(f"📖 Usage: When building a page, check design-system/{project_slug}/pages/[page].md first.")
97
+ print(f" If exists, its rules override MASTER.md. Otherwise, use MASTER.md.")
98
+ print("=" * 60)
99
+ # Stack search
100
+ elif args.stack:
101
+ result = search_stack(args.query, args.stack, args.max_results)
102
+ if args.json:
103
+ import json
104
+ print(json.dumps(result, indent=2, ensure_ascii=False))
105
+ else:
106
+ print(format_output(result))
107
+ # Domain search
108
+ else:
109
+ result = search(args.query, args.domain, args.max_results)
110
+ if args.json:
111
+ import json
112
+ print(json.dumps(result, indent=2, ensure_ascii=False))
113
+ else:
114
+ print(format_output(result))
@@ -76,7 +76,7 @@ context = {
76
76
  {milestone_num} → context.milestone_num
77
77
 
78
78
  2. In auto_mode, append per-command flag if not already present:
79
- maestro-analyze / maestro-brainstorm / maestro-roadmap / maestro-ui-design → -y
79
+ maestro-analyze / maestro-brainstorm / maestro-roadmap / maestro-ui-craft → -y
80
80
  maestro-plan → --auto
81
81
  quality-test → --auto-fix
82
82
  quality-retrospective → --auto-yes
@@ -95,7 +95,7 @@ Read `step.engine` from status.json (pre-computed by selection workflow Step 3e)
95
95
  If `step.engine` is missing or null, fallback to auto selection:
96
96
  ```
97
97
  CLI: maestro-plan, maestro-execute, maestro-analyze, maestro-brainstorm,
98
- maestro-roadmap, maestro-ui-design, quality-refactor
98
+ maestro-roadmap, maestro-ui-craft, quality-refactor
99
99
  Internal: everything else (current-session Skill() call)
100
100
  ```
101
101
 
@@ -105,7 +105,7 @@ const chainMap = {
105
105
  'status': [{ cmd: 'manage-status' }],
106
106
  'init': [{ cmd: 'maestro-init' }],
107
107
  'analyze': [{ cmd: 'maestro-analyze', args: '{phase}' }],
108
- 'ui_design': [{ cmd: 'maestro-ui-design', args: '{phase}' }],
108
+ 'ui_design': [{ cmd: 'maestro-ui-craft', args: '"{phase}" --chain build' }],
109
109
  'plan': [{ cmd: 'maestro-plan', args: '{phase}' }],
110
110
  'execute': [{ cmd: 'maestro-execute', args: '{phase}' }],
111
111
  'verify': [{ cmd: 'maestro-verify', args: '{phase}' }],
@@ -150,8 +150,8 @@ const chainMap = {
150
150
  { cmd: 'maestro-execute', args: '{phase}' },
151
151
  { cmd: 'maestro-verify', args: '{phase}' }
152
152
  ],
153
- 'ui-design-driven': [
154
- { cmd: 'maestro-ui-design', args: '{phase}' },
153
+ 'ui-craft-build': [
154
+ { cmd: 'maestro-ui-craft', args: '"{phase}" --chain build' },
155
155
  { cmd: 'maestro-plan', args: '{phase}' },
156
156
  { cmd: 'maestro-execute', args: '{phase}' },
157
157
  { cmd: 'maestro-verify', args: '{phase}' }
@@ -233,7 +233,7 @@ Step type is selected **per step**, not per chain. Pre-compute and write to each
233
233
  ```
234
234
  If execMode is 'cli' or 'internal' → force that type for all steps ("cli" or "skill").
235
235
  In 'auto' mode, select per step:
236
- CLI steps (heavy, context-isolated): maestro-plan, maestro-execute, maestro-analyze, maestro-brainstorm, maestro-roadmap, maestro-ui-design, quality-refactor → type: "cli"
236
+ CLI steps (heavy, context-isolated): maestro-plan, maestro-execute, maestro-analyze, maestro-brainstorm, maestro-roadmap, maestro-ui-craft, quality-refactor → type: "cli"
237
237
  Skill steps (everything else): current-session Skill() call — verify, review, test, debug, milestone-*, manage-*, spec-*, quick, etc. → type: "skill"
238
238
  ```
239
239
 
@@ -318,7 +318,7 @@ const chainMap = {
318
318
  'init': [{ cmd: 'maestro-init' }],
319
319
  'analyze': [{ cmd: 'maestro-analyze', args: '{phase}' }],
320
320
  'analyze-quick': [{ cmd: 'maestro-analyze', args: '{phase} -q' }],
321
- 'ui_design': [{ cmd: 'maestro-ui-design', args: '{phase}' }],
321
+ 'ui_design': [{ cmd: 'maestro-ui-craft', args: '"{description}" --chain build' }],
322
322
  'ui_craft': [{ cmd: 'maestro-ui-craft', args: '"{description}"' }],
323
323
  'ui_craft_build': [{ cmd: 'maestro-ui-craft', args: '"{description}" --chain build' }],
324
324
  'ui_craft_improve': [{ cmd: 'maestro-ui-craft', args: '"{description}" --chain improve' }],
@@ -370,7 +370,7 @@ const chainMap = {
370
370
  'spec-driven': [{ cmd: 'maestro-init' }, { cmd: 'maestro-roadmap', args: '--mode full "{description}"' }, { cmd: 'maestro-plan', args: '{phase}' }, { cmd: 'maestro-execute', args: '{phase}' }, { cmd: 'maestro-verify', args: '{phase}' }],
371
371
  'roadmap-driven': [{ cmd: 'maestro-init' }, { cmd: 'maestro-roadmap', args: '"{description}"' }, { cmd: 'maestro-plan', args: '{phase}' }, { cmd: 'maestro-execute', args: '{phase}' }, { cmd: 'maestro-verify', args: '{phase}' }],
372
372
  'brainstorm-driven': [{ cmd: 'maestro-brainstorm', args: '"{description}"' }, { cmd: 'maestro-plan', args: '{phase}' }, { cmd: 'maestro-execute', args: '{phase}' }, { cmd: 'maestro-verify', args: '{phase}' }],
373
- 'ui-design-driven': [{ cmd: 'maestro-ui-design', args: '{phase}' }, { cmd: 'maestro-plan', args: '{phase}' }, { cmd: 'maestro-execute', args: '{phase}' }, { cmd: 'maestro-verify', args: '{phase}' }],
373
+ 'ui-craft-build': [{ cmd: 'maestro-ui-craft', args: '"{description}" --chain build' }, { cmd: 'maestro-plan', args: '{phase}' }, { cmd: 'maestro-execute', args: '{phase}' }, { cmd: 'maestro-verify', args: '{phase}' }],
374
374
  'ui-craft-driven': [{ cmd: 'maestro-ui-craft', args: '"{description}" --chain build' }, { cmd: 'maestro-verify', args: '{phase}' }],
375
375
  'analyze-plan-execute': [{ cmd: 'maestro-analyze', args: '"{description}" -q' }, { cmd: 'maestro-plan', args: '--dir {scratch_dir}' }, { cmd: 'maestro-execute', args: '--dir {scratch_dir}' }],
376
376
  'execute-verify': [{ cmd: 'maestro-execute', args: '{phase}' }, { cmd: 'maestro-verify', args: '{phase}' }],
@@ -440,7 +440,7 @@ detectNextAction(state):
440
440
  | `spec-driven` | init → spec-generate → plan → execute → verify | From idea/requirements (heavy) |
441
441
  | `roadmap-driven` | init → roadmap → plan → execute → verify | From requirements (light) |
442
442
  | `brainstorm-driven` | brainstorm → plan → execute → verify | From exploration |
443
- | `ui-design-driven` | ui-design → plan → execute → verify | From UI prototypes |
443
+ | `ui-craft-build` | ui-craft --chain build → plan → execute → verify | From design system generation |
444
444
  | `analyze-plan-execute` | analyze -q → plan --dir → execute --dir | Fast track (scratch mode) |
445
445
  | `execute-verify` | execute → verify | Resume after planning |
446
446
  | `review-fix` | plan --gaps → execute → review | Fix review-blocked issues |
@@ -470,7 +470,7 @@ detectNextAction(state):
470
470
  | `"discover issues"` | `{explore, issue}` | issue_discover | manage-issue-discover |
471
471
  | `"brainstorm notifications"` | `{explore, feature}` | brainstorm | brainstorm-driven |
472
472
  | `"spec generate auth"` | `{create, spec}` | spec_generate | spec-driven |
473
- | `"ui design landing"` | `{create, ui}` | ui_design | ui-design-driven |
473
+ | `"ui design landing"` | `{create, ui}` | ui_design | ui-craft-build |
474
474
  | `"refactor auth module"` | `{refactor, code}` | refactor | quality-refactor |
475
475
  | `"复盘 phase 2"` | `{retrospect, phase}` | retrospective | quality-retrospective |
476
476
  | `"team review code"` | `{review, team}` | team_review | team-review |
package/workflows/plan.md CHANGED
@@ -84,7 +84,7 @@ default → Create Mode: P1 → P2 → P3 → P4 → P4.5 → P5
84
84
  4b. **Load design reference** (if available)
85
85
  - If `${PHASE_DIR}/design-ref/MASTER.md` exists: load MASTER.md, design-tokens.json, animation-tokens.json (optional), layout-templates/layout-*.json
86
86
  - Every UI task must include in `read_first[]`: design-tokens.json, animation-tokens.json, relevant layout-*.json, MASTER.md
87
- - Else if phase goal matches UI keywords (`landing|page|dashboard|frontend|UI|component|界面`): suggest running `maestro-ui-design` (non-blocking)
87
+ - Else if phase goal matches UI keywords (`landing|page|dashboard|frontend|UI|component|界面`): suggest running `maestro-ui-craft --chain build` (non-blocking)
88
88
 
89
89
  5. **Load upstream analysis** (if available)
90
90
  - If `${PHASE_DIR}/conclusions.json` exists with non-empty status: load as explorationContext (conclusions + explorations.json + perspectives.json)
@@ -364,7 +364,7 @@ Spacing & Layout, Effects & Interactions, Component Styles, Animation System, An
364
364
 
365
365
  `maestro-plan` P1 (Context Collection):
366
366
  - If `${PHASE_DIR}/design-ref/MASTER.md` exists: load as planner context, add `design-tokens.json`, `layout-templates/layout-*.json`, `animation-tokens.json` to UI task `read_first[]`
367
- - If missing + phase goal has UI keywords: suggest `maestro-ui-design` (non-blocking)
367
+ - If missing + phase goal has UI keywords: suggest `maestro-ui-craft --chain build` (non-blocking)
368
368
 
369
369
  ---
370
370
 
@@ -169,7 +169,7 @@ If the design needs exceed ui-ux-pro-max capabilities (e.g., multi-layout matrix
169
169
 
170
170
  ```
171
171
  For advanced multi-layer design exploration:
172
- Skill({ skill: "maestro-ui-design", args: "{phase} --full" })
172
+ /maestro-ui-craft --chain build {target}
173
173
  ```
174
174
 
175
175
  ---
@@ -1,104 +0,0 @@
1
- ---
2
- name: maestro-ui-design
3
- description: Generate UI design prototypes, select and solidify as code
4
- argument-hint: "<phase|topic> [--styles N] [--stack <stack>] [--targets <pages>] [--layouts N] [--refine] [--persist] [--full] [-y]"
5
- allowed-tools:
6
- - Read
7
- - Write
8
- - Edit
9
- - Bash
10
- - Glob
11
- - Grep
12
- - Agent
13
- - AskUserQuestion
14
- ---
15
- <purpose>
16
- Generate UI design prototypes for a phase or topic. Two workflow paths, auto-selected by skill availability:
17
-
18
- 1. **Primary (ui-style.md):** Delegates design to ui-ux-pro-max skill. Generates multiple style variants via `--design-system`, user selects, solidifies as code reference. Lightweight and fast.
19
- 2. **Fallback (ui-design.md):** Self-contained 4-layer pipeline (style → animation → layout → assembly) with 6D attribute space, OKLCH tokens, layout templates, and full prototype matrix. Used when ui-ux-pro-max is unavailable or `--full` is requested.
20
-
21
- Both paths produce the same output contract: MASTER.md + design-tokens.json + animation-tokens.json + selection.json for downstream plan/execute consumption.
22
-
23
- Position in pipeline: analyze -> **ui-design** -> plan -> execute -> verify
24
- </purpose>
25
-
26
- <deferred_reading>
27
- - [ui-style.md](~/.maestro/workflows/ui-style.md) — read when SKILL_PATH found (primary path)
28
- - [ui-design.md](~/.maestro/workflows/ui-design.md) — read when SKILL_PATH empty or --full (fallback path)
29
- - [index.json](~/.maestro/templates/index.json) — read when updating phase metadata
30
- - [scratch-index.json](~/.maestro/templates/scratch-index.json) — read when operating in scratch mode
31
- </deferred_reading>
32
-
33
- <context>
34
- $ARGUMENTS — phase number for phase mode, topic text for scratch mode, with optional flags.
35
-
36
- Flags, workflow routing, scope modes, and output artifacts defined in the routed workflow (ui-style.md or ui-design.md).
37
-
38
- **Phase mode** (number): resolves phase directory, reads context.md/brainstorm for requirements.
39
- **Scratch mode** (text): creates `.workflow/scratch/{YYYYMMDD}-ui-design-{slug}/` for standalone exploration.
40
- </context>
41
-
42
- <execution>
43
- ## 1. Load UI Specs
44
-
45
- Load project UI conventions before generating designs:
46
-
47
- ```bash
48
- maestro spec load --category ui
49
- ```
50
-
51
- If specs not initialized, continue without — the workflow still produces valid output.
52
-
53
- ## 2. Workflow Routing
54
-
55
- Detect ui-ux-pro-max skill availability and route to the appropriate workflow:
56
-
57
- - **`--full` flag present** → Follow '~/.maestro/workflows/ui-design.md' completely (forced full pipeline)
58
- - **ui-ux-pro-max found** → Follow '~/.maestro/workflows/ui-style.md' completely (lightweight delegation)
59
- - **ui-ux-pro-max not found** → Follow '~/.maestro/workflows/ui-design.md' completely (self-contained fallback)
60
-
61
- Skill detection logic, report format, and complete pipeline steps defined in the routed workflow file.
62
-
63
- **Next-step routing on completion:**
64
- - Plan with design reference → /maestro-plan {phase}
65
- - Refine selected design → /maestro-ui-design {phase} --refine
66
- - Analyze before planning → /maestro-analyze {phase}
67
- </execution>
68
-
69
- <error_codes>
70
- | Code | Severity | Description | Stage |
71
- |------|----------|-------------|-------|
72
- | E001 | error | Phase or topic argument required | parse_input |
73
- | E002 | error | Phase directory not found | parse_input |
74
- | E003 | error | Python not available (both paths need Python for ui-ux-pro-max or agent fallback) | setup |
75
- | E004 | error | --refine requires existing design-ref/ | parse_input |
76
- | W001 | warning | Design system generation returned partial results | generate |
77
- | W002 | warning | Prototype rendering failed for one variant | render |
78
- | W003 | warning | No context.md found, using phase goal only | context |
79
- | W004 | warning | ui-ux-pro-max not found, falling back to full pipeline | routing |
80
- </error_codes>
81
-
82
- <success_criteria>
83
- **Both paths (common):**
84
- - [ ] UI specs loaded via `spec load --category ui` (if available)
85
- - [ ] Requirements extracted from phase context (context.md, brainstorm, spec, or user input)
86
- - [ ] N style variants generated with contrasting design directions
87
- - [ ] User selected preferred variant (or auto-selected in -y mode)
88
- - [ ] MASTER.md written with complete design system specification
89
- - [ ] design-tokens.json written with production-ready tokens (OKLCH colors, component_styles)
90
- - [ ] animation-tokens.json written (duration, easing, transitions, keyframes)
91
- - [ ] selection.json recorded with choice metadata
92
- - [ ] index.json updated with design_ref status
93
-
94
- **ui-style.md path (primary):**
95
- - [ ] ui-ux-pro-max --design-system called with product/industry/style keywords
96
- - [ ] Tokens extracted from ui-ux-pro-max output into structured JSON
97
-
98
- **ui-design.md path (--full or fallback):**
99
- - [ ] 6D attribute space used for maximum contrast between variants
100
- - [ ] Layout templates generated per target (dom_structure + css_layout_rules)
101
- - [ ] HTML prototypes assembled: styles x layouts x targets
102
- - [ ] compare.html generated as interactive matrix viewer
103
- </success_criteria>
104
- </output>