wogiflow 1.0.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/.workflow/agents/reviewer.md +81 -0
- package/.workflow/agents/security.md +94 -0
- package/.workflow/agents/story-writer.md +58 -0
- package/.workflow/bridges/base-bridge.js +395 -0
- package/.workflow/bridges/claude-bridge.js +434 -0
- package/.workflow/bridges/index.js +130 -0
- package/.workflow/lib/assumption-detector.js +481 -0
- package/.workflow/lib/config-substitution.js +371 -0
- package/.workflow/lib/failure-categories.js +478 -0
- package/.workflow/state/app-map.md.template +15 -0
- package/.workflow/state/architecture.md.template +24 -0
- package/.workflow/state/component-index.json.template +5 -0
- package/.workflow/state/decisions.md.template +15 -0
- package/.workflow/state/feedback-patterns.md.template +9 -0
- package/.workflow/state/knowledge-sync.json.template +6 -0
- package/.workflow/state/progress.md.template +14 -0
- package/.workflow/state/ready.json.template +7 -0
- package/.workflow/state/request-log.md.template +14 -0
- package/.workflow/state/session-state.json.template +11 -0
- package/.workflow/state/stack.md.template +33 -0
- package/.workflow/state/testing.md.template +36 -0
- package/.workflow/templates/claude-md.hbs +257 -0
- package/.workflow/templates/correction-report.md +67 -0
- package/.workflow/templates/gemini-md.hbs +52 -0
- package/README.md +1802 -0
- package/bin/flow +205 -0
- package/lib/index.js +33 -0
- package/lib/installer.js +467 -0
- package/lib/release-channel.js +269 -0
- package/lib/skill-registry.js +526 -0
- package/lib/upgrader.js +401 -0
- package/lib/utils.js +305 -0
- package/package.json +64 -0
- package/scripts/flow +985 -0
- package/scripts/flow-adaptive-learning.js +1259 -0
- package/scripts/flow-aggregate.js +488 -0
- package/scripts/flow-archive +133 -0
- package/scripts/flow-auto-context.js +1015 -0
- package/scripts/flow-auto-learn.js +615 -0
- package/scripts/flow-bridge.js +223 -0
- package/scripts/flow-browser-suggest.js +316 -0
- package/scripts/flow-bug.js +247 -0
- package/scripts/flow-cascade.js +711 -0
- package/scripts/flow-changelog +85 -0
- package/scripts/flow-checkpoint.js +483 -0
- package/scripts/flow-cli.js +403 -0
- package/scripts/flow-code-intelligence.js +760 -0
- package/scripts/flow-complexity.js +502 -0
- package/scripts/flow-config-set.js +152 -0
- package/scripts/flow-constants.js +157 -0
- package/scripts/flow-context +152 -0
- package/scripts/flow-context-init.js +482 -0
- package/scripts/flow-context-monitor.js +384 -0
- package/scripts/flow-context-scoring.js +886 -0
- package/scripts/flow-correct.js +458 -0
- package/scripts/flow-damage-control.js +985 -0
- package/scripts/flow-deps +101 -0
- package/scripts/flow-diff.js +700 -0
- package/scripts/flow-done +151 -0
- package/scripts/flow-done.js +489 -0
- package/scripts/flow-durable-session.js +1541 -0
- package/scripts/flow-entropy-monitor.js +345 -0
- package/scripts/flow-export-profile +349 -0
- package/scripts/flow-export-scanner.js +1046 -0
- package/scripts/flow-figma-confirm.js +400 -0
- package/scripts/flow-figma-extract.js +496 -0
- package/scripts/flow-figma-generate.js +683 -0
- package/scripts/flow-figma-index.js +909 -0
- package/scripts/flow-figma-match.js +617 -0
- package/scripts/flow-figma-mcp-server.js +518 -0
- package/scripts/flow-figma-pipeline.js +414 -0
- package/scripts/flow-file-ops.js +301 -0
- package/scripts/flow-gate-confidence.js +825 -0
- package/scripts/flow-guided-edit.js +659 -0
- package/scripts/flow-health +185 -0
- package/scripts/flow-health.js +413 -0
- package/scripts/flow-hooks.js +556 -0
- package/scripts/flow-http-client.js +249 -0
- package/scripts/flow-hybrid-detect.js +167 -0
- package/scripts/flow-hybrid-interactive.js +591 -0
- package/scripts/flow-hybrid-test.js +152 -0
- package/scripts/flow-import-profile +439 -0
- package/scripts/flow-init +253 -0
- package/scripts/flow-instruction-richness.js +827 -0
- package/scripts/flow-jira-integration.js +579 -0
- package/scripts/flow-knowledge-router.js +522 -0
- package/scripts/flow-knowledge-sync.js +589 -0
- package/scripts/flow-linear-integration.js +631 -0
- package/scripts/flow-links.js +774 -0
- package/scripts/flow-log-manager.js +559 -0
- package/scripts/flow-loop-enforcer.js +1246 -0
- package/scripts/flow-loop-retry-learning.js +630 -0
- package/scripts/flow-lsp.js +923 -0
- package/scripts/flow-map-index +348 -0
- package/scripts/flow-map-sync +201 -0
- package/scripts/flow-memory-blocks.js +668 -0
- package/scripts/flow-memory-compactor.js +350 -0
- package/scripts/flow-memory-db.js +1110 -0
- package/scripts/flow-memory-sync.js +484 -0
- package/scripts/flow-metrics.js +353 -0
- package/scripts/flow-migrate-ids.js +370 -0
- package/scripts/flow-model-adapter.js +802 -0
- package/scripts/flow-model-router.js +884 -0
- package/scripts/flow-models.js +1231 -0
- package/scripts/flow-morning.js +517 -0
- package/scripts/flow-multi-approach.js +660 -0
- package/scripts/flow-new-feature +86 -0
- package/scripts/flow-onboard +1042 -0
- package/scripts/flow-orchestrate-llm.js +459 -0
- package/scripts/flow-orchestrate.js +3592 -0
- package/scripts/flow-output.js +123 -0
- package/scripts/flow-parallel-detector.js +399 -0
- package/scripts/flow-parallel-dispatch.js +987 -0
- package/scripts/flow-parallel.js +428 -0
- package/scripts/flow-pattern-enforcer.js +600 -0
- package/scripts/flow-prd-manager.js +282 -0
- package/scripts/flow-progress.js +323 -0
- package/scripts/flow-project-analyzer.js +975 -0
- package/scripts/flow-prompt-composer.js +487 -0
- package/scripts/flow-providers.js +1381 -0
- package/scripts/flow-queue.js +308 -0
- package/scripts/flow-ready +82 -0
- package/scripts/flow-ready.js +189 -0
- package/scripts/flow-regression.js +396 -0
- package/scripts/flow-response-parser.js +450 -0
- package/scripts/flow-resume.js +284 -0
- package/scripts/flow-rules-sync.js +439 -0
- package/scripts/flow-run-trace.js +718 -0
- package/scripts/flow-safety.js +587 -0
- package/scripts/flow-search +104 -0
- package/scripts/flow-security.js +481 -0
- package/scripts/flow-session-end +106 -0
- package/scripts/flow-session-end.js +437 -0
- package/scripts/flow-session-state.js +671 -0
- package/scripts/flow-setup-hooks +216 -0
- package/scripts/flow-setup-hooks.js +377 -0
- package/scripts/flow-skill-create.js +329 -0
- package/scripts/flow-skill-creator.js +572 -0
- package/scripts/flow-skill-generator.js +1046 -0
- package/scripts/flow-skill-learn.js +880 -0
- package/scripts/flow-skill-matcher.js +578 -0
- package/scripts/flow-spec-generator.js +820 -0
- package/scripts/flow-stack-wizard.js +895 -0
- package/scripts/flow-standup +162 -0
- package/scripts/flow-start +74 -0
- package/scripts/flow-start.js +235 -0
- package/scripts/flow-status +110 -0
- package/scripts/flow-status.js +301 -0
- package/scripts/flow-step-browser.js +83 -0
- package/scripts/flow-step-changelog.js +217 -0
- package/scripts/flow-step-comments.js +306 -0
- package/scripts/flow-step-complexity.js +234 -0
- package/scripts/flow-step-coverage.js +218 -0
- package/scripts/flow-step-knowledge.js +193 -0
- package/scripts/flow-step-pr-tests.js +364 -0
- package/scripts/flow-step-regression.js +89 -0
- package/scripts/flow-step-review.js +516 -0
- package/scripts/flow-step-security.js +162 -0
- package/scripts/flow-step-silent-failures.js +290 -0
- package/scripts/flow-step-simplifier.js +346 -0
- package/scripts/flow-story +105 -0
- package/scripts/flow-story.js +500 -0
- package/scripts/flow-suspend.js +252 -0
- package/scripts/flow-sync-daemon.js +654 -0
- package/scripts/flow-task-analyzer.js +606 -0
- package/scripts/flow-team-dashboard.js +748 -0
- package/scripts/flow-team-sync.js +752 -0
- package/scripts/flow-team.js +977 -0
- package/scripts/flow-tech-options.js +528 -0
- package/scripts/flow-templates.js +812 -0
- package/scripts/flow-tiered-learning.js +728 -0
- package/scripts/flow-trace +204 -0
- package/scripts/flow-transcript-chunking.js +1106 -0
- package/scripts/flow-transcript-digest.js +7918 -0
- package/scripts/flow-transcript-language.js +465 -0
- package/scripts/flow-transcript-parsing.js +1085 -0
- package/scripts/flow-transcript-stories.js +2194 -0
- package/scripts/flow-update-map +224 -0
- package/scripts/flow-utils.js +2242 -0
- package/scripts/flow-verification.js +644 -0
- package/scripts/flow-verify.js +1177 -0
- package/scripts/flow-voice-input.js +638 -0
- package/scripts/flow-watch +168 -0
- package/scripts/flow-workflow-steps.js +521 -0
- package/scripts/flow-workflow.js +1029 -0
- package/scripts/flow-worktree.js +489 -0
- package/scripts/hooks/adapters/base-adapter.js +102 -0
- package/scripts/hooks/adapters/claude-code.js +359 -0
- package/scripts/hooks/adapters/index.js +79 -0
- package/scripts/hooks/core/component-check.js +341 -0
- package/scripts/hooks/core/index.js +35 -0
- package/scripts/hooks/core/loop-check.js +241 -0
- package/scripts/hooks/core/session-context.js +294 -0
- package/scripts/hooks/core/task-gate.js +177 -0
- package/scripts/hooks/core/validation.js +230 -0
- package/scripts/hooks/entry/claude-code/post-tool-use.js +65 -0
- package/scripts/hooks/entry/claude-code/pre-tool-use.js +89 -0
- package/scripts/hooks/entry/claude-code/session-end.js +87 -0
- package/scripts/hooks/entry/claude-code/session-start.js +46 -0
- package/scripts/hooks/entry/claude-code/stop.js +43 -0
- package/scripts/postinstall.js +139 -0
- package/templates/browser-test-flow.json +56 -0
- package/templates/bug-report.md +43 -0
- package/templates/component-detail.md +42 -0
- package/templates/component.stories.tsx +49 -0
- package/templates/context/constraints.md +83 -0
- package/templates/context/conventions.md +177 -0
- package/templates/context/stack.md +60 -0
- package/templates/correction-report.md +90 -0
- package/templates/feature-proposal.md +35 -0
- package/templates/hybrid/_base.md +254 -0
- package/templates/hybrid/_patterns.md +45 -0
- package/templates/hybrid/create-component.md +127 -0
- package/templates/hybrid/create-file.md +56 -0
- package/templates/hybrid/create-hook.md +145 -0
- package/templates/hybrid/create-service.md +70 -0
- package/templates/hybrid/fix-bug.md +33 -0
- package/templates/hybrid/modify-file.md +55 -0
- package/templates/story.md +68 -0
- package/templates/task.json +56 -0
- package/templates/trace.md +69 -0
|
@@ -0,0 +1,812 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Wogi Flow - Template Generator
|
|
5
|
+
*
|
|
6
|
+
* Analyzes project code and generates customized templates for hybrid mode.
|
|
7
|
+
* Run during onboarding or manually to refresh templates.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* flow-templates generate # Generate all templates
|
|
11
|
+
* flow-templates analyze # Analyze project patterns only
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const { getProjectRoot } = require('./flow-utils');
|
|
17
|
+
|
|
18
|
+
const PROJECT_ROOT = getProjectRoot();
|
|
19
|
+
const TEMPLATES_DIR = path.join(PROJECT_ROOT, 'templates', 'hybrid');
|
|
20
|
+
const WORKFLOW_DIR = path.join(PROJECT_ROOT, '.workflow');
|
|
21
|
+
|
|
22
|
+
// ============================================================
|
|
23
|
+
// Project Analyzer
|
|
24
|
+
// ============================================================
|
|
25
|
+
|
|
26
|
+
class ProjectAnalyzer {
|
|
27
|
+
constructor() {
|
|
28
|
+
this.patterns = {
|
|
29
|
+
framework: null,
|
|
30
|
+
stateManagement: null,
|
|
31
|
+
styling: null,
|
|
32
|
+
testing: null,
|
|
33
|
+
components: [],
|
|
34
|
+
hooks: [],
|
|
35
|
+
services: [],
|
|
36
|
+
utilities: []
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
analyze() {
|
|
41
|
+
console.log('🔍 Analyzing project...\n');
|
|
42
|
+
|
|
43
|
+
this.detectFramework();
|
|
44
|
+
this.detectStateManagement();
|
|
45
|
+
this.detectStyling();
|
|
46
|
+
this.detectTesting();
|
|
47
|
+
this.findExamples();
|
|
48
|
+
this.extractNamingConventions();
|
|
49
|
+
this.extractImportPatterns();
|
|
50
|
+
|
|
51
|
+
return this.patterns;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
detectFramework() {
|
|
55
|
+
const packageJson = this.loadPackageJson();
|
|
56
|
+
if (!packageJson) return;
|
|
57
|
+
|
|
58
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
59
|
+
|
|
60
|
+
if (deps['next']) {
|
|
61
|
+
this.patterns.framework = 'Next.js';
|
|
62
|
+
this.patterns.frameworkVersion = deps['next'];
|
|
63
|
+
} else if (deps['@remix-run/react']) {
|
|
64
|
+
this.patterns.framework = 'Remix';
|
|
65
|
+
} else if (deps['gatsby']) {
|
|
66
|
+
this.patterns.framework = 'Gatsby';
|
|
67
|
+
} else if (deps['vue']) {
|
|
68
|
+
this.patterns.framework = 'Vue';
|
|
69
|
+
} else if (deps['@angular/core']) {
|
|
70
|
+
this.patterns.framework = 'Angular';
|
|
71
|
+
} else if (deps['react']) {
|
|
72
|
+
this.patterns.framework = 'React';
|
|
73
|
+
this.patterns.frameworkVersion = deps['react'];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
console.log(` Framework: ${this.patterns.framework || 'Unknown'}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
detectStateManagement() {
|
|
80
|
+
const packageJson = this.loadPackageJson();
|
|
81
|
+
if (!packageJson) return;
|
|
82
|
+
|
|
83
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
84
|
+
|
|
85
|
+
if (deps['zustand']) {
|
|
86
|
+
this.patterns.stateManagement = 'Zustand';
|
|
87
|
+
} else if (deps['@reduxjs/toolkit'] || deps['redux']) {
|
|
88
|
+
this.patterns.stateManagement = 'Redux';
|
|
89
|
+
} else if (deps['mobx']) {
|
|
90
|
+
this.patterns.stateManagement = 'MobX';
|
|
91
|
+
} else if (deps['recoil']) {
|
|
92
|
+
this.patterns.stateManagement = 'Recoil';
|
|
93
|
+
} else if (deps['jotai']) {
|
|
94
|
+
this.patterns.stateManagement = 'Jotai';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
console.log(` State Management: ${this.patterns.stateManagement || 'None detected'}`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
detectStyling() {
|
|
101
|
+
const packageJson = this.loadPackageJson();
|
|
102
|
+
if (!packageJson) return;
|
|
103
|
+
|
|
104
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
105
|
+
|
|
106
|
+
const stylingOptions = [];
|
|
107
|
+
|
|
108
|
+
if (deps['tailwindcss']) stylingOptions.push('Tailwind CSS');
|
|
109
|
+
if (deps['styled-components']) stylingOptions.push('Styled Components');
|
|
110
|
+
if (deps['@emotion/react']) stylingOptions.push('Emotion');
|
|
111
|
+
if (deps['sass'] || deps['node-sass']) stylingOptions.push('SASS');
|
|
112
|
+
if (deps['@mui/material']) stylingOptions.push('Material UI');
|
|
113
|
+
if (deps['@chakra-ui/react']) stylingOptions.push('Chakra UI');
|
|
114
|
+
if (deps['class-variance-authority']) stylingOptions.push('CVA');
|
|
115
|
+
|
|
116
|
+
this.patterns.styling = stylingOptions.length > 0 ? stylingOptions : ['CSS Modules'];
|
|
117
|
+
console.log(` Styling: ${this.patterns.styling.join(', ')}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
detectTesting() {
|
|
121
|
+
const packageJson = this.loadPackageJson();
|
|
122
|
+
if (!packageJson) return;
|
|
123
|
+
|
|
124
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
125
|
+
|
|
126
|
+
if (deps['vitest']) {
|
|
127
|
+
this.patterns.testing = 'Vitest';
|
|
128
|
+
} else if (deps['jest']) {
|
|
129
|
+
this.patterns.testing = 'Jest';
|
|
130
|
+
} else if (deps['@testing-library/react']) {
|
|
131
|
+
this.patterns.testing = 'React Testing Library';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
console.log(` Testing: ${this.patterns.testing || 'None detected'}`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
findExamples() {
|
|
138
|
+
console.log('\n Finding code examples...');
|
|
139
|
+
|
|
140
|
+
const componentDirs = ['src/components', 'components', 'app/components'];
|
|
141
|
+
for (const dir of componentDirs) {
|
|
142
|
+
if (fs.existsSync(path.join(PROJECT_ROOT, dir))) {
|
|
143
|
+
this.patterns.components = this.findFilesWithExports(dir, /\.(tsx|jsx)$/);
|
|
144
|
+
console.log(` Components: ${this.patterns.components.length} found`);
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const hookDirs = ['src/hooks', 'hooks', 'app/hooks'];
|
|
150
|
+
for (const dir of hookDirs) {
|
|
151
|
+
if (fs.existsSync(path.join(PROJECT_ROOT, dir))) {
|
|
152
|
+
this.patterns.hooks = this.findFilesWithExports(dir, /^use.*\.(ts|tsx)$/);
|
|
153
|
+
console.log(` Hooks: ${this.patterns.hooks.length} found`);
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const serviceDirs = ['src/services', 'services', 'src/api', 'api', 'src/lib'];
|
|
159
|
+
for (const dir of serviceDirs) {
|
|
160
|
+
if (fs.existsSync(path.join(PROJECT_ROOT, dir))) {
|
|
161
|
+
this.patterns.services = this.findFilesWithExports(dir, /\.(ts|js)$/);
|
|
162
|
+
console.log(` Services: ${this.patterns.services.length} found`);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const utilDirs = ['src/utils', 'utils', 'src/lib/utils', 'lib/utils'];
|
|
168
|
+
for (const dir of utilDirs) {
|
|
169
|
+
if (fs.existsSync(path.join(PROJECT_ROOT, dir))) {
|
|
170
|
+
this.patterns.utilities = this.findFilesWithExports(dir, /\.(ts|js)$/);
|
|
171
|
+
console.log(` Utilities: ${this.patterns.utilities.length} found`);
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
findFilesWithExports(dir, pattern) {
|
|
178
|
+
const results = [];
|
|
179
|
+
const fullDir = path.join(PROJECT_ROOT, dir);
|
|
180
|
+
|
|
181
|
+
if (!fs.existsSync(fullDir)) return results;
|
|
182
|
+
|
|
183
|
+
const walkDir = (currentDir) => {
|
|
184
|
+
const files = fs.readdirSync(currentDir);
|
|
185
|
+
|
|
186
|
+
for (const file of files) {
|
|
187
|
+
const filePath = path.join(currentDir, file);
|
|
188
|
+
const stat = fs.statSync(filePath);
|
|
189
|
+
|
|
190
|
+
if (stat.isDirectory() && !file.startsWith('_') && file !== 'node_modules') {
|
|
191
|
+
walkDir(filePath);
|
|
192
|
+
} else if (stat.isFile() && pattern.test(file)) {
|
|
193
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
194
|
+
const relativePath = path.relative(PROJECT_ROOT, filePath);
|
|
195
|
+
|
|
196
|
+
const exports = this.extractExports(content);
|
|
197
|
+
if (exports.length > 0) {
|
|
198
|
+
results.push({
|
|
199
|
+
path: relativePath,
|
|
200
|
+
name: path.basename(file, path.extname(file)),
|
|
201
|
+
exports,
|
|
202
|
+
content: content.slice(0, 3000)
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
walkDir(fullDir);
|
|
210
|
+
return results.slice(0, 5);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
extractExports(content) {
|
|
214
|
+
const exports = [];
|
|
215
|
+
|
|
216
|
+
const namedExportRegex = /export\s+(?:const|function|class|interface|type)\s+(\w+)/g;
|
|
217
|
+
let match;
|
|
218
|
+
while ((match = namedExportRegex.exec(content)) !== null) {
|
|
219
|
+
exports.push(match[1]);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (/export\s+default/.test(content)) {
|
|
223
|
+
exports.push('default');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return exports;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
extractNamingConventions() {
|
|
230
|
+
this.patterns.naming = {
|
|
231
|
+
components: 'PascalCase',
|
|
232
|
+
hooks: 'camelCase with use prefix',
|
|
233
|
+
services: 'camelCase',
|
|
234
|
+
utilities: 'camelCase',
|
|
235
|
+
types: 'PascalCase',
|
|
236
|
+
files: {
|
|
237
|
+
components: 'PascalCase.tsx',
|
|
238
|
+
hooks: 'useXxx.ts',
|
|
239
|
+
services: 'xxxService.ts'
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
extractImportPatterns() {
|
|
245
|
+
const tsconfigPath = path.join(PROJECT_ROOT, 'tsconfig.json');
|
|
246
|
+
if (fs.existsSync(tsconfigPath)) {
|
|
247
|
+
try {
|
|
248
|
+
const tsconfig = JSON.parse(fs.readFileSync(tsconfigPath, 'utf-8'));
|
|
249
|
+
const paths = tsconfig.compilerOptions?.paths || {};
|
|
250
|
+
|
|
251
|
+
this.patterns.importAliases = Object.keys(paths).map(alias => ({
|
|
252
|
+
alias: alias.replace('/*', ''),
|
|
253
|
+
path: paths[alias][0]?.replace('/*', '') || ''
|
|
254
|
+
}));
|
|
255
|
+
|
|
256
|
+
console.log(`\n Import aliases: ${this.patterns.importAliases.map(a => a.alias).join(', ') || 'None'}`);
|
|
257
|
+
} catch (err) {
|
|
258
|
+
// Ignore tsconfig parse errors
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
loadPackageJson() {
|
|
264
|
+
const pkgPath = path.join(PROJECT_ROOT, 'package.json');
|
|
265
|
+
if (fs.existsSync(pkgPath)) {
|
|
266
|
+
return JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
267
|
+
}
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// ============================================================
|
|
273
|
+
// Template Generator
|
|
274
|
+
// ============================================================
|
|
275
|
+
|
|
276
|
+
class TemplateGenerator {
|
|
277
|
+
constructor(patterns) {
|
|
278
|
+
this.patterns = patterns;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
generateAll() {
|
|
282
|
+
console.log('\n📝 Generating templates...\n');
|
|
283
|
+
|
|
284
|
+
if (!fs.existsSync(TEMPLATES_DIR)) {
|
|
285
|
+
fs.mkdirSync(TEMPLATES_DIR, { recursive: true });
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
this.generateBase();
|
|
289
|
+
this.generatePatterns();
|
|
290
|
+
this.generateComponentTemplate();
|
|
291
|
+
this.generateHookTemplate();
|
|
292
|
+
this.generateServiceTemplate();
|
|
293
|
+
this.generateUtilityTemplate();
|
|
294
|
+
this.generatePageTemplate();
|
|
295
|
+
this.generateTypeTemplate();
|
|
296
|
+
this.generateModifyFileTemplate();
|
|
297
|
+
this.generateTestTemplate();
|
|
298
|
+
this.generateFixBugTemplate();
|
|
299
|
+
|
|
300
|
+
console.log('\n✅ Templates generated successfully!\n');
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
generateBase() {
|
|
304
|
+
const template = `# Universal Rules
|
|
305
|
+
|
|
306
|
+
You are generating code for a ${this.patterns.framework || 'JavaScript'} project.
|
|
307
|
+
|
|
308
|
+
## Critical Rules
|
|
309
|
+
|
|
310
|
+
1. Output ONLY code. No explanations, no markdown code blocks, no preamble.
|
|
311
|
+
2. Use TypeScript with proper types.
|
|
312
|
+
3. Follow the existing patterns shown in _patterns.md
|
|
313
|
+
4. Include all necessary imports at the top.
|
|
314
|
+
5. Add brief JSDoc comments for exported functions/components.
|
|
315
|
+
6. Do NOT create files that weren't requested.
|
|
316
|
+
7. Match the project's naming conventions exactly.
|
|
317
|
+
|
|
318
|
+
## Project Stack
|
|
319
|
+
|
|
320
|
+
- Framework: ${this.patterns.framework || 'React'}
|
|
321
|
+
- State Management: ${this.patterns.stateManagement || 'React hooks'}
|
|
322
|
+
- Styling: ${this.patterns.styling?.join(', ') || 'CSS'}
|
|
323
|
+
- Testing: ${this.patterns.testing || 'None configured'}
|
|
324
|
+
|
|
325
|
+
## Import Aliases
|
|
326
|
+
|
|
327
|
+
${this.patterns.importAliases?.map(a => `- \`${a.alias}\` → \`${a.path}\``).join('\n') || 'No aliases configured'}
|
|
328
|
+
|
|
329
|
+
## Validation
|
|
330
|
+
|
|
331
|
+
After you output code, it will be automatically validated:
|
|
332
|
+
- TypeScript compilation check
|
|
333
|
+
- ESLint check
|
|
334
|
+
|
|
335
|
+
If validation fails, you'll receive the error and must fix it.
|
|
336
|
+
`;
|
|
337
|
+
|
|
338
|
+
fs.writeFileSync(path.join(TEMPLATES_DIR, '_base.md'), template);
|
|
339
|
+
console.log(' ✓ _base.md');
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
generatePatterns() {
|
|
343
|
+
let template = `# Project Patterns
|
|
344
|
+
|
|
345
|
+
These patterns are extracted from the actual codebase. Follow them exactly.
|
|
346
|
+
|
|
347
|
+
`;
|
|
348
|
+
|
|
349
|
+
const componentExample = this.patterns.components?.[0];
|
|
350
|
+
if (componentExample) {
|
|
351
|
+
template += `## Component Pattern
|
|
352
|
+
|
|
353
|
+
Based on: \`${componentExample.path}\`
|
|
354
|
+
|
|
355
|
+
\`\`\`typescript
|
|
356
|
+
${componentExample.content}
|
|
357
|
+
\`\`\`
|
|
358
|
+
|
|
359
|
+
`;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const hookExample = this.patterns.hooks?.[0];
|
|
363
|
+
if (hookExample) {
|
|
364
|
+
template += `## Hook Pattern
|
|
365
|
+
|
|
366
|
+
Based on: \`${hookExample.path}\`
|
|
367
|
+
|
|
368
|
+
\`\`\`typescript
|
|
369
|
+
${hookExample.content}
|
|
370
|
+
\`\`\`
|
|
371
|
+
|
|
372
|
+
`;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const serviceExample = this.patterns.services?.[0];
|
|
376
|
+
if (serviceExample) {
|
|
377
|
+
template += `## Service Pattern
|
|
378
|
+
|
|
379
|
+
Based on: \`${serviceExample.path}\`
|
|
380
|
+
|
|
381
|
+
\`\`\`typescript
|
|
382
|
+
${serviceExample.content}
|
|
383
|
+
\`\`\`
|
|
384
|
+
|
|
385
|
+
`;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
template += `## Naming Conventions
|
|
389
|
+
|
|
390
|
+
- Components: PascalCase (e.g., \`UserProfile.tsx\`)
|
|
391
|
+
- Hooks: camelCase with \`use\` prefix (e.g., \`useAuth.ts\`)
|
|
392
|
+
- Services: camelCase with \`Service\` suffix (e.g., \`authService.ts\`)
|
|
393
|
+
- Utilities: camelCase (e.g., \`formatDate.ts\`)
|
|
394
|
+
- Types/Interfaces: PascalCase (e.g., \`UserProfile\`, \`AuthResponse\`)
|
|
395
|
+
|
|
396
|
+
## Import Order
|
|
397
|
+
|
|
398
|
+
1. React/framework imports
|
|
399
|
+
2. Third-party libraries
|
|
400
|
+
3. Aliased imports (@/ or ~/)
|
|
401
|
+
4. Relative imports
|
|
402
|
+
5. Type imports (with \`type\` keyword)
|
|
403
|
+
|
|
404
|
+
## File Structure
|
|
405
|
+
|
|
406
|
+
\`\`\`
|
|
407
|
+
src/
|
|
408
|
+
├── components/ # UI components
|
|
409
|
+
├── hooks/ # Custom React hooks
|
|
410
|
+
├── services/ # API and business logic
|
|
411
|
+
├── lib/ # Utilities and helpers
|
|
412
|
+
├── types/ # TypeScript type definitions
|
|
413
|
+
└── app/ or pages/ # Routes/pages
|
|
414
|
+
\`\`\`
|
|
415
|
+
`;
|
|
416
|
+
|
|
417
|
+
fs.writeFileSync(path.join(TEMPLATES_DIR, '_patterns.md'), template);
|
|
418
|
+
console.log(' ✓ _patterns.md');
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
generateComponentTemplate() {
|
|
422
|
+
const template = `{{include _base.md}}
|
|
423
|
+
|
|
424
|
+
# Task: Create React Component
|
|
425
|
+
|
|
426
|
+
{{include _patterns.md}}
|
|
427
|
+
|
|
428
|
+
## Component Specification
|
|
429
|
+
|
|
430
|
+
**Name:** {{name}}
|
|
431
|
+
**File Path:** {{path}}
|
|
432
|
+
|
|
433
|
+
**Props:**
|
|
434
|
+
{{props}}
|
|
435
|
+
|
|
436
|
+
**Description:**
|
|
437
|
+
{{description}}
|
|
438
|
+
|
|
439
|
+
**Must Use These Existing Components/Hooks:**
|
|
440
|
+
{{uses}}
|
|
441
|
+
|
|
442
|
+
**Expected Behavior:**
|
|
443
|
+
{{behavior}}
|
|
444
|
+
|
|
445
|
+
## Requirements
|
|
446
|
+
|
|
447
|
+
1. Create a functional component with proper TypeScript types
|
|
448
|
+
2. Define a Props interface named \`{{name}}Props\`
|
|
449
|
+
3. Export as named export: \`export function {{name}}\`
|
|
450
|
+
4. Use the existing components and hooks listed above
|
|
451
|
+
5. Follow the component pattern from _patterns.md exactly
|
|
452
|
+
6. Add JSDoc comment describing the component
|
|
453
|
+
|
|
454
|
+
## Output
|
|
455
|
+
|
|
456
|
+
Output the complete file content starting with imports. No markdown code blocks.
|
|
457
|
+
`;
|
|
458
|
+
|
|
459
|
+
fs.writeFileSync(path.join(TEMPLATES_DIR, 'create-component.md'), template);
|
|
460
|
+
console.log(' ✓ create-component.md');
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
generateHookTemplate() {
|
|
464
|
+
const template = `{{include _base.md}}
|
|
465
|
+
|
|
466
|
+
# Task: Create React Hook
|
|
467
|
+
|
|
468
|
+
{{include _patterns.md}}
|
|
469
|
+
|
|
470
|
+
## Hook Specification
|
|
471
|
+
|
|
472
|
+
**Name:** {{name}}
|
|
473
|
+
**File Path:** {{path}}
|
|
474
|
+
|
|
475
|
+
**Return Values:**
|
|
476
|
+
{{returns}}
|
|
477
|
+
|
|
478
|
+
**Description:**
|
|
479
|
+
{{description}}
|
|
480
|
+
|
|
481
|
+
**Dependencies/Uses:**
|
|
482
|
+
{{uses}}
|
|
483
|
+
|
|
484
|
+
## Requirements
|
|
485
|
+
|
|
486
|
+
1. Name must start with "use"
|
|
487
|
+
2. Return an object with named properties (not array)
|
|
488
|
+
3. Handle loading and error states if applicable
|
|
489
|
+
4. Define return type interface
|
|
490
|
+
5. Follow the hook pattern from _patterns.md exactly
|
|
491
|
+
6. Add JSDoc comment describing the hook
|
|
492
|
+
|
|
493
|
+
## Output
|
|
494
|
+
|
|
495
|
+
Output the complete file content starting with imports. No markdown code blocks.
|
|
496
|
+
`;
|
|
497
|
+
|
|
498
|
+
fs.writeFileSync(path.join(TEMPLATES_DIR, 'create-hook.md'), template);
|
|
499
|
+
console.log(' ✓ create-hook.md');
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
generateServiceTemplate() {
|
|
503
|
+
const template = `{{include _base.md}}
|
|
504
|
+
|
|
505
|
+
# Task: Create Service
|
|
506
|
+
|
|
507
|
+
{{include _patterns.md}}
|
|
508
|
+
|
|
509
|
+
## Service Specification
|
|
510
|
+
|
|
511
|
+
**Name:** {{name}}
|
|
512
|
+
**File Path:** {{path}}
|
|
513
|
+
|
|
514
|
+
**Methods:**
|
|
515
|
+
{{methods}}
|
|
516
|
+
|
|
517
|
+
**Description:**
|
|
518
|
+
{{description}}
|
|
519
|
+
|
|
520
|
+
**Types to Define:**
|
|
521
|
+
{{types}}
|
|
522
|
+
|
|
523
|
+
## Requirements
|
|
524
|
+
|
|
525
|
+
1. Export as a singleton object or class
|
|
526
|
+
2. Define all TypeScript types for parameters and returns
|
|
527
|
+
3. Handle errors appropriately
|
|
528
|
+
4. Follow the service pattern from _patterns.md exactly
|
|
529
|
+
5. Add JSDoc comments for each method
|
|
530
|
+
|
|
531
|
+
## Output
|
|
532
|
+
|
|
533
|
+
Output the complete file content starting with imports. No markdown code blocks.
|
|
534
|
+
`;
|
|
535
|
+
|
|
536
|
+
fs.writeFileSync(path.join(TEMPLATES_DIR, 'create-service.md'), template);
|
|
537
|
+
console.log(' ✓ create-service.md');
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
generateUtilityTemplate() {
|
|
541
|
+
const template = `{{include _base.md}}
|
|
542
|
+
|
|
543
|
+
# Task: Create Utility Function(s)
|
|
544
|
+
|
|
545
|
+
{{include _patterns.md}}
|
|
546
|
+
|
|
547
|
+
## Utility Specification
|
|
548
|
+
|
|
549
|
+
**File Path:** {{path}}
|
|
550
|
+
|
|
551
|
+
**Functions:**
|
|
552
|
+
{{functions}}
|
|
553
|
+
|
|
554
|
+
**Description:**
|
|
555
|
+
{{description}}
|
|
556
|
+
|
|
557
|
+
## Requirements
|
|
558
|
+
|
|
559
|
+
1. Pure functions with no side effects where possible
|
|
560
|
+
2. Full TypeScript types for parameters and returns
|
|
561
|
+
3. Handle edge cases
|
|
562
|
+
4. Add JSDoc comments with examples
|
|
563
|
+
5. Export each function as named export
|
|
564
|
+
|
|
565
|
+
## Output
|
|
566
|
+
|
|
567
|
+
Output the complete file content starting with imports. No markdown code blocks.
|
|
568
|
+
`;
|
|
569
|
+
|
|
570
|
+
fs.writeFileSync(path.join(TEMPLATES_DIR, 'create-utility.md'), template);
|
|
571
|
+
console.log(' ✓ create-utility.md');
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
generatePageTemplate() {
|
|
575
|
+
const framework = this.patterns.framework || 'React';
|
|
576
|
+
|
|
577
|
+
let template = `{{include _base.md}}
|
|
578
|
+
|
|
579
|
+
# Task: Create Page Component
|
|
580
|
+
|
|
581
|
+
{{include _patterns.md}}
|
|
582
|
+
|
|
583
|
+
## Page Specification
|
|
584
|
+
|
|
585
|
+
**Name:** {{name}}
|
|
586
|
+
**File Path:** {{path}}
|
|
587
|
+
|
|
588
|
+
**Description:**
|
|
589
|
+
{{description}}
|
|
590
|
+
|
|
591
|
+
**Required Components:**
|
|
592
|
+
{{components}}
|
|
593
|
+
|
|
594
|
+
**Data Requirements:**
|
|
595
|
+
{{data}}
|
|
596
|
+
|
|
597
|
+
`;
|
|
598
|
+
|
|
599
|
+
if (framework === 'Next.js') {
|
|
600
|
+
template += `## Next.js Requirements
|
|
601
|
+
|
|
602
|
+
- Use App Router conventions if path is in \`app/\` directory
|
|
603
|
+
- Use Pages Router conventions if path is in \`pages/\` directory
|
|
604
|
+
- Export metadata if needed
|
|
605
|
+
- Handle loading and error states
|
|
606
|
+
|
|
607
|
+
`;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
template += `## Output
|
|
611
|
+
|
|
612
|
+
Output the complete file content starting with imports. No markdown code blocks.
|
|
613
|
+
`;
|
|
614
|
+
|
|
615
|
+
fs.writeFileSync(path.join(TEMPLATES_DIR, 'create-page.md'), template);
|
|
616
|
+
console.log(' ✓ create-page.md');
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
generateTypeTemplate() {
|
|
620
|
+
const template = `{{include _base.md}}
|
|
621
|
+
|
|
622
|
+
# Task: Create TypeScript Types
|
|
623
|
+
|
|
624
|
+
## Type Specification
|
|
625
|
+
|
|
626
|
+
**File Path:** {{path}}
|
|
627
|
+
|
|
628
|
+
**Types to Create:**
|
|
629
|
+
{{types}}
|
|
630
|
+
|
|
631
|
+
**Description:**
|
|
632
|
+
{{description}}
|
|
633
|
+
|
|
634
|
+
## Requirements
|
|
635
|
+
|
|
636
|
+
1. Use \`interface\` for object shapes that might be extended
|
|
637
|
+
2. Use \`type\` for unions, intersections, or simple aliases
|
|
638
|
+
3. Export all types
|
|
639
|
+
4. Add JSDoc comments explaining each type
|
|
640
|
+
5. Use descriptive property names
|
|
641
|
+
|
|
642
|
+
## Output
|
|
643
|
+
|
|
644
|
+
Output the complete file content. No markdown code blocks.
|
|
645
|
+
`;
|
|
646
|
+
|
|
647
|
+
fs.writeFileSync(path.join(TEMPLATES_DIR, 'create-type.md'), template);
|
|
648
|
+
console.log(' ✓ create-type.md');
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
generateModifyFileTemplate() {
|
|
652
|
+
const template = `{{include _base.md}}
|
|
653
|
+
|
|
654
|
+
# Task: Modify Existing File
|
|
655
|
+
|
|
656
|
+
## File to Modify
|
|
657
|
+
|
|
658
|
+
**Path:** {{path}}
|
|
659
|
+
|
|
660
|
+
## Current File Content
|
|
661
|
+
|
|
662
|
+
\`\`\`
|
|
663
|
+
{{currentContent}}
|
|
664
|
+
\`\`\`
|
|
665
|
+
|
|
666
|
+
## Required Changes
|
|
667
|
+
|
|
668
|
+
{{modifications}}
|
|
669
|
+
|
|
670
|
+
## Requirements
|
|
671
|
+
|
|
672
|
+
1. Make ONLY the specified changes
|
|
673
|
+
2. Preserve all existing code and formatting
|
|
674
|
+
3. Maintain proper imports (add new ones if needed)
|
|
675
|
+
4. Keep the file's existing style
|
|
676
|
+
|
|
677
|
+
## Output
|
|
678
|
+
|
|
679
|
+
Output the COMPLETE modified file with all changes applied.
|
|
680
|
+
Do NOT output a diff or partial content.
|
|
681
|
+
Output the entire file content, starting with imports.
|
|
682
|
+
No markdown code blocks.
|
|
683
|
+
`;
|
|
684
|
+
|
|
685
|
+
fs.writeFileSync(path.join(TEMPLATES_DIR, 'modify-file.md'), template);
|
|
686
|
+
console.log(' ✓ modify-file.md');
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
generateTestTemplate() {
|
|
690
|
+
const testing = this.patterns.testing || 'Jest';
|
|
691
|
+
|
|
692
|
+
const template = `{{include _base.md}}
|
|
693
|
+
|
|
694
|
+
# Task: Create Test File
|
|
695
|
+
|
|
696
|
+
## Test Specification
|
|
697
|
+
|
|
698
|
+
**File Path:** {{path}}
|
|
699
|
+
**Testing:** {{testTarget}}
|
|
700
|
+
**Test Framework:** ${testing}
|
|
701
|
+
|
|
702
|
+
**Test Cases:**
|
|
703
|
+
{{testCases}}
|
|
704
|
+
|
|
705
|
+
## Requirements
|
|
706
|
+
|
|
707
|
+
1. Import the module being tested
|
|
708
|
+
2. Group tests with \`describe\` blocks
|
|
709
|
+
3. Use clear test names that describe expected behavior
|
|
710
|
+
4. Include happy path and edge cases
|
|
711
|
+
5. Mock external dependencies
|
|
712
|
+
|
|
713
|
+
## Output
|
|
714
|
+
|
|
715
|
+
Output the complete test file. No markdown code blocks.
|
|
716
|
+
`;
|
|
717
|
+
|
|
718
|
+
fs.writeFileSync(path.join(TEMPLATES_DIR, 'create-test.md'), template);
|
|
719
|
+
console.log(' ✓ create-test.md');
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
generateFixBugTemplate() {
|
|
723
|
+
const template = `{{include _base.md}}
|
|
724
|
+
|
|
725
|
+
# Task: Fix Bug
|
|
726
|
+
|
|
727
|
+
## Bug Details
|
|
728
|
+
|
|
729
|
+
**File:** {{path}}
|
|
730
|
+
**Bug Description:** {{bugDescription}}
|
|
731
|
+
**Expected Behavior:** {{expectedBehavior}}
|
|
732
|
+
**Actual Behavior:** {{actualBehavior}}
|
|
733
|
+
|
|
734
|
+
## Current File Content
|
|
735
|
+
|
|
736
|
+
\`\`\`
|
|
737
|
+
{{currentContent}}
|
|
738
|
+
\`\`\`
|
|
739
|
+
|
|
740
|
+
## Error Message (if any)
|
|
741
|
+
|
|
742
|
+
{{errorMessage}}
|
|
743
|
+
|
|
744
|
+
## Requirements
|
|
745
|
+
|
|
746
|
+
1. Identify the root cause
|
|
747
|
+
2. Fix ONLY what's necessary
|
|
748
|
+
3. Don't refactor unrelated code
|
|
749
|
+
4. Ensure the fix doesn't break other functionality
|
|
750
|
+
5. Add a comment explaining the fix if it's not obvious
|
|
751
|
+
|
|
752
|
+
## Output
|
|
753
|
+
|
|
754
|
+
Output the COMPLETE fixed file.
|
|
755
|
+
No markdown code blocks.
|
|
756
|
+
`;
|
|
757
|
+
|
|
758
|
+
fs.writeFileSync(path.join(TEMPLATES_DIR, 'fix-bug.md'), template);
|
|
759
|
+
console.log(' ✓ fix-bug.md');
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// ============================================================
|
|
764
|
+
// Main CLI
|
|
765
|
+
// ============================================================
|
|
766
|
+
|
|
767
|
+
async function main() {
|
|
768
|
+
const [,, command] = process.argv;
|
|
769
|
+
|
|
770
|
+
switch (command) {
|
|
771
|
+
case 'generate': {
|
|
772
|
+
const analyzer = new ProjectAnalyzer();
|
|
773
|
+
const patterns = analyzer.analyze();
|
|
774
|
+
|
|
775
|
+
const generator = new TemplateGenerator(patterns);
|
|
776
|
+
generator.generateAll();
|
|
777
|
+
|
|
778
|
+
const stateDir = path.join(WORKFLOW_DIR, 'state');
|
|
779
|
+
if (!fs.existsSync(stateDir)) {
|
|
780
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
781
|
+
}
|
|
782
|
+
const patternsPath = path.join(stateDir, 'project-patterns.json');
|
|
783
|
+
fs.writeFileSync(patternsPath, JSON.stringify(patterns, null, 2));
|
|
784
|
+
console.log(`Patterns saved to: ${patternsPath}`);
|
|
785
|
+
break;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
case 'analyze': {
|
|
789
|
+
const analyzer = new ProjectAnalyzer();
|
|
790
|
+
const patterns = analyzer.analyze();
|
|
791
|
+
console.log('\nPatterns:', JSON.stringify(patterns, null, 2));
|
|
792
|
+
break;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
default:
|
|
796
|
+
console.log(`
|
|
797
|
+
Wogi Flow Template Generator
|
|
798
|
+
|
|
799
|
+
Commands:
|
|
800
|
+
generate Analyze project and generate templates
|
|
801
|
+
analyze Analyze project patterns only
|
|
802
|
+
|
|
803
|
+
Usage:
|
|
804
|
+
./scripts/flow-templates.js generate
|
|
805
|
+
`);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
main().catch(err => {
|
|
810
|
+
console.error(`Error: ${err.message}`);
|
|
811
|
+
process.exit(1);
|
|
812
|
+
});
|