maestro-flow 0.3.48 → 0.4.1
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 +231 -74
- package/.claude/commands/maestro-merge.md +3 -0
- package/.claude/commands/maestro-roadmap.md +5 -1
- package/.claude/commands/maestro.md +3 -3
- 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/.codex/skills/maestro/SKILL.md +70 -28
- 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 +230 -97
- 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-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/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 +107 -117
- 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-craft.md +0 -364
- package/.claude/commands/maestro-ui-design.md +0 -104
- package/.claude/skills/maestro-impeccable/SKILL.md +0 -169
- package/.codex/skills/maestro-ui-craft/SKILL.md +0 -341
- 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-
|
|
79
|
+
maestro-analyze / maestro-brainstorm / maestro-roadmap / maestro-impeccable → -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-
|
|
98
|
+
maestro-roadmap, maestro-impeccable, 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-
|
|
108
|
+
'ui_design': [{ cmd: 'maestro-impeccable', 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
|
-
'
|
|
154
|
-
{ cmd: 'maestro-
|
|
153
|
+
'impeccable-build': [
|
|
154
|
+
{ cmd: 'maestro-impeccable', 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}' }
|