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.
Files changed (221) hide show
  1. package/.workflow/agents/reviewer.md +81 -0
  2. package/.workflow/agents/security.md +94 -0
  3. package/.workflow/agents/story-writer.md +58 -0
  4. package/.workflow/bridges/base-bridge.js +395 -0
  5. package/.workflow/bridges/claude-bridge.js +434 -0
  6. package/.workflow/bridges/index.js +130 -0
  7. package/.workflow/lib/assumption-detector.js +481 -0
  8. package/.workflow/lib/config-substitution.js +371 -0
  9. package/.workflow/lib/failure-categories.js +478 -0
  10. package/.workflow/state/app-map.md.template +15 -0
  11. package/.workflow/state/architecture.md.template +24 -0
  12. package/.workflow/state/component-index.json.template +5 -0
  13. package/.workflow/state/decisions.md.template +15 -0
  14. package/.workflow/state/feedback-patterns.md.template +9 -0
  15. package/.workflow/state/knowledge-sync.json.template +6 -0
  16. package/.workflow/state/progress.md.template +14 -0
  17. package/.workflow/state/ready.json.template +7 -0
  18. package/.workflow/state/request-log.md.template +14 -0
  19. package/.workflow/state/session-state.json.template +11 -0
  20. package/.workflow/state/stack.md.template +33 -0
  21. package/.workflow/state/testing.md.template +36 -0
  22. package/.workflow/templates/claude-md.hbs +257 -0
  23. package/.workflow/templates/correction-report.md +67 -0
  24. package/.workflow/templates/gemini-md.hbs +52 -0
  25. package/README.md +1802 -0
  26. package/bin/flow +205 -0
  27. package/lib/index.js +33 -0
  28. package/lib/installer.js +467 -0
  29. package/lib/release-channel.js +269 -0
  30. package/lib/skill-registry.js +526 -0
  31. package/lib/upgrader.js +401 -0
  32. package/lib/utils.js +305 -0
  33. package/package.json +64 -0
  34. package/scripts/flow +985 -0
  35. package/scripts/flow-adaptive-learning.js +1259 -0
  36. package/scripts/flow-aggregate.js +488 -0
  37. package/scripts/flow-archive +133 -0
  38. package/scripts/flow-auto-context.js +1015 -0
  39. package/scripts/flow-auto-learn.js +615 -0
  40. package/scripts/flow-bridge.js +223 -0
  41. package/scripts/flow-browser-suggest.js +316 -0
  42. package/scripts/flow-bug.js +247 -0
  43. package/scripts/flow-cascade.js +711 -0
  44. package/scripts/flow-changelog +85 -0
  45. package/scripts/flow-checkpoint.js +483 -0
  46. package/scripts/flow-cli.js +403 -0
  47. package/scripts/flow-code-intelligence.js +760 -0
  48. package/scripts/flow-complexity.js +502 -0
  49. package/scripts/flow-config-set.js +152 -0
  50. package/scripts/flow-constants.js +157 -0
  51. package/scripts/flow-context +152 -0
  52. package/scripts/flow-context-init.js +482 -0
  53. package/scripts/flow-context-monitor.js +384 -0
  54. package/scripts/flow-context-scoring.js +886 -0
  55. package/scripts/flow-correct.js +458 -0
  56. package/scripts/flow-damage-control.js +985 -0
  57. package/scripts/flow-deps +101 -0
  58. package/scripts/flow-diff.js +700 -0
  59. package/scripts/flow-done +151 -0
  60. package/scripts/flow-done.js +489 -0
  61. package/scripts/flow-durable-session.js +1541 -0
  62. package/scripts/flow-entropy-monitor.js +345 -0
  63. package/scripts/flow-export-profile +349 -0
  64. package/scripts/flow-export-scanner.js +1046 -0
  65. package/scripts/flow-figma-confirm.js +400 -0
  66. package/scripts/flow-figma-extract.js +496 -0
  67. package/scripts/flow-figma-generate.js +683 -0
  68. package/scripts/flow-figma-index.js +909 -0
  69. package/scripts/flow-figma-match.js +617 -0
  70. package/scripts/flow-figma-mcp-server.js +518 -0
  71. package/scripts/flow-figma-pipeline.js +414 -0
  72. package/scripts/flow-file-ops.js +301 -0
  73. package/scripts/flow-gate-confidence.js +825 -0
  74. package/scripts/flow-guided-edit.js +659 -0
  75. package/scripts/flow-health +185 -0
  76. package/scripts/flow-health.js +413 -0
  77. package/scripts/flow-hooks.js +556 -0
  78. package/scripts/flow-http-client.js +249 -0
  79. package/scripts/flow-hybrid-detect.js +167 -0
  80. package/scripts/flow-hybrid-interactive.js +591 -0
  81. package/scripts/flow-hybrid-test.js +152 -0
  82. package/scripts/flow-import-profile +439 -0
  83. package/scripts/flow-init +253 -0
  84. package/scripts/flow-instruction-richness.js +827 -0
  85. package/scripts/flow-jira-integration.js +579 -0
  86. package/scripts/flow-knowledge-router.js +522 -0
  87. package/scripts/flow-knowledge-sync.js +589 -0
  88. package/scripts/flow-linear-integration.js +631 -0
  89. package/scripts/flow-links.js +774 -0
  90. package/scripts/flow-log-manager.js +559 -0
  91. package/scripts/flow-loop-enforcer.js +1246 -0
  92. package/scripts/flow-loop-retry-learning.js +630 -0
  93. package/scripts/flow-lsp.js +923 -0
  94. package/scripts/flow-map-index +348 -0
  95. package/scripts/flow-map-sync +201 -0
  96. package/scripts/flow-memory-blocks.js +668 -0
  97. package/scripts/flow-memory-compactor.js +350 -0
  98. package/scripts/flow-memory-db.js +1110 -0
  99. package/scripts/flow-memory-sync.js +484 -0
  100. package/scripts/flow-metrics.js +353 -0
  101. package/scripts/flow-migrate-ids.js +370 -0
  102. package/scripts/flow-model-adapter.js +802 -0
  103. package/scripts/flow-model-router.js +884 -0
  104. package/scripts/flow-models.js +1231 -0
  105. package/scripts/flow-morning.js +517 -0
  106. package/scripts/flow-multi-approach.js +660 -0
  107. package/scripts/flow-new-feature +86 -0
  108. package/scripts/flow-onboard +1042 -0
  109. package/scripts/flow-orchestrate-llm.js +459 -0
  110. package/scripts/flow-orchestrate.js +3592 -0
  111. package/scripts/flow-output.js +123 -0
  112. package/scripts/flow-parallel-detector.js +399 -0
  113. package/scripts/flow-parallel-dispatch.js +987 -0
  114. package/scripts/flow-parallel.js +428 -0
  115. package/scripts/flow-pattern-enforcer.js +600 -0
  116. package/scripts/flow-prd-manager.js +282 -0
  117. package/scripts/flow-progress.js +323 -0
  118. package/scripts/flow-project-analyzer.js +975 -0
  119. package/scripts/flow-prompt-composer.js +487 -0
  120. package/scripts/flow-providers.js +1381 -0
  121. package/scripts/flow-queue.js +308 -0
  122. package/scripts/flow-ready +82 -0
  123. package/scripts/flow-ready.js +189 -0
  124. package/scripts/flow-regression.js +396 -0
  125. package/scripts/flow-response-parser.js +450 -0
  126. package/scripts/flow-resume.js +284 -0
  127. package/scripts/flow-rules-sync.js +439 -0
  128. package/scripts/flow-run-trace.js +718 -0
  129. package/scripts/flow-safety.js +587 -0
  130. package/scripts/flow-search +104 -0
  131. package/scripts/flow-security.js +481 -0
  132. package/scripts/flow-session-end +106 -0
  133. package/scripts/flow-session-end.js +437 -0
  134. package/scripts/flow-session-state.js +671 -0
  135. package/scripts/flow-setup-hooks +216 -0
  136. package/scripts/flow-setup-hooks.js +377 -0
  137. package/scripts/flow-skill-create.js +329 -0
  138. package/scripts/flow-skill-creator.js +572 -0
  139. package/scripts/flow-skill-generator.js +1046 -0
  140. package/scripts/flow-skill-learn.js +880 -0
  141. package/scripts/flow-skill-matcher.js +578 -0
  142. package/scripts/flow-spec-generator.js +820 -0
  143. package/scripts/flow-stack-wizard.js +895 -0
  144. package/scripts/flow-standup +162 -0
  145. package/scripts/flow-start +74 -0
  146. package/scripts/flow-start.js +235 -0
  147. package/scripts/flow-status +110 -0
  148. package/scripts/flow-status.js +301 -0
  149. package/scripts/flow-step-browser.js +83 -0
  150. package/scripts/flow-step-changelog.js +217 -0
  151. package/scripts/flow-step-comments.js +306 -0
  152. package/scripts/flow-step-complexity.js +234 -0
  153. package/scripts/flow-step-coverage.js +218 -0
  154. package/scripts/flow-step-knowledge.js +193 -0
  155. package/scripts/flow-step-pr-tests.js +364 -0
  156. package/scripts/flow-step-regression.js +89 -0
  157. package/scripts/flow-step-review.js +516 -0
  158. package/scripts/flow-step-security.js +162 -0
  159. package/scripts/flow-step-silent-failures.js +290 -0
  160. package/scripts/flow-step-simplifier.js +346 -0
  161. package/scripts/flow-story +105 -0
  162. package/scripts/flow-story.js +500 -0
  163. package/scripts/flow-suspend.js +252 -0
  164. package/scripts/flow-sync-daemon.js +654 -0
  165. package/scripts/flow-task-analyzer.js +606 -0
  166. package/scripts/flow-team-dashboard.js +748 -0
  167. package/scripts/flow-team-sync.js +752 -0
  168. package/scripts/flow-team.js +977 -0
  169. package/scripts/flow-tech-options.js +528 -0
  170. package/scripts/flow-templates.js +812 -0
  171. package/scripts/flow-tiered-learning.js +728 -0
  172. package/scripts/flow-trace +204 -0
  173. package/scripts/flow-transcript-chunking.js +1106 -0
  174. package/scripts/flow-transcript-digest.js +7918 -0
  175. package/scripts/flow-transcript-language.js +465 -0
  176. package/scripts/flow-transcript-parsing.js +1085 -0
  177. package/scripts/flow-transcript-stories.js +2194 -0
  178. package/scripts/flow-update-map +224 -0
  179. package/scripts/flow-utils.js +2242 -0
  180. package/scripts/flow-verification.js +644 -0
  181. package/scripts/flow-verify.js +1177 -0
  182. package/scripts/flow-voice-input.js +638 -0
  183. package/scripts/flow-watch +168 -0
  184. package/scripts/flow-workflow-steps.js +521 -0
  185. package/scripts/flow-workflow.js +1029 -0
  186. package/scripts/flow-worktree.js +489 -0
  187. package/scripts/hooks/adapters/base-adapter.js +102 -0
  188. package/scripts/hooks/adapters/claude-code.js +359 -0
  189. package/scripts/hooks/adapters/index.js +79 -0
  190. package/scripts/hooks/core/component-check.js +341 -0
  191. package/scripts/hooks/core/index.js +35 -0
  192. package/scripts/hooks/core/loop-check.js +241 -0
  193. package/scripts/hooks/core/session-context.js +294 -0
  194. package/scripts/hooks/core/task-gate.js +177 -0
  195. package/scripts/hooks/core/validation.js +230 -0
  196. package/scripts/hooks/entry/claude-code/post-tool-use.js +65 -0
  197. package/scripts/hooks/entry/claude-code/pre-tool-use.js +89 -0
  198. package/scripts/hooks/entry/claude-code/session-end.js +87 -0
  199. package/scripts/hooks/entry/claude-code/session-start.js +46 -0
  200. package/scripts/hooks/entry/claude-code/stop.js +43 -0
  201. package/scripts/postinstall.js +139 -0
  202. package/templates/browser-test-flow.json +56 -0
  203. package/templates/bug-report.md +43 -0
  204. package/templates/component-detail.md +42 -0
  205. package/templates/component.stories.tsx +49 -0
  206. package/templates/context/constraints.md +83 -0
  207. package/templates/context/conventions.md +177 -0
  208. package/templates/context/stack.md +60 -0
  209. package/templates/correction-report.md +90 -0
  210. package/templates/feature-proposal.md +35 -0
  211. package/templates/hybrid/_base.md +254 -0
  212. package/templates/hybrid/_patterns.md +45 -0
  213. package/templates/hybrid/create-component.md +127 -0
  214. package/templates/hybrid/create-file.md +56 -0
  215. package/templates/hybrid/create-hook.md +145 -0
  216. package/templates/hybrid/create-service.md +70 -0
  217. package/templates/hybrid/fix-bug.md +33 -0
  218. package/templates/hybrid/modify-file.md +55 -0
  219. package/templates/story.md +68 -0
  220. package/templates/task.json +56 -0
  221. package/templates/trace.md +69 -0
