@torka/claude-workflows 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -105
- package/examples/settings.local.example.json +0 -39
- package/install.js +3 -7
- package/package.json +2 -12
- package/skills/designer-founder/steps/step-01-context.md +171 -0
- package/skills/designer-founder/steps/step-01b-continue.md +75 -0
- package/skills/designer-founder/steps/step-02-scope.md +198 -0
- package/skills/designer-founder/steps/step-03-design.md +168 -0
- package/skills/designer-founder/steps/step-04-artifacts.md +292 -0
- package/skills/designer-founder/templates/component-strategy.md +35 -0
- package/skills/designer-founder/templates/design-brief.md +26 -0
- package/skills/designer-founder/templates/layouts.md +41 -0
- package/skills/designer-founder/templates/user-journeys.md +32 -0
- package/skills/designer-founder/tools/conversion.md +275 -0
- package/skills/designer-founder/tools/direct-mapping.md +222 -0
- package/skills/designer-founder/tools/magicpatterns.md +193 -0
- package/skills/designer-founder/tools/superdesign-assets/generate-theme.ts +193 -0
- package/skills/designer-founder/tools/superdesign-assets/superdesign-agent-instructions.md +375 -0
- package/skills/designer-founder/tools/superdesign.md +167 -0
- package/skills/designer-founder/tools/wireframe.md +181 -0
- package/skills/designer-founder/workflow.md +85 -0
- package/uninstall.js +40 -8
- package/hooks/auto_approve_safe.py +0 -261
- package/hooks/auto_approve_safe.rules.json +0 -134
- package/scripts/context-monitor.py +0 -175
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# MagicPatterns Tool Execution
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
MagicPatterns is an AI design tool that generates React components directly. Requires MagicPatterns MCP to be configured.
|
|
6
|
+
|
|
7
|
+
**Output:** React component code + hosted design URL
|
|
8
|
+
**MCP Tools Used:** `create_design`, `get_design`, `read_files`, `update_design`
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Prerequisites
|
|
13
|
+
|
|
14
|
+
Check MCP availability:
|
|
15
|
+
```
|
|
16
|
+
MagicPatterns MCP: [check if mcp__magicpatterns tools available]
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
If not available, inform user:
|
|
20
|
+
```
|
|
21
|
+
MagicPatterns MCP is not configured.
|
|
22
|
+
|
|
23
|
+
To use MagicPatterns:
|
|
24
|
+
1. Configure MCP server (see magicpatterns.com/docs)
|
|
25
|
+
2. Or use MagicPatterns directly in browser and share the URL
|
|
26
|
+
|
|
27
|
+
Alternative options:
|
|
28
|
+
[S] SuperDesign - HTML/CSS prototype
|
|
29
|
+
[W] Wireframe - Structure first
|
|
30
|
+
[D] Direct - Map to components directly
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Execution Flow
|
|
36
|
+
|
|
37
|
+
### 1. Frame Design Prompt
|
|
38
|
+
|
|
39
|
+
Construct prompt from context:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
{user_intent}
|
|
43
|
+
|
|
44
|
+
Requirements:
|
|
45
|
+
- Use React with TypeScript
|
|
46
|
+
- Tailwind CSS for styling
|
|
47
|
+
- Responsive design (mobile-first)
|
|
48
|
+
- {additional_context_from_scope}
|
|
49
|
+
|
|
50
|
+
Style:
|
|
51
|
+
- {inspiration_notes}
|
|
52
|
+
- Clean, modern aesthetic
|
|
53
|
+
- Consistent with shadcn/ui patterns
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 2. Create Design
|
|
57
|
+
|
|
58
|
+
Use MCP tool:
|
|
59
|
+
```
|
|
60
|
+
Tool: create_design
|
|
61
|
+
Parameters:
|
|
62
|
+
prompt: "{constructed_prompt}"
|
|
63
|
+
imageUrls: [{inspiration_image_urls}] // optional
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 3. Present Result
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
DESIGN CREATED
|
|
70
|
+
|
|
71
|
+
Preview URL: {preview_url}
|
|
72
|
+
Editor URL: {editor_url}
|
|
73
|
+
|
|
74
|
+
Please review the design in MagicPatterns.
|
|
75
|
+
|
|
76
|
+
Options:
|
|
77
|
+
[U] Update - Request changes
|
|
78
|
+
[R] Read Code - Extract React component code
|
|
79
|
+
[V] View Files - List available files
|
|
80
|
+
[C] Continue - Design is approved
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 4. Handle User Selection
|
|
84
|
+
|
|
85
|
+
**If U (Update):**
|
|
86
|
+
|
|
87
|
+
Ask what changes are needed:
|
|
88
|
+
```
|
|
89
|
+
What changes would you like to make?
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Use MCP tool:
|
|
93
|
+
```
|
|
94
|
+
Tool: update_design
|
|
95
|
+
Parameters:
|
|
96
|
+
url: "{design_url}"
|
|
97
|
+
prompt: "{user_change_request}"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Return to step 3 after update completes.
|
|
101
|
+
|
|
102
|
+
**If V (View Files):**
|
|
103
|
+
|
|
104
|
+
Use MCP tool:
|
|
105
|
+
```
|
|
106
|
+
Tool: get_design
|
|
107
|
+
Parameters:
|
|
108
|
+
url: "{design_url}"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Present file list:
|
|
112
|
+
```
|
|
113
|
+
Available files in design:
|
|
114
|
+
- {file_1}
|
|
115
|
+
- {file_2}
|
|
116
|
+
- ...
|
|
117
|
+
|
|
118
|
+
Which files would you like to read? [comma-separated list or 'all']
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**If R (Read Code):**
|
|
122
|
+
|
|
123
|
+
First get file list if not already retrieved:
|
|
124
|
+
```
|
|
125
|
+
Tool: get_design
|
|
126
|
+
Parameters:
|
|
127
|
+
url: "{design_url}"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Then read files:
|
|
131
|
+
```
|
|
132
|
+
Tool: read_files
|
|
133
|
+
Parameters:
|
|
134
|
+
url: "{design_url}"
|
|
135
|
+
fileNames: [{selected_files}]
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Present code:
|
|
139
|
+
```
|
|
140
|
+
REACT CODE EXTRACTED
|
|
141
|
+
|
|
142
|
+
{file_contents}
|
|
143
|
+
|
|
144
|
+
Options:
|
|
145
|
+
[S] Save - Store code for artifact generation
|
|
146
|
+
[A] Adjust - Request changes
|
|
147
|
+
[C] Continue - Code is approved
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**If C (Continue):**
|
|
151
|
+
- Store design URL and any extracted code
|
|
152
|
+
- Return control to parent step
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Output State
|
|
157
|
+
|
|
158
|
+
After completion, set:
|
|
159
|
+
|
|
160
|
+
```yaml
|
|
161
|
+
design:
|
|
162
|
+
tool_used: magicpatterns
|
|
163
|
+
output_location: "{design_url}"
|
|
164
|
+
output_format: react
|
|
165
|
+
needs_conversion: false # Already React
|
|
166
|
+
extracted_code:
|
|
167
|
+
files:
|
|
168
|
+
- name: "{filename}"
|
|
169
|
+
content: "{code}"
|
|
170
|
+
design_id: "{id_from_url}"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Using MagicPatterns for Conversion
|
|
176
|
+
|
|
177
|
+
MagicPatterns can also convert existing designs (from SuperDesign HTML) to React:
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
Tool: create_design
|
|
181
|
+
Parameters:
|
|
182
|
+
prompt: "Convert this HTML design to React components with Tailwind CSS:
|
|
183
|
+
[describe the HTML structure]
|
|
184
|
+
|
|
185
|
+
Requirements:
|
|
186
|
+
- TypeScript
|
|
187
|
+
- Tailwind CSS
|
|
188
|
+
- Break into reusable components
|
|
189
|
+
- Follow shadcn/ui patterns"
|
|
190
|
+
imageUrls: [{screenshot_of_html_design}] // if available
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
This is useful in the conversion step when the user chooses MagicPatterns for HTML→React conversion.
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
#!/usr/bin/env npx tsx
|
|
2
|
+
/**
|
|
3
|
+
* Theme Generation CLI Script
|
|
4
|
+
*
|
|
5
|
+
* Generates CSS theme files from input content.
|
|
6
|
+
* Matches the execution logic of the generateTheme tool.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* npx tsx _bmad-output/tmp/generate-theme.ts --name "Theme Name" --output path/to/theme.css --input source.css
|
|
10
|
+
* cat theme.css | npx tsx _bmad-output/tmp/generate-theme.ts --name "Theme Name" --output path/to/theme.css
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import * as fs from 'node:fs'
|
|
14
|
+
import * as path from 'node:path'
|
|
15
|
+
import * as readline from 'node:readline'
|
|
16
|
+
|
|
17
|
+
// Parse command-line arguments
|
|
18
|
+
const args = process.argv.slice(2)
|
|
19
|
+
|
|
20
|
+
function getArg(flag: string): string | undefined {
|
|
21
|
+
const idx = args.indexOf(flag)
|
|
22
|
+
return idx !== -1 && args[idx + 1] ? args[idx + 1] : undefined
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function hasFlag(flag: string): boolean {
|
|
26
|
+
return args.includes(flag)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function printUsage(): void {
|
|
30
|
+
console.log(`
|
|
31
|
+
Theme Generation CLI
|
|
32
|
+
|
|
33
|
+
Usage:
|
|
34
|
+
npx tsx generate-theme.ts --name <theme_name> --output <path> [options]
|
|
35
|
+
|
|
36
|
+
Required:
|
|
37
|
+
--name <theme_name> Theme name for identification
|
|
38
|
+
--output <path> Output CSS file path (relative to project root)
|
|
39
|
+
|
|
40
|
+
Optional:
|
|
41
|
+
--input <path> Read CSS content from file (alternative to stdin)
|
|
42
|
+
--no-create-dirs Don't create parent directories
|
|
43
|
+
--help Show this help message
|
|
44
|
+
|
|
45
|
+
Examples:
|
|
46
|
+
# Read CSS from file
|
|
47
|
+
npx tsx generate-theme.ts --name "Dark Mode" --output .superdesign/themes/dark.css --input theme-content.css
|
|
48
|
+
|
|
49
|
+
# Read CSS from stdin
|
|
50
|
+
cat theme.css | npx tsx generate-theme.ts --name "Light Mode" --output .superdesign/themes/light.css
|
|
51
|
+
|
|
52
|
+
# Echo CSS directly
|
|
53
|
+
echo ':root { --primary: blue; }' | npx tsx generate-theme.ts --name "Test" --output .superdesign/test.css
|
|
54
|
+
`)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function printResult(success: boolean, message: string, data?: Record<string, unknown>): void {
|
|
58
|
+
const result = {
|
|
59
|
+
success,
|
|
60
|
+
message,
|
|
61
|
+
...data,
|
|
62
|
+
}
|
|
63
|
+
console.log(JSON.stringify(result, null, 2))
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function readStdin(): Promise<string> {
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
// Check if stdin has data (not a TTY)
|
|
69
|
+
if (process.stdin.isTTY) {
|
|
70
|
+
resolve('')
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const rl = readline.createInterface({
|
|
75
|
+
input: process.stdin,
|
|
76
|
+
terminal: false,
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const lines: string[] = []
|
|
80
|
+
rl.on('line', line => lines.push(line))
|
|
81
|
+
rl.on('close', () => resolve(lines.join('\n')))
|
|
82
|
+
rl.on('error', reject)
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function main(): Promise<void> {
|
|
87
|
+
// Show help if requested
|
|
88
|
+
if (hasFlag('--help') || hasFlag('-h')) {
|
|
89
|
+
printUsage()
|
|
90
|
+
process.exit(0)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Parse arguments
|
|
94
|
+
const themeName = getArg('--name')
|
|
95
|
+
const outputPath = getArg('--output')
|
|
96
|
+
const inputPath = getArg('--input')
|
|
97
|
+
const createDirs = !hasFlag('--no-create-dirs')
|
|
98
|
+
|
|
99
|
+
// Validate required arguments
|
|
100
|
+
if (!themeName) {
|
|
101
|
+
printResult(false, 'Missing required argument: --name')
|
|
102
|
+
process.exit(1)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!outputPath) {
|
|
106
|
+
printResult(false, 'Missing required argument: --output')
|
|
107
|
+
process.exit(1)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Determine project root (two levels up from this script location)
|
|
111
|
+
const projectRoot = path.resolve(__dirname, '../..')
|
|
112
|
+
|
|
113
|
+
// Resolve and validate output path
|
|
114
|
+
const resolvedOutputPath = path.resolve(projectRoot, outputPath)
|
|
115
|
+
if (!resolvedOutputPath.startsWith(projectRoot)) {
|
|
116
|
+
printResult(false, 'Output path must be within project directory', {
|
|
117
|
+
attempted_path: outputPath,
|
|
118
|
+
resolved_path: resolvedOutputPath,
|
|
119
|
+
project_root: projectRoot,
|
|
120
|
+
})
|
|
121
|
+
process.exit(1)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Read CSS content from input file or stdin
|
|
125
|
+
let cssContent: string
|
|
126
|
+
|
|
127
|
+
if (inputPath) {
|
|
128
|
+
const resolvedInputPath = path.resolve(projectRoot, inputPath)
|
|
129
|
+
if (!resolvedInputPath.startsWith(projectRoot)) {
|
|
130
|
+
printResult(false, 'Input path must be within project directory', {
|
|
131
|
+
attempted_path: inputPath,
|
|
132
|
+
})
|
|
133
|
+
process.exit(1)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!fs.existsSync(resolvedInputPath)) {
|
|
137
|
+
printResult(false, `Input file not found: ${inputPath}`, {
|
|
138
|
+
resolved_path: resolvedInputPath,
|
|
139
|
+
})
|
|
140
|
+
process.exit(1)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
cssContent = fs.readFileSync(resolvedInputPath, 'utf-8')
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
cssContent = await readStdin()
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (!cssContent || cssContent.trim() === '') {
|
|
150
|
+
printResult(false, 'No CSS content provided. Use --input <file> or pipe content via stdin.')
|
|
151
|
+
process.exit(1)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Create parent directories if needed
|
|
155
|
+
const outputDir = path.dirname(resolvedOutputPath)
|
|
156
|
+
if (createDirs && !fs.existsSync(outputDir)) {
|
|
157
|
+
try {
|
|
158
|
+
fs.mkdirSync(outputDir, { recursive: true })
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
printResult(false, `Failed to create directory: ${outputDir}`, {
|
|
162
|
+
error: err instanceof Error ? err.message : String(err),
|
|
163
|
+
})
|
|
164
|
+
process.exit(1)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Write CSS content to output file
|
|
169
|
+
try {
|
|
170
|
+
fs.writeFileSync(resolvedOutputPath, cssContent, 'utf-8')
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
printResult(false, `Failed to write file: ${resolvedOutputPath}`, {
|
|
174
|
+
error: err instanceof Error ? err.message : String(err),
|
|
175
|
+
})
|
|
176
|
+
process.exit(1)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Print success result
|
|
180
|
+
printResult(true, `Theme "${themeName}" saved successfully`, {
|
|
181
|
+
theme_name: themeName,
|
|
182
|
+
file_path: resolvedOutputPath,
|
|
183
|
+
relative_path: outputPath,
|
|
184
|
+
bytes_written: Buffer.byteLength(cssContent, 'utf-8'),
|
|
185
|
+
})
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
main().catch((err) => {
|
|
189
|
+
printResult(false, 'Unexpected error', {
|
|
190
|
+
error: err instanceof Error ? err.message : String(err),
|
|
191
|
+
})
|
|
192
|
+
process.exit(1)
|
|
193
|
+
})
|