claude-code-workflow 6.0.5 → 6.1.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.
Files changed (117) hide show
  1. package/.claude/agents/action-planning-agent.md +1 -1
  2. package/.claude/agents/cli-execution-agent.md +269 -269
  3. package/.claude/agents/cli-explore-agent.md +182 -182
  4. package/.claude/agents/context-search-agent.md +582 -582
  5. package/.claude/agents/memory-bridge.md +93 -93
  6. package/.claude/commands/cli/cli-init.md +1 -1
  7. package/.claude/commands/memory/docs-full-cli.md +471 -471
  8. package/.claude/commands/memory/docs-related-cli.md +386 -386
  9. package/.claude/commands/memory/docs.md +615 -615
  10. package/.claude/commands/memory/load.md +1 -1
  11. package/.claude/commands/memory/update-full.md +332 -332
  12. package/.claude/commands/memory/update-related.md +5 -5
  13. package/.claude/commands/workflow/init.md +1 -1
  14. package/.claude/commands/workflow/lite-fix.md +621 -621
  15. package/.claude/commands/workflow/lite-plan.md +592 -592
  16. package/.claude/commands/workflow/tools/context-gather.md +434 -434
  17. package/.claude/commands/workflow/ui-design/generate.md +504 -504
  18. package/.claude/commands/workflow/ui-design/import-from-code.md +537 -537
  19. package/.claude/scripts/classify-folders.sh +4 -0
  20. package/.claude/scripts/convert_tokens_to_css.sh +4 -0
  21. package/.claude/scripts/detect_changed_modules.sh +5 -1
  22. package/.claude/scripts/discover-design-files.sh +87 -83
  23. package/.claude/scripts/generate_module_docs.sh +717 -713
  24. package/.claude/scripts/get_modules_by_depth.sh +5 -1
  25. package/.claude/scripts/ui-generate-preview.sh +4 -0
  26. package/.claude/scripts/ui-instantiate-prototypes.sh +4 -0
  27. package/.claude/scripts/update_module_claude.sh +4 -0
  28. package/.claude/skills/command-guide/index/all-commands.json +1 -12
  29. package/.claude/skills/command-guide/index/by-category.json +1 -12
  30. package/.claude/skills/command-guide/index/by-use-case.json +1 -12
  31. package/.claude/skills/command-guide/index/essential-commands.json +1 -12
  32. package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +127 -71
  33. package/.claude/skills/command-guide/reference/agents/cli-execution-agent.md +269 -269
  34. package/.claude/skills/command-guide/reference/agents/cli-explore-agent.md +182 -182
  35. package/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +18 -38
  36. package/.claude/skills/command-guide/reference/agents/context-search-agent.md +582 -577
  37. package/.claude/skills/command-guide/reference/agents/memory-bridge.md +93 -93
  38. package/.claude/skills/command-guide/reference/commands/cli/cli-init.md +1 -1
  39. package/.claude/skills/command-guide/reference/commands/memory/docs-full-cli.md +471 -471
  40. package/.claude/skills/command-guide/reference/commands/memory/docs-related-cli.md +386 -386
  41. package/.claude/skills/command-guide/reference/commands/memory/docs.md +615 -610
  42. package/.claude/skills/command-guide/reference/commands/memory/load.md +1 -1
  43. package/.claude/skills/command-guide/reference/commands/memory/update-full.md +332 -332
  44. package/.claude/skills/command-guide/reference/commands/memory/update-related.md +5 -5
  45. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/artifacts.md +299 -451
  46. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/auto-parallel.md +14 -37
  47. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/synthesis.md +252 -350
  48. package/.claude/skills/command-guide/reference/commands/workflow/init.md +2 -2
  49. package/.claude/skills/command-guide/reference/commands/workflow/lite-execute.md +52 -0
  50. package/.claude/skills/command-guide/reference/commands/workflow/lite-fix.md +621 -602
  51. package/.claude/skills/command-guide/reference/commands/workflow/lite-plan.md +46 -36
  52. package/.claude/skills/command-guide/reference/commands/workflow/review-fix.md +18 -58
  53. package/.claude/skills/command-guide/reference/commands/workflow/review-module-cycle.md +22 -52
  54. package/.claude/skills/command-guide/reference/commands/workflow/review-session-cycle.md +19 -48
  55. package/.claude/skills/command-guide/reference/commands/workflow/session/start.md +25 -5
  56. package/.claude/skills/command-guide/reference/commands/workflow/tdd-plan.md +1 -1
  57. package/.claude/skills/command-guide/reference/commands/workflow/test-fix-gen.md +7 -7
  58. package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +434 -434
  59. package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-agent.md +151 -11
  60. package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +4 -4
  61. package/.claude/skills/command-guide/reference/commands/workflow/tools/test-task-generate.md +1 -1
  62. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/generate.md +504 -504
  63. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/import-from-code.md +537 -537
  64. package/.claude/workflows/context-search-strategy.md +77 -77
  65. package/.claude/workflows/tool-strategy.md +90 -71
  66. package/.claude/workflows/workflow-architecture.md +1 -1
  67. package/ccw/src/cli.js +7 -0
  68. package/ccw/src/commands/tool.js +181 -0
  69. package/ccw/src/core/dashboard-generator.js +18 -3
  70. package/ccw/src/core/lite-scanner.js +35 -11
  71. package/ccw/src/core/server.js +531 -46
  72. package/ccw/src/templates/dashboard-css/01-base.css +161 -0
  73. package/ccw/src/templates/dashboard-css/02-session.css +726 -0
  74. package/ccw/src/templates/dashboard-css/03-tasks.css +512 -0
  75. package/ccw/src/templates/dashboard-css/04-lite-tasks.css +843 -0
  76. package/ccw/src/templates/dashboard-css/05-context.css +2206 -0
  77. package/ccw/src/templates/dashboard-css/06-cards.css +1570 -0
  78. package/ccw/src/templates/dashboard-css/07-managers.css +936 -0
  79. package/ccw/src/templates/dashboard-css/08-review.css +1266 -0
  80. package/ccw/src/templates/dashboard-css/09-explorer.css +1397 -0
  81. package/ccw/src/templates/dashboard-js/components/global-notifications.js +219 -0
  82. package/ccw/src/templates/dashboard-js/components/hook-manager.js +10 -0
  83. package/ccw/src/templates/dashboard-js/components/mcp-manager.js +11 -1
  84. package/ccw/src/templates/dashboard-js/components/navigation.js +11 -5
  85. package/ccw/src/templates/dashboard-js/components/tabs-context.js +20 -20
  86. package/ccw/src/templates/dashboard-js/components/tabs-other.js +11 -11
  87. package/ccw/src/templates/dashboard-js/components/theme.js +29 -1
  88. package/ccw/src/templates/dashboard-js/main.js +4 -0
  89. package/ccw/src/templates/dashboard-js/state.js +5 -0
  90. package/ccw/src/templates/dashboard-js/views/explorer.js +852 -0
  91. package/ccw/src/templates/dashboard-js/views/home.js +13 -9
  92. package/ccw/src/templates/dashboard-js/views/hook-manager.js +8 -5
  93. package/ccw/src/templates/dashboard-js/views/lite-tasks.js +21 -16
  94. package/ccw/src/templates/dashboard-js/views/mcp-manager.js +90 -19
  95. package/ccw/src/templates/dashboard-js/views/project-overview.js +15 -11
  96. package/ccw/src/templates/dashboard-js/views/review-session.js +3 -3
  97. package/ccw/src/templates/dashboard-js/views/session-detail.js +38 -28
  98. package/ccw/src/templates/dashboard.html +129 -28
  99. package/ccw/src/tools/classify-folders.js +204 -0
  100. package/ccw/src/tools/convert-tokens-to-css.js +250 -0
  101. package/ccw/src/tools/detect-changed-modules.js +288 -0
  102. package/ccw/src/tools/discover-design-files.js +134 -0
  103. package/ccw/src/tools/edit-file.js +266 -0
  104. package/ccw/src/tools/generate-module-docs.js +416 -0
  105. package/ccw/src/tools/get-modules-by-depth.js +308 -0
  106. package/ccw/src/tools/index.js +176 -0
  107. package/ccw/src/tools/ui-generate-preview.js +327 -0
  108. package/ccw/src/tools/ui-instantiate-prototypes.js +301 -0
  109. package/ccw/src/tools/update-module-claude.js +380 -0
  110. package/package.json +1 -1
  111. package/.claude/skills/command-guide/reference/commands/workflow/status.md +0 -352
  112. package/ccw/src/core/server.js.bak +0 -385
  113. package/ccw/src/core/server_original.bak +0 -385
  114. package/ccw/src/templates/dashboard.css +0 -8187
  115. package/ccw/src/templates/dashboard_tailwind.html +0 -42
  116. package/ccw/src/templates/dashboard_test.html +0 -37
  117. package/ccw/src/templates/tailwind-base.css +0 -212
@@ -0,0 +1,327 @@
1
+ /**
2
+ * UI Generate Preview Tool
3
+ * Generate compare.html and index.html for UI prototypes
4
+ */
5
+
6
+ import { readdirSync, existsSync, readFileSync, writeFileSync } from 'fs';
7
+ import { resolve, basename } from 'path';
8
+
9
+ /**
10
+ * Auto-detect matrix dimensions from file patterns
11
+ * Pattern: {target}-style-{s}-layout-{l}.html
12
+ */
13
+ function detectMatrixDimensions(prototypesDir) {
14
+ const files = readdirSync(prototypesDir).filter(f => f.match(/.*-style-\d+-layout-\d+\.html$/));
15
+
16
+ const styles = new Set();
17
+ const layouts = new Set();
18
+ const targets = new Set();
19
+
20
+ files.forEach(file => {
21
+ const styleMatch = file.match(/-style-(\d+)-/);
22
+ const layoutMatch = file.match(/-layout-(\d+)\.html/);
23
+ const targetMatch = file.match(/^(.+)-style-/);
24
+
25
+ if (styleMatch) styles.add(parseInt(styleMatch[1]));
26
+ if (layoutMatch) layouts.add(parseInt(layoutMatch[1]));
27
+ if (targetMatch) targets.add(targetMatch[1]);
28
+ });
29
+
30
+ return {
31
+ styles: Math.max(...Array.from(styles)),
32
+ layouts: Math.max(...Array.from(layouts)),
33
+ targets: Array.from(targets).sort()
34
+ };
35
+ }
36
+
37
+ /**
38
+ * Load template from file
39
+ */
40
+ function loadTemplate(templatePath) {
41
+ const defaultPath = resolve(
42
+ process.env.HOME || process.env.USERPROFILE,
43
+ '.claude/workflows/_template-compare-matrix.html'
44
+ );
45
+
46
+ const path = templatePath || defaultPath;
47
+
48
+ if (!existsSync(path)) {
49
+ // Return minimal fallback template
50
+ return `<!DOCTYPE html>
51
+ <html>
52
+ <head><title>UI Prototypes Comparison</title></head>
53
+ <body>
54
+ <h1>UI Prototypes Matrix</h1>
55
+ <p>Styles: {{style_variants}} | Layouts: {{layout_variants}}</p>
56
+ <p>Pages: {{pages_json}}</p>
57
+ <p>Generated: {{timestamp}}</p>
58
+ </body>
59
+ </html>`;
60
+ }
61
+
62
+ return readFileSync(path, 'utf8');
63
+ }
64
+
65
+ /**
66
+ * Generate compare.html from template
67
+ */
68
+ function generateCompareHtml(template, metadata) {
69
+ const { runId, sessionId, timestamp, styles, layouts, targets } = metadata;
70
+
71
+ const pagesJson = JSON.stringify(targets);
72
+
73
+ return template
74
+ .replace(/\{\{run_id\}\}/g, runId)
75
+ .replace(/\{\{session_id\}\}/g, sessionId)
76
+ .replace(/\{\{timestamp\}\}/g, timestamp)
77
+ .replace(/\{\{style_variants\}\}/g, styles.toString())
78
+ .replace(/\{\{layout_variants\}\}/g, layouts.toString())
79
+ .replace(/\{\{pages_json\}\}/g, pagesJson);
80
+ }
81
+
82
+ /**
83
+ * Generate index.html
84
+ */
85
+ function generateIndexHtml(metadata) {
86
+ const { styles, layouts, targets } = metadata;
87
+ const total = styles * layouts * targets.length;
88
+
89
+ return `<!DOCTYPE html>
90
+ <html lang="en">
91
+ <head>
92
+ <meta charset="UTF-8">
93
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
94
+ <title>UI Prototypes Index</title>
95
+ <style>
96
+ * { margin: 0; padding: 0; box-sizing: border-box; }
97
+ body {
98
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
99
+ max-width: 1200px;
100
+ margin: 0 auto;
101
+ padding: 40px 20px;
102
+ background: #f5f5f5;
103
+ }
104
+ h1 { margin-bottom: 10px; color: #333; }
105
+ .subtitle { color: #666; margin-bottom: 30px; }
106
+ .cta {
107
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
108
+ color: white;
109
+ padding: 20px;
110
+ border-radius: 8px;
111
+ margin-bottom: 30px;
112
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
113
+ }
114
+ .cta h2 { margin-bottom: 10px; }
115
+ .cta a {
116
+ display: inline-block;
117
+ background: white;
118
+ color: #667eea;
119
+ padding: 10px 20px;
120
+ border-radius: 6px;
121
+ text-decoration: none;
122
+ font-weight: 600;
123
+ margin-top: 10px;
124
+ }
125
+ .stats {
126
+ display: grid;
127
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
128
+ gap: 15px;
129
+ margin-bottom: 30px;
130
+ }
131
+ .stat {
132
+ background: white;
133
+ padding: 15px;
134
+ border-radius: 8px;
135
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
136
+ }
137
+ .stat-label { font-size: 0.85em; color: #666; margin-bottom: 5px; }
138
+ .stat-value { font-size: 1.5em; font-weight: bold; color: #333; }
139
+ .files {
140
+ background: white;
141
+ padding: 20px;
142
+ border-radius: 8px;
143
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
144
+ }
145
+ .files h2 { margin-bottom: 15px; color: #333; }
146
+ .file-list { list-style: none; }
147
+ .file-list li {
148
+ padding: 8px 0;
149
+ border-bottom: 1px solid #eee;
150
+ }
151
+ .file-list li:last-child { border-bottom: none; }
152
+ .file-list a {
153
+ color: #667eea;
154
+ text-decoration: none;
155
+ }
156
+ .file-list a:hover { text-decoration: underline; }
157
+ </style>
158
+ </head>
159
+ <body>
160
+ <h1>UI Prototypes</h1>
161
+ <p class="subtitle">Interactive design exploration matrix</p>
162
+
163
+ <div class="cta">
164
+ <h2>📊 Interactive Comparison</h2>
165
+ <p>View all prototypes side-by-side with synchronized scrolling</p>
166
+ <a href="compare.html">Open Comparison Matrix →</a>
167
+ </div>
168
+
169
+ <div class="stats">
170
+ <div class="stat">
171
+ <div class="stat-label">Style Variants</div>
172
+ <div class="stat-value">${styles}</div>
173
+ </div>
174
+ <div class="stat">
175
+ <div class="stat-label">Layout Variants</div>
176
+ <div class="stat-value">${layouts}</div>
177
+ </div>
178
+ <div class="stat">
179
+ <div class="stat-label">Pages/Components</div>
180
+ <div class="stat-value">${targets.length}</div>
181
+ </div>
182
+ <div class="stat">
183
+ <div class="stat-label">Total Prototypes</div>
184
+ <div class="stat-value">${total}</div>
185
+ </div>
186
+ </div>
187
+
188
+ <div class="files">
189
+ <h2>Individual Prototypes</h2>
190
+ <ul class="file-list">
191
+ ${targets.map(target => {
192
+ const items = [];
193
+ for (let s = 1; s <= styles; s++) {
194
+ for (let l = 1; l <= layouts; l++) {
195
+ const filename = `${target}-style-${s}-layout-${l}.html`;
196
+ items.push(` <li><a href="${filename}">${filename}</a></li>`);
197
+ }
198
+ }
199
+ return items.join('\n');
200
+ }).join('\n')}
201
+ </ul>
202
+ </div>
203
+ </body>
204
+ </html>`;
205
+ }
206
+
207
+ /**
208
+ * Generate PREVIEW.md
209
+ */
210
+ function generatePreviewMd(metadata) {
211
+ const { styles, layouts, targets } = metadata;
212
+
213
+ return `# UI Prototypes Preview
214
+
215
+ ## Matrix Dimensions
216
+
217
+ - **Style Variants**: ${styles}
218
+ - **Layout Variants**: ${layouts}
219
+ - **Pages/Components**: ${targets.join(', ')}
220
+ - **Total Prototypes**: ${styles * layouts * targets.length}
221
+
222
+ ## Quick Start
223
+
224
+ 1. **Interactive Comparison**: Open \`compare.html\` for side-by-side view with synchronized scrolling
225
+ 2. **Browse Index**: Open \`index.html\` for a navigable list of all prototypes
226
+ 3. **Individual Files**: Access specific prototypes directly (e.g., \`${targets[0]}-style-1-layout-1.html\`)
227
+
228
+ ## File Naming Convention
229
+
230
+ \`\`\`
231
+ {page}-style-{s}-layout-{l}.html
232
+ \`\`\`
233
+
234
+ - **page**: Component/page name (${targets.join(', ')})
235
+ - **s**: Style variant number (1-${styles})
236
+ - **l**: Layout variant number (1-${layouts})
237
+
238
+ ## Tips
239
+
240
+ - Use compare.html for quick visual comparison across all variants
241
+ - Synchronized scrolling helps identify consistency issues
242
+ - Check responsive behavior across different layout variants
243
+ `;
244
+ }
245
+
246
+ /**
247
+ * Main execute function
248
+ */
249
+ async function execute(params) {
250
+ const { prototypesDir = '.', template: templatePath } = params;
251
+
252
+ const targetPath = resolve(process.cwd(), prototypesDir);
253
+
254
+ if (!existsSync(targetPath)) {
255
+ throw new Error(`Directory not found: ${targetPath}`);
256
+ }
257
+
258
+ // Auto-detect matrix dimensions
259
+ const { styles, layouts, targets } = detectMatrixDimensions(targetPath);
260
+
261
+ if (styles === 0 || layouts === 0 || targets.length === 0) {
262
+ throw new Error('No prototype files found matching pattern {target}-style-{s}-layout-{l}.html');
263
+ }
264
+
265
+ // Generate metadata
266
+ const metadata = {
267
+ runId: `run-${new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5)}`,
268
+ sessionId: 'standalone',
269
+ timestamp: new Date().toISOString(),
270
+ styles,
271
+ layouts,
272
+ targets
273
+ };
274
+
275
+ // Load template
276
+ const template = loadTemplate(templatePath);
277
+
278
+ // Generate files
279
+ const compareHtml = generateCompareHtml(template, metadata);
280
+ const indexHtml = generateIndexHtml(metadata);
281
+ const previewMd = generatePreviewMd(metadata);
282
+
283
+ // Write files
284
+ writeFileSync(resolve(targetPath, 'compare.html'), compareHtml, 'utf8');
285
+ writeFileSync(resolve(targetPath, 'index.html'), indexHtml, 'utf8');
286
+ writeFileSync(resolve(targetPath, 'PREVIEW.md'), previewMd, 'utf8');
287
+
288
+ return {
289
+ success: true,
290
+ prototypes_dir: prototypesDir,
291
+ styles,
292
+ layouts,
293
+ targets,
294
+ total_prototypes: styles * layouts * targets.length,
295
+ files_generated: ['compare.html', 'index.html', 'PREVIEW.md']
296
+ };
297
+ }
298
+
299
+ /**
300
+ * Tool Definition
301
+ */
302
+ export const uiGeneratePreviewTool = {
303
+ name: 'ui_generate_preview',
304
+ description: `Generate interactive preview files for UI prototypes.
305
+ Generates:
306
+ - compare.html: Interactive matrix view with synchronized scrolling
307
+ - index.html: Navigation and statistics
308
+ - PREVIEW.md: Usage guide
309
+
310
+ Auto-detects matrix dimensions from file pattern: {target}-style-{s}-layout-{l}.html`,
311
+ parameters: {
312
+ type: 'object',
313
+ properties: {
314
+ prototypesDir: {
315
+ type: 'string',
316
+ description: 'Prototypes directory path (default: current directory)',
317
+ default: '.'
318
+ },
319
+ template: {
320
+ type: 'string',
321
+ description: 'Optional path to compare.html template'
322
+ }
323
+ },
324
+ required: []
325
+ },
326
+ execute
327
+ };
@@ -0,0 +1,301 @@
1
+ /**
2
+ * UI Instantiate Prototypes Tool
3
+ * Create final UI prototypes from templates (Style × Layout × Page matrix)
4
+ */
5
+
6
+ import { readdirSync, existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from 'fs';
7
+ import { resolve, join, basename } from 'path';
8
+
9
+ /**
10
+ * Auto-detect pages from templates directory
11
+ */
12
+ function autoDetectPages(templatesDir) {
13
+ if (!existsSync(templatesDir)) {
14
+ return [];
15
+ }
16
+
17
+ const files = readdirSync(templatesDir).filter(f => f.match(/.*-layout-\d+\.html$/));
18
+ const pages = new Set();
19
+
20
+ files.forEach(file => {
21
+ const match = file.match(/^(.+)-layout-\d+\.html$/);
22
+ if (match) pages.add(match[1]);
23
+ });
24
+
25
+ return Array.from(pages).sort();
26
+ }
27
+
28
+ /**
29
+ * Auto-detect style variants count
30
+ */
31
+ function autoDetectStyleVariants(basePath) {
32
+ const styleDir = resolve(basePath, '..', 'style-extraction');
33
+
34
+ if (!existsSync(styleDir)) {
35
+ return 3; // Default
36
+ }
37
+
38
+ const dirs = readdirSync(styleDir, { withFileTypes: true })
39
+ .filter(d => d.isDirectory() && d.name.startsWith('style-'));
40
+
41
+ return dirs.length > 0 ? dirs.length : 3;
42
+ }
43
+
44
+ /**
45
+ * Auto-detect layout variants count
46
+ */
47
+ function autoDetectLayoutVariants(templatesDir) {
48
+ if (!existsSync(templatesDir)) {
49
+ return 3; // Default
50
+ }
51
+
52
+ const files = readdirSync(templatesDir);
53
+ const firstPage = files.find(f => f.endsWith('-layout-1.html'));
54
+
55
+ if (!firstPage) return 3;
56
+
57
+ const pageName = firstPage.replace(/-layout-1\.html$/, '');
58
+ const layoutFiles = files.filter(f => f.match(new RegExp(`^${pageName}-layout-\\d+\\.html$`)));
59
+
60
+ return layoutFiles.length > 0 ? layoutFiles.length : 3;
61
+ }
62
+
63
+ /**
64
+ * Load CSS tokens file
65
+ */
66
+ function loadTokensCss(styleDir, styleNum) {
67
+ const tokenPath = join(styleDir, `style-${styleNum}`, 'tokens.css');
68
+
69
+ if (existsSync(tokenPath)) {
70
+ return readFileSync(tokenPath, 'utf8');
71
+ }
72
+
73
+ return '/* No tokens.css found */';
74
+ }
75
+
76
+ /**
77
+ * Replace CSS placeholder in template
78
+ */
79
+ function replaceCssPlaceholder(html, tokensCss) {
80
+ // Replace {{tokens.css}} placeholder
81
+ return html.replace(/\{\{tokens\.css\}\}/g, tokensCss);
82
+ }
83
+
84
+ /**
85
+ * Generate prototype from template
86
+ */
87
+ function generatePrototype(templatePath, styleDir, styleNum, outputPath) {
88
+ const templateHtml = readFileSync(templatePath, 'utf8');
89
+ const tokensCss = loadTokensCss(styleDir, styleNum);
90
+ const finalHtml = replaceCssPlaceholder(templateHtml, tokensCss);
91
+
92
+ writeFileSync(outputPath, finalHtml, 'utf8');
93
+ }
94
+
95
+ /**
96
+ * Generate implementation notes
97
+ */
98
+ function generateImplementationNotes(page, styleNum, layoutNum) {
99
+ return `# Implementation Notes: ${page}-style-${styleNum}-layout-${layoutNum}
100
+
101
+ ## Overview
102
+ Prototype combining:
103
+ - **Page/Component**: ${page}
104
+ - **Style Variant**: ${styleNum}
105
+ - **Layout Variant**: ${layoutNum}
106
+
107
+ ## Implementation Checklist
108
+
109
+ ### 1. Style Integration
110
+ - [ ] Verify all CSS custom properties are applied correctly
111
+ - [ ] Check color palette consistency
112
+ - [ ] Validate typography settings
113
+ - [ ] Test spacing and border radius values
114
+
115
+ ### 2. Layout Verification
116
+ - [ ] Confirm component structure matches layout variant
117
+ - [ ] Test responsive behavior
118
+ - [ ] Verify flex/grid layouts
119
+ - [ ] Check alignment and spacing
120
+
121
+ ### 3. Accessibility
122
+ - [ ] Color contrast ratios (WCAG AA minimum)
123
+ - [ ] Keyboard navigation
124
+ - [ ] Screen reader compatibility
125
+ - [ ] Focus indicators
126
+
127
+ ### 4. Browser Testing
128
+ - [ ] Chrome/Edge
129
+ - [ ] Firefox
130
+ - [ ] Safari
131
+ - [ ] Mobile browsers
132
+
133
+ ## Next Steps
134
+ 1. Review prototype in browser
135
+ 2. Compare with design specifications
136
+ 3. Implement in production codebase
137
+ 4. Add interactive functionality
138
+ 5. Write tests
139
+ `;
140
+ }
141
+
142
+ /**
143
+ * Main execute function
144
+ */
145
+ async function execute(params) {
146
+ const {
147
+ prototypesDir,
148
+ pages: pagesParam,
149
+ styleVariants: styleVariantsParam,
150
+ layoutVariants: layoutVariantsParam,
151
+ runId: runIdParam,
152
+ sessionId = 'standalone',
153
+ generatePreview = true
154
+ } = params;
155
+
156
+ if (!prototypesDir) {
157
+ throw new Error('Parameter "prototypesDir" is required');
158
+ }
159
+
160
+ const basePath = resolve(process.cwd(), prototypesDir);
161
+
162
+ if (!existsSync(basePath)) {
163
+ throw new Error(`Directory not found: ${basePath}`);
164
+ }
165
+
166
+ const templatesDir = join(basePath, '_templates');
167
+ const styleDir = resolve(basePath, '..', 'style-extraction');
168
+
169
+ // Auto-detect or use provided parameters
170
+ let pages, styleVariants, layoutVariants;
171
+
172
+ if (pagesParam && styleVariantsParam && layoutVariantsParam) {
173
+ // Manual mode
174
+ pages = Array.isArray(pagesParam) ? pagesParam : pagesParam.split(',').map(p => p.trim());
175
+ styleVariants = parseInt(styleVariantsParam);
176
+ layoutVariants = parseInt(layoutVariantsParam);
177
+ } else {
178
+ // Auto-detect mode
179
+ pages = autoDetectPages(templatesDir);
180
+ styleVariants = autoDetectStyleVariants(basePath);
181
+ layoutVariants = autoDetectLayoutVariants(templatesDir);
182
+ }
183
+
184
+ if (pages.length === 0) {
185
+ throw new Error('No pages detected. Ensure _templates directory contains layout files.');
186
+ }
187
+
188
+ // Generate run ID
189
+ const runId = runIdParam || `run-${new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5)}`;
190
+
191
+ // Phase 1: Copy templates and replace CSS placeholders
192
+ const generatedFiles = [];
193
+
194
+ for (const page of pages) {
195
+ for (let s = 1; s <= styleVariants; s++) {
196
+ for (let l = 1; l <= layoutVariants; l++) {
197
+ const templateFile = `${page}-layout-${l}.html`;
198
+ const templatePath = join(templatesDir, templateFile);
199
+
200
+ if (!existsSync(templatePath)) {
201
+ console.warn(`Template not found: ${templateFile}, skipping...`);
202
+ continue;
203
+ }
204
+
205
+ const outputFile = `${page}-style-${s}-layout-${l}.html`;
206
+ const outputPath = join(basePath, outputFile);
207
+
208
+ // Generate prototype
209
+ generatePrototype(templatePath, styleDir, s, outputPath);
210
+
211
+ // Generate implementation notes
212
+ const notesFile = `${page}-style-${s}-layout-${l}-notes.md`;
213
+ const notesPath = join(basePath, notesFile);
214
+ const notes = generateImplementationNotes(page, s, l);
215
+ writeFileSync(notesPath, notes, 'utf8');
216
+
217
+ generatedFiles.push(outputFile);
218
+ }
219
+ }
220
+ }
221
+
222
+ // Phase 2: Generate preview files (optional)
223
+ const previewFiles = [];
224
+ if (generatePreview) {
225
+ // Import and execute ui_generate_preview tool
226
+ const { uiGeneratePreviewTool } = await import('./ui-generate-preview.js');
227
+ const previewResult = await uiGeneratePreviewTool.execute({ prototypesDir: basePath });
228
+
229
+ if (previewResult.success) {
230
+ previewFiles.push(...previewResult.files_generated);
231
+ }
232
+ }
233
+
234
+ return {
235
+ success: true,
236
+ run_id: runId,
237
+ session_id: sessionId,
238
+ prototypes_dir: basePath,
239
+ pages,
240
+ style_variants: styleVariants,
241
+ layout_variants: layoutVariants,
242
+ total_prototypes: generatedFiles.length,
243
+ files_generated: generatedFiles,
244
+ preview_files: previewFiles,
245
+ message: `Generated ${generatedFiles.length} prototypes (${styleVariants} styles × ${layoutVariants} layouts × ${pages.length} pages)`
246
+ };
247
+ }
248
+
249
+ /**
250
+ * Tool Definition
251
+ */
252
+ export const uiInstantiatePrototypesTool = {
253
+ name: 'ui_instantiate_prototypes',
254
+ description: `Create final UI prototypes from templates (Style × Layout × Page matrix).
255
+
256
+ Two Modes:
257
+ 1. Auto-detect (recommended): Only specify prototypesDir
258
+ 2. Manual: Specify prototypesDir, pages, styleVariants, layoutVariants
259
+
260
+ Features:
261
+ - Copies templates and replaces CSS placeholders with tokens.css
262
+ - Generates implementation notes for each prototype
263
+ - Optionally generates preview files (compare.html, index.html, PREVIEW.md)`,
264
+ parameters: {
265
+ type: 'object',
266
+ properties: {
267
+ prototypesDir: {
268
+ type: 'string',
269
+ description: 'Prototypes directory path'
270
+ },
271
+ pages: {
272
+ type: 'string',
273
+ description: 'Comma-separated list of pages (auto-detected if not provided)'
274
+ },
275
+ styleVariants: {
276
+ type: 'number',
277
+ description: 'Number of style variants (auto-detected if not provided)'
278
+ },
279
+ layoutVariants: {
280
+ type: 'number',
281
+ description: 'Number of layout variants (auto-detected if not provided)'
282
+ },
283
+ runId: {
284
+ type: 'string',
285
+ description: 'Run ID (auto-generated if not provided)'
286
+ },
287
+ sessionId: {
288
+ type: 'string',
289
+ description: 'Session ID (default: standalone)',
290
+ default: 'standalone'
291
+ },
292
+ generatePreview: {
293
+ type: 'boolean',
294
+ description: 'Generate preview files (default: true)',
295
+ default: true
296
+ }
297
+ },
298
+ required: ['prototypesDir']
299
+ },
300
+ execute
301
+ };