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.
- package/.claude/agents/impeccable-agent.md +99 -0
- package/.claude/commands/maestro-analyze.md +2 -2
- package/.claude/commands/maestro-brainstorm.md +116 -112
- package/.claude/commands/maestro-composer.md +5 -0
- package/.claude/commands/maestro-impeccable.md +46 -9
- package/.claude/commands/maestro-merge.md +3 -0
- package/.claude/commands/maestro-roadmap.md +5 -1
- package/.claude/commands/maestro-ui-craft.md +56 -4
- package/.claude/commands/maestro.md +1 -1
- package/.claude/commands/manage-issue-discover.md +4 -0
- package/.claude/commands/quality-refactor.md +3 -0
- package/.claude/skills/maestro-help/index/catalog.json +1 -1
- package/.claude/skills/maestro-help/phases/01-parse-intent.md +1 -1
- package/.claude/skills/maestro-impeccable/SKILL.md +3 -1
- package/.codex/skills/maestro/SKILL.md +167 -25
- package/.codex/skills/maestro-brainstorm/SKILL.md +19 -2
- package/.codex/skills/maestro-composer/SKILL.md +5 -0
- package/.codex/skills/maestro-help/catalog.json +1 -1
- package/.codex/skills/maestro-impeccable/SKILL.md +24 -5
- package/.codex/skills/maestro-merge/SKILL.md +3 -0
- package/.codex/skills/maestro-milestone-audit/SKILL.md +64 -7
- package/.codex/skills/maestro-quick/SKILL.md +1 -1
- package/.codex/skills/maestro-ralph/SKILL.md +45 -25
- package/.codex/skills/maestro-roadmap/SKILL.md +1 -1
- package/.codex/skills/maestro-tools-execute/SKILL.md +1 -1
- package/.codex/skills/maestro-tools-register/SKILL.md +1 -1
- package/.codex/skills/maestro-ui-craft/SKILL.md +51 -6
- package/.codex/skills/quality-refactor/SKILL.md +114 -22
- package/chains/_intent-map.json +1 -1
- package/chains/singles/ui-design.json +4 -4
- package/chains/{ui-design-driven.json → ui-craft-build.json} +8 -8
- package/dashboard/dist-server/dashboard/src/server/coordinator/chain-map.js +3 -3
- package/dashboard/dist-server/dashboard/src/server/coordinator/chain-map.js.map +1 -1
- package/dist/src/commands/delegate.d.ts.map +1 -1
- package/dist/src/commands/delegate.js +12 -7
- package/dist/src/commands/delegate.js.map +1 -1
- package/dist/src/commands/impeccable.d.ts +2 -1
- package/dist/src/commands/impeccable.d.ts.map +1 -1
- package/dist/src/commands/impeccable.js +80 -1
- package/dist/src/commands/impeccable.js.map +1 -1
- package/package.json +1 -1
- package/templates/planning-roles/ui-designer.md +86 -99
- package/templates/workflows/specs/node-catalog.md +1 -1
- package/workflows/brainstorm.md +26 -0
- package/workflows/cli-tools-usage.md +9 -26
- package/workflows/delegate-usage.md +301 -343
- package/workflows/impeccable/design.md +462 -0
- package/workflows/impeccable/explore.md +157 -0
- package/workflows/impeccable/shape.md +4 -0
- package/workflows/impeccable/ui-search/__pycache__/core.cpython-313.pyc +0 -0
- package/workflows/impeccable/ui-search/__pycache__/design_system.cpython-313.pyc +0 -0
- package/workflows/impeccable/ui-search/core.py +262 -0
- package/workflows/impeccable/ui-search/data/app-interface.csv +31 -0
- package/workflows/impeccable/ui-search/data/charts.csv +26 -0
- package/workflows/impeccable/ui-search/data/colors.csv +162 -0
- package/workflows/impeccable/ui-search/data/design.csv +1776 -0
- package/workflows/impeccable/ui-search/data/draft.csv +1779 -0
- package/workflows/impeccable/ui-search/data/google-fonts.csv +1924 -0
- package/workflows/impeccable/ui-search/data/icons.csv +106 -0
- package/workflows/impeccable/ui-search/data/landing.csv +35 -0
- package/workflows/impeccable/ui-search/data/products.csv +162 -0
- package/workflows/impeccable/ui-search/data/react-performance.csv +45 -0
- package/workflows/impeccable/ui-search/data/stacks/angular.csv +51 -0
- package/workflows/impeccable/ui-search/data/stacks/astro.csv +54 -0
- package/workflows/impeccable/ui-search/data/stacks/flutter.csv +53 -0
- package/workflows/impeccable/ui-search/data/stacks/html-tailwind.csv +56 -0
- package/workflows/impeccable/ui-search/data/stacks/jetpack-compose.csv +53 -0
- package/workflows/impeccable/ui-search/data/stacks/laravel.csv +51 -0
- package/workflows/impeccable/ui-search/data/stacks/nextjs.csv +53 -0
- package/workflows/impeccable/ui-search/data/stacks/nuxt-ui.csv +51 -0
- package/workflows/impeccable/ui-search/data/stacks/nuxtjs.csv +59 -0
- package/workflows/impeccable/ui-search/data/stacks/react-native.csv +52 -0
- package/workflows/impeccable/ui-search/data/stacks/react.csv +54 -0
- package/workflows/impeccable/ui-search/data/stacks/shadcn.csv +61 -0
- package/workflows/impeccable/ui-search/data/stacks/svelte.csv +54 -0
- package/workflows/impeccable/ui-search/data/stacks/swiftui.csv +51 -0
- package/workflows/impeccable/ui-search/data/stacks/threejs.csv +54 -0
- package/workflows/impeccable/ui-search/data/stacks/vue.csv +50 -0
- package/workflows/impeccable/ui-search/data/styles.csv +85 -0
- package/workflows/impeccable/ui-search/data/typography.csv +74 -0
- package/workflows/impeccable/ui-search/data/ui-reasoning.csv +162 -0
- package/workflows/impeccable/ui-search/data/ux-guidelines.csv +100 -0
- package/workflows/impeccable/ui-search/design_system.py +1148 -0
- package/workflows/impeccable/ui-search/prototype-template.html +511 -0
- package/workflows/impeccable/ui-search/render-prototype.js +208 -0
- package/workflows/impeccable/ui-search/search.py +114 -0
- package/workflows/maestro-chain-execute.md +2 -2
- package/workflows/maestro.codex.md +3 -3
- package/workflows/maestro.md +5 -5
- package/workflows/plan.md +1 -1
- package/workflows/ui-design.md +1 -1
- package/workflows/ui-style.md +1 -1
- package/.claude/commands/maestro-ui-design.md +0 -104
- 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-
|
|
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-
|
|
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-
|
|
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-
|
|
154
|
-
{ cmd: 'maestro-ui-
|
|
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}' }
|
package/workflows/maestro.md
CHANGED
|
@@ -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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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)
|
package/workflows/ui-design.md
CHANGED
|
@@ -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-
|
|
367
|
+
- If missing + phase goal has UI keywords: suggest `maestro-ui-craft --chain build` (non-blocking)
|
|
368
368
|
|
|
369
369
|
---
|
|
370
370
|
|
package/workflows/ui-style.md
CHANGED
|
@@ -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
|
-
|
|
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>
|