@@ -0,0 +1,572 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Wogi Flow - Skill Auto-Creator
5
+ *
6
+ * Automatically detects frameworks in the project and offers to create
7
+ * skills with knowledge from official documentation.
8
+ *
9
+ * Features:
10
+ * - Scans project for framework indicators (package.json, file patterns)
11
+ * - Fetches official documentation summaries
12
+ * - Generates skill structure with patterns/anti-patterns
13
+ * - Integrates with existing skill system
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+ const { getConfig, getProjectRoot } = require('./flow-utils');
19
+
20
+ /**
21
+ * Detect frameworks in the project
22
+ */
23
+ function detectFrameworks() {
24
+ const projectRoot = getProjectRoot();
25
+ const config = getConfig();
26
+ const skillLearning = config.skillLearning || {};
27
+ const patterns = skillLearning.frameworkDetectionPatterns || {};
28
+
29
+ const detected = [];
30
+
31
+ // Check package.json for dependencies
32
+ const packageJsonPath = path.join(projectRoot, 'package.json');
33
+ let packageDeps = {};
34
+
35
+ if (fs.existsSync(packageJsonPath)) {
36
+ try {
37
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
38
+ packageDeps = {
39
+ ...pkg.dependencies,
40
+ ...pkg.devDependencies
41
+ };
42
+ } catch {
43
+ // Ignore parse errors
44
+ }
45
+ }
46
+
47
+ // Check requirements.txt for Python
48
+ const requirementsPath = path.join(projectRoot, 'requirements.txt');
49
+ let pythonDeps = [];
50
+
51
+ if (fs.existsSync(requirementsPath)) {
52
+ try {
53
+ pythonDeps = fs.readFileSync(requirementsPath, 'utf-8')
54
+ .split('\n')
55
+ .map(line => line.split('==')[0].split('>=')[0].trim().toLowerCase())
56
+ .filter(Boolean);
57
+ } catch {
58
+ // Ignore
59
+ }
60
+ }
61
+
62
+ // Scan for file patterns
63
+ const srcDirs = ['src', 'app', 'lib', 'components', '.'];
64
+ const foundFiles = {};
65
+
66
+ for (const dir of srcDirs) {
67
+ const fullDir = path.join(projectRoot, dir);
68
+ if (!fs.existsSync(fullDir) || !fs.statSync(fullDir).isDirectory()) continue;
69
+
70
+ try {
71
+ const files = scanDirectory(fullDir, 3); // Scan 3 levels deep
72
+ for (const file of files) {
73
+ const ext = path.extname(file);
74
+ const basename = path.basename(file);
75
+ if (!foundFiles[ext]) foundFiles[ext] = [];
76
+ foundFiles[ext].push(basename);
77
+ }
78
+ } catch {
79
+ // Ignore scan errors
80
+ }
81
+ }
82
+
83
+ // Check each framework
84
+ for (const [framework, framePatterns] of Object.entries(patterns)) {
85
+ const reasons = [];
86
+
87
+ for (const pattern of framePatterns) {
88
+ // Check if pattern is a package name
89
+ if (pattern.startsWith('@') || !pattern.includes('*')) {
90
+ if (packageDeps[pattern]) {
91
+ reasons.push(`package: ${pattern}`);
92
+ }
93
+ if (pythonDeps.includes(pattern.toLowerCase())) {
94
+ reasons.push(`python-package: ${pattern}`);
95
+ }
96
+ }
97
+
98
+ // Check file patterns
99
+ if (pattern.includes('*')) {
100
+ const ext = path.extname(pattern);
101
+ const prefix = path.basename(pattern).replace('*', '');
102
+
103
+ if (foundFiles[ext]) {
104
+ const matches = foundFiles[ext].filter(f =>
105
+ prefix ? f.includes(prefix.replace('.', '')) : true
106
+ );
107
+ if (matches.length > 0) {
108
+ reasons.push(`files: ${matches.slice(0, 3).join(', ')}${matches.length > 3 ? '...' : ''}`);
109
+ }
110
+ }
111
+ }
112
+ }
113
+
114
+ if (reasons.length > 0) {
115
+ detected.push({
116
+ framework,
117
+ confidence: Math.min(reasons.length / 2, 1), // 0-1 scale
118
+ reasons,
119
+ docsUrl: (skillLearning.officialDocsUrls || {})[framework] || null
120
+ });
121
+ }
122
+ }
123
+
124
+ // Sort by confidence
125
+ detected.sort((a, b) => b.confidence - a.confidence);
126
+
127
+ return detected;
128
+ }
129
+
130
+ /**
131
+ * Scan directory recursively
132
+ */
133
+ function scanDirectory(dir, maxDepth, currentDepth = 0) {
134
+ if (currentDepth >= maxDepth) return [];
135
+
136
+ const files = [];
137
+
138
+ try {
139
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
140
+
141
+ for (const entry of entries) {
142
+ // Skip common non-source directories
143
+ if (entry.isDirectory()) {
144
+ if (['node_modules', '.git', 'dist', 'build', '__pycache__', '.next'].includes(entry.name)) {
145
+ continue;
146
+ }
147
+ files.push(...scanDirectory(path.join(dir, entry.name), maxDepth, currentDepth + 1));
148
+ } else if (entry.isFile()) {
149
+ files.push(path.join(dir, entry.name));
150
+ }
151
+ }
152
+ } catch {
153
+ // Ignore permission errors
154
+ }
155
+
156
+ return files;
157
+ }
158
+
159
+ /**
160
+ * Check if skill already exists
161
+ */
162
+ function skillExists(framework) {
163
+ const projectRoot = getProjectRoot();
164
+ const skillPath = path.join(projectRoot, '.claude', 'skills', framework);
165
+ return fs.existsSync(skillPath);
166
+ }
167
+
168
+ /**
169
+ * Get installed skills
170
+ */
171
+ function getInstalledSkills() {
172
+ const config = getConfig();
173
+ return config.skills?.installed || [];
174
+ }
175
+
176
+ /**
177
+ * Generate skill structure for a framework
178
+ */
179
+ function generateSkillStructure(framework, docsUrl) {
180
+ const projectRoot = getProjectRoot();
181
+ const skillPath = path.join(projectRoot, '.claude', 'skills', framework);
182
+
183
+ // Create directory structure
184
+ const dirs = [
185
+ skillPath,
186
+ path.join(skillPath, 'knowledge'),
187
+ path.join(skillPath, 'rules'),
188
+ path.join(skillPath, 'commands'),
189
+ path.join(skillPath, 'templates')
190
+ ];
191
+
192
+ for (const dir of dirs) {
193
+ if (!fs.existsSync(dir)) {
194
+ fs.mkdirSync(dir, { recursive: true });
195
+ }
196
+ }
197
+
198
+ // Generate skill.md
199
+ const skillMd = `# ${framework} Skill
200
+
201
+ ## Overview
202
+ Auto-generated skill for ${framework} framework.
203
+
204
+ ## Official Documentation
205
+ ${docsUrl || 'Not specified'}
206
+
207
+ ## File Patterns
208
+ Load this skill when working with files matching:
209
+ ${getFilePatterns(framework)}
210
+
211
+ ## Quick Reference
212
+ - See \`knowledge/patterns.md\` for common patterns
213
+ - See \`knowledge/anti-patterns.md\` for things to avoid
214
+ - See \`rules/conventions.md\` for coding conventions
215
+
216
+ ## Commands
217
+ ${generateCommandsList(framework)}
218
+
219
+ ## Templates
220
+ See \`templates/\` for code templates.
221
+ `;
222
+
223
+ fs.writeFileSync(path.join(skillPath, 'skill.md'), skillMd);
224
+
225
+ // Generate knowledge files
226
+ generateKnowledgeFiles(skillPath, framework);
227
+
228
+ // Generate rules
229
+ generateRulesFiles(skillPath, framework);
230
+
231
+ return skillPath;
232
+ }
233
+
234
+ /**
235
+ * Get file patterns for a framework
236
+ */
237
+ function getFilePatterns(framework) {
238
+ const patterns = {
239
+ nestjs: '- `*.module.ts`\n- `*.controller.ts`\n- `*.service.ts`\n- `*.entity.ts`',
240
+ react: '- `*.tsx`\n- `*.jsx`\n- `use*.ts` (hooks)',
241
+ vue: '- `*.vue`\n- `composables/*.ts`',
242
+ angular: '- `*.component.ts`\n- `*.service.ts`\n- `*.module.ts`',
243
+ fastapi: '- `main.py`\n- `routers/*.py`\n- `models/*.py`',
244
+ django: '- `views.py`\n- `models.py`\n- `urls.py`',
245
+ express: '- `routes/*.js`\n- `middleware/*.js`\n- `controllers/*.js`'
246
+ };
247
+
248
+ return patterns[framework] || '- TBD based on project analysis';
249
+ }
250
+
251
+ /**
252
+ * Generate commands list
253
+ */
254
+ function generateCommandsList(framework) {
255
+ const commands = {
256
+ nestjs: `- \`/${framework}-scaffold [name]\` - Create module with controller/service\n- \`/${framework}-entity [name]\` - Create TypeORM entity`,
257
+ react: `- \`/${framework}-component [name]\` - Create component\n- \`/${framework}-hook [name]\` - Create custom hook`,
258
+ vue: `- \`/${framework}-component [name]\` - Create Vue component\n- \`/${framework}-composable [name]\` - Create composable`,
259
+ fastapi: `- \`/${framework}-router [name]\` - Create router\n- \`/${framework}-model [name]\` - Create Pydantic model`,
260
+ default: 'No commands defined yet. Add to `commands/` directory.'
261
+ };
262
+
263
+ return commands[framework] || commands.default;
264
+ }
265
+
266
+ /**
267
+ * Generate knowledge files
268
+ */
269
+ function generateKnowledgeFiles(skillPath, framework) {
270
+ // patterns.md
271
+ const patternsContent = `# ${framework} Patterns
272
+
273
+ ## Common Patterns
274
+
275
+ ### Pattern 1: [Name]
276
+ **When to use:** [Description]
277
+ **Example:**
278
+ \`\`\`typescript
279
+ // Code example
280
+ \`\`\`
281
+
282
+ ---
283
+
284
+ *Add more patterns as you learn them. This file is automatically updated.*
285
+ `;
286
+
287
+ fs.writeFileSync(path.join(skillPath, 'knowledge', 'patterns.md'), patternsContent);
288
+
289
+ // anti-patterns.md
290
+ const antiPatternsContent = `# ${framework} Anti-Patterns
291
+
292
+ ## Things to Avoid
293
+
294
+ ### Anti-Pattern 1: [Name]
295
+ **Why it's bad:** [Explanation]
296
+ **Instead, do:** [Better approach]
297
+
298
+ ---
299
+
300
+ *Add more anti-patterns as you learn them. This file is automatically updated.*
301
+ `;
302
+
303
+ fs.writeFileSync(path.join(skillPath, 'knowledge', 'anti-patterns.md'), antiPatternsContent);
304
+
305
+ // learnings.md
306
+ const learningsContent = `# ${framework} Learnings
307
+
308
+ ## Session Learnings
309
+
310
+ *This file is automatically updated when the skill learning system detects relevant corrections or patterns.*
311
+
312
+ ---
313
+
314
+ | Date | Learning | Source |
315
+ |------|----------|--------|
316
+ `;
317
+
318
+ fs.writeFileSync(path.join(skillPath, 'knowledge', 'learnings.md'), learningsContent);
319
+ }
320
+
321
+ /**
322
+ * Generate rules files
323
+ */
324
+ function generateRulesFiles(skillPath, framework) {
325
+ const conventions = {
326
+ nestjs: `# NestJS Conventions
327
+
328
+ ## File Naming
329
+ - Modules: \`[name].module.ts\`
330
+ - Controllers: \`[name].controller.ts\`
331
+ - Services: \`[name].service.ts\`
332
+ - Entities: \`[name].entity.ts\`
333
+
334
+ ## Structure
335
+ - One module per feature/domain
336
+ - Controllers handle HTTP, services handle logic
337
+ - Use DTOs for request/response validation
338
+
339
+ ## Dependency Injection
340
+ - Always inject via constructor
341
+ - Use interfaces for loose coupling
342
+ `,
343
+ react: `# React Conventions
344
+
345
+ ## File Naming
346
+ - Components: PascalCase \`ComponentName.tsx\`
347
+ - Hooks: camelCase with \`use\` prefix \`useHookName.ts\`
348
+
349
+ ## Component Structure
350
+ - Functional components only
351
+ - Props interface above component
352
+ - Hooks at top of component
353
+
354
+ ## State Management
355
+ - Local state for component-specific data
356
+ - Context for shared state
357
+ - Avoid prop drilling > 2 levels
358
+ `,
359
+ default: `# ${framework} Conventions
360
+
361
+ ## File Naming
362
+ TBD based on project conventions.
363
+
364
+ ## Structure
365
+ TBD based on project structure.
366
+
367
+ ## Best Practices
368
+ TBD based on official documentation.
369
+ `
370
+ };
371
+
372
+ const content = conventions[framework] || conventions.default;
373
+ fs.writeFileSync(path.join(skillPath, 'rules', 'conventions.md'), content);
374
+ }
375
+
376
+ /**
377
+ * Register skill in config.json
378
+ */
379
+ function registerSkill(framework) {
380
+ const projectRoot = getProjectRoot();
381
+ const configPath = path.join(projectRoot, '.workflow', 'config.json');
382
+
383
+ const config = getConfig();
384
+
385
+ if (!config.skills) {
386
+ config.skills = { installed: [] };
387
+ }
388
+
389
+ if (!config.skills.installed.includes(framework)) {
390
+ config.skills.installed.push(framework);
391
+ }
392
+
393
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
394
+ }
395
+
396
+ /**
397
+ * Generate detection report
398
+ */
399
+ function generateDetectionReport(detected) {
400
+ const lines = [
401
+ '',
402
+ '╔════════════════════════════════════════════════════════╗',
403
+ '║ 🔍 FRAMEWORK DETECTION REPORT ║',
404
+ '╠════════════════════════════════════════════════════════╣'
405
+ ];
406
+
407
+ if (detected.length === 0) {
408
+ lines.push('║ No frameworks detected in this project.'.padEnd(57) + '║');
409
+ lines.push('╚════════════════════════════════════════════════════════╝');
410
+ return lines.join('\n');
411
+ }
412
+
413
+ const installed = getInstalledSkills();
414
+
415
+ for (const fw of detected) {
416
+ const status = installed.includes(fw.framework) ? '✅' :
417
+ skillExists(fw.framework) ? '📦' : '❌';
418
+ const confidence = Math.round(fw.confidence * 100);
419
+
420
+ lines.push(`║ ${status} ${fw.framework.padEnd(20)} Confidence: ${confidence}%`.padEnd(57) + '║');
421
+
422
+ for (const reason of fw.reasons.slice(0, 2)) {
423
+ lines.push(`║ └─ ${reason}`.padEnd(57) + '║');
424
+ }
425
+ }
426
+
427
+ lines.push('╠════════════════════════════════════════════════════════╣');
428
+ lines.push('║ Legend: ✅ installed 📦 exists ❌ not created'.padEnd(57) + '║');
429
+ lines.push('╚════════════════════════════════════════════════════════╝');
430
+
431
+ // Add suggestions
432
+ const needsCreation = detected.filter(fw =>
433
+ !installed.includes(fw.framework) && !skillExists(fw.framework)
434
+ );
435
+
436
+ if (needsCreation.length > 0) {
437
+ lines.push('');
438
+ lines.push('💡 Suggested skills to create:');
439
+ for (const fw of needsCreation) {
440
+ lines.push(` ./scripts/flow skill-create ${fw.framework}`);
441
+ }
442
+ }
443
+
444
+ return lines.join('\n');
445
+ }
446
+
447
+ /**
448
+ * Create a skill interactively
449
+ */
450
+ function createSkill(framework, options = {}) {
451
+ const { docsUrl = null, autoRegister = true } = options;
452
+
453
+ // Check if already exists
454
+ if (skillExists(framework)) {
455
+ return {
456
+ success: false,
457
+ message: `Skill '${framework}' already exists`,
458
+ path: null
459
+ };
460
+ }
461
+
462
+ // Get docs URL from config if not provided
463
+ const config = getConfig();
464
+ const finalDocsUrl = docsUrl ||
465
+ (config.skillLearning?.officialDocsUrls || {})[framework] ||
466
+ null;
467
+
468
+ // Generate skill structure
469
+ const skillPath = generateSkillStructure(framework, finalDocsUrl);
470
+
471
+ // Register in config
472
+ if (autoRegister) {
473
+ registerSkill(framework);
474
+ }
475
+
476
+ return {
477
+ success: true,
478
+ message: `Skill '${framework}' created successfully`,
479
+ path: skillPath,
480
+ docsUrl: finalDocsUrl
481
+ };
482
+ }
483
+
484
+ // ============================================================
485
+ // Exports
486
+ // ============================================================
487
+
488
+ module.exports = {
489
+ detectFrameworks,
490
+ skillExists,
491
+ getInstalledSkills,
492
+ generateSkillStructure,
493
+ registerSkill,
494
+ generateDetectionReport,
495
+ createSkill
496
+ };
497
+
498
+ // ============================================================
499
+ // CLI
500
+ // ============================================================
501
+
502
+ if (require.main === module) {
503
+ const args = process.argv.slice(2);
504
+ const command = args[0];
505
+
506
+ switch (command) {
507
+ case 'detect': {
508
+ const detected = detectFrameworks();
509
+ console.log(generateDetectionReport(detected));
510
+ break;
511
+ }
512
+
513
+ case 'create': {
514
+ const framework = args[1];
515
+ if (!framework) {
516
+ console.error('Usage: node flow-skill-creator.js create <framework>');
517
+ process.exit(1);
518
+ }
519
+
520
+ const result = createSkill(framework);
521
+ if (result.success) {
522
+ console.log(`\n✅ ${result.message}`);
523
+ console.log(` Path: ${result.path}`);
524
+ if (result.docsUrl) {
525
+ console.log(` Docs: ${result.docsUrl}`);
526
+ }
527
+ console.log('\nNext steps:');
528
+ console.log('1. Review generated files in .claude/skills/' + framework);
529
+ console.log('2. Add patterns from official documentation');
530
+ console.log('3. Add project-specific conventions');
531
+ } else {
532
+ console.error(`\n❌ ${result.message}`);
533
+ process.exit(1);
534
+ }
535
+ break;
536
+ }
537
+
538
+ case 'list': {
539
+ const installed = getInstalledSkills();
540
+ console.log('\n📚 Installed Skills\n');
541
+ if (installed.length === 0) {
542
+ console.log('No skills installed.');
543
+ } else {
544
+ installed.forEach(s => console.log(` • ${s}`));
545
+ }
546
+ break;
547
+ }
548
+
549
+ default:
550
+ console.log(`
551
+ Wogi Flow - Skill Auto-Creator
552
+
553
+ Usage:
554
+ node flow-skill-creator.js <command> [args]
555
+
556
+ Commands:
557
+ detect Scan project and detect frameworks
558
+ create <framework> Create skill for a framework
559
+ list List installed skills
560
+
561
+ Examples:
562
+ node flow-skill-creator.js detect
563
+ node flow-skill-creator.js create nestjs
564
+ node flow-skill-creator.js create react
565
+
566
+ Configuration (config.json):
567
+ skillLearning.autoDetectFrameworks: true
568
+ skillLearning.frameworkDetectionPatterns: { ... }
569
+ skillLearning.officialDocsUrls: { ... }
570
+ `);
571
+ }
572
+ }