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,218 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Wogi Flow - Coverage Check Step
5
+ *
6
+ * Checks test coverage meets threshold.
7
+ * Supports Jest, Vitest, NYC/Istanbul coverage formats.
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const { execSync } = require('child_process');
13
+ const { getProjectRoot, colors, getConfig } = require('./flow-utils');
14
+
15
+ const PROJECT_ROOT = getProjectRoot();
16
+
17
+ // Common coverage output locations
18
+ const COVERAGE_PATHS = [
19
+ 'coverage/coverage-summary.json', // Jest/Vitest JSON summary
20
+ 'coverage/coverage-final.json', // Istanbul/NYC
21
+ 'coverage/lcov-report/index.html', // LCOV HTML
22
+ '.nyc_output/coverage.json', // NYC output
23
+ ];
24
+
25
+ /**
26
+ * Run coverage check step
27
+ *
28
+ * @param {object} options
29
+ * @param {string[]} options.files - Files modified
30
+ * @param {object} options.stepConfig - Step configuration
31
+ * @param {string} options.mode - Step mode (block/warn/prompt/auto)
32
+ * @returns {object} - { passed: boolean, message: string, coverage?: object }
33
+ */
34
+ async function run(options = {}) {
35
+ const { files = [], stepConfig = {}, mode } = options;
36
+ const minCoverage = stepConfig.minCoverage || 80;
37
+ const checkFiles = stepConfig.checkModifiedOnly ?? true;
38
+
39
+ // Try to find existing coverage data
40
+ let coverage = findExistingCoverage();
41
+
42
+ // If no coverage found, try to run tests with coverage
43
+ if (!coverage && stepConfig.runTests !== false) {
44
+ coverage = await runCoverageTests();
45
+ }
46
+
47
+ if (!coverage) {
48
+ return {
49
+ passed: true,
50
+ message: 'No coverage data available',
51
+ suggestion: 'Run tests with coverage: npm test -- --coverage',
52
+ };
53
+ }
54
+
55
+ // Check overall coverage
56
+ const overall = coverage.total || coverage;
57
+ const metrics = ['lines', 'statements', 'branches', 'functions'];
58
+
59
+ const results = {};
60
+ let allPassing = true;
61
+
62
+ for (const metric of metrics) {
63
+ if (overall[metric]) {
64
+ const pct = overall[metric].pct ?? overall[metric].percent ?? overall[metric];
65
+ if (typeof pct === 'number') {
66
+ results[metric] = pct;
67
+ if (pct < minCoverage) {
68
+ allPassing = false;
69
+ }
70
+ }
71
+ }
72
+ }
73
+
74
+ // Check coverage for modified files specifically
75
+ let modifiedFileCoverage = null;
76
+ if (checkFiles && files.length > 0 && coverage.files) {
77
+ modifiedFileCoverage = checkModifiedFilesCoverage(files, coverage.files, minCoverage);
78
+ }
79
+
80
+ // Report results
81
+ if (Object.keys(results).length > 0) {
82
+ console.log(colors.yellow + `\n Coverage (threshold: ${minCoverage}%):` + colors.reset);
83
+ for (const [metric, pct] of Object.entries(results)) {
84
+ const color = pct >= minCoverage ? colors.green : colors.red;
85
+ const icon = pct >= minCoverage ? '✓' : '✗';
86
+ console.log(` ${color}${icon}${colors.reset} ${metric}: ${pct.toFixed(1)}%`);
87
+ }
88
+ }
89
+
90
+ if (modifiedFileCoverage && modifiedFileCoverage.uncovered.length > 0) {
91
+ console.log(colors.yellow + '\n Modified files with low coverage:' + colors.reset);
92
+ for (const file of modifiedFileCoverage.uncovered) {
93
+ console.log(colors.red + ` ✗ ${file.name}: ${file.coverage.toFixed(1)}%` + colors.reset);
94
+ }
95
+ }
96
+
97
+ if (!allPassing) {
98
+ return {
99
+ passed: false,
100
+ message: `Coverage below ${minCoverage}% threshold`,
101
+ coverage: results,
102
+ modifiedFileCoverage,
103
+ };
104
+ }
105
+
106
+ return {
107
+ passed: true,
108
+ message: `Coverage meets ${minCoverage}% threshold`,
109
+ coverage: results,
110
+ };
111
+ }
112
+
113
+ /**
114
+ * Find existing coverage data
115
+ */
116
+ function findExistingCoverage() {
117
+ for (const coveragePath of COVERAGE_PATHS) {
118
+ const fullPath = path.join(PROJECT_ROOT, coveragePath);
119
+ if (fs.existsSync(fullPath)) {
120
+ try {
121
+ if (coveragePath.endsWith('.json')) {
122
+ return JSON.parse(fs.readFileSync(fullPath, 'utf8'));
123
+ }
124
+ // For HTML reports, try to find accompanying JSON
125
+ const jsonPath = fullPath.replace('.html', '.json');
126
+ if (fs.existsSync(jsonPath)) {
127
+ return JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
128
+ }
129
+ } catch (err) {
130
+ // Continue to next path
131
+ }
132
+ }
133
+ }
134
+ return null;
135
+ }
136
+
137
+ /**
138
+ * Run tests with coverage
139
+ */
140
+ async function runCoverageTests() {
141
+ // Check package.json for test script
142
+ const packagePath = path.join(PROJECT_ROOT, 'package.json');
143
+ if (!fs.existsSync(packagePath)) return null;
144
+
145
+ try {
146
+ const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
147
+ const scripts = pkg.scripts || {};
148
+
149
+ // Try to find coverage command
150
+ let coverageCmd = null;
151
+
152
+ if (scripts['test:coverage']) {
153
+ coverageCmd = 'npm run test:coverage';
154
+ } else if (scripts.coverage) {
155
+ coverageCmd = 'npm run coverage';
156
+ } else if (scripts.test) {
157
+ // Try to add --coverage flag
158
+ if (scripts.test.includes('jest') || scripts.test.includes('vitest')) {
159
+ coverageCmd = 'npm test -- --coverage --json --outputFile=coverage/coverage-summary.json';
160
+ }
161
+ }
162
+
163
+ if (!coverageCmd) return null;
164
+
165
+ // Run coverage
166
+ execSync(coverageCmd, {
167
+ cwd: PROJECT_ROOT,
168
+ stdio: ['pipe', 'pipe', 'pipe'],
169
+ timeout: 300000, // 5 minute timeout
170
+ });
171
+
172
+ // Try to read the output
173
+ return findExistingCoverage();
174
+
175
+ } catch (err) {
176
+ // Test run failed or timed out
177
+ return null;
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Check coverage for specific modified files
183
+ */
184
+ function checkModifiedFilesCoverage(files, coverageFiles, threshold) {
185
+ const covered = [];
186
+ const uncovered = [];
187
+
188
+ for (const file of files) {
189
+ // Skip test files
190
+ if (file.includes('.test.') || file.includes('.spec.')) continue;
191
+
192
+ // Skip non-code files
193
+ if (!file.match(/\.(js|ts|jsx|tsx)$/)) continue;
194
+
195
+ // Find in coverage data
196
+ const coverageKey = Object.keys(coverageFiles).find(k =>
197
+ k.endsWith(file) || k.includes(file)
198
+ );
199
+
200
+ if (coverageKey) {
201
+ const fileCov = coverageFiles[coverageKey];
202
+ const pct = fileCov.lines?.pct ?? fileCov.statements?.pct ?? 0;
203
+
204
+ if (pct >= threshold) {
205
+ covered.push({ name: file, coverage: pct });
206
+ } else {
207
+ uncovered.push({ name: file, coverage: pct });
208
+ }
209
+ } else {
210
+ // File not in coverage - might be new or not tested
211
+ uncovered.push({ name: file, coverage: 0, notFound: true });
212
+ }
213
+ }
214
+
215
+ return { covered, uncovered };
216
+ }
217
+
218
+ module.exports = { run, findExistingCoverage };
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Wogi Flow - Update Knowledge Base Step
5
+ *
6
+ * Prompts to document learnings in the knowledge base.
7
+ * Helps capture institutional knowledge automatically.
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const { getProjectRoot, colors, getConfig } = require('./flow-utils');
13
+
14
+ const PROJECT_ROOT = getProjectRoot();
15
+ const KNOWLEDGE_DIR = path.join(PROJECT_ROOT, '.claude', 'docs', 'knowledge-base');
16
+
17
+ /**
18
+ * Run update knowledge base step
19
+ *
20
+ * @param {object} options
21
+ * @param {string} options.taskId - Current task ID
22
+ * @param {string} options.taskTitle - Task title/description
23
+ * @param {string[]} options.files - Files modified
24
+ * @param {object} options.stepConfig - Step configuration
25
+ * @param {string} options.mode - Step mode (block/warn/prompt/auto)
26
+ * @param {object} options.learnings - Any learnings discovered during task
27
+ * @returns {object} - { passed: boolean, message: string, suggestion?: string }
28
+ */
29
+ async function run(options = {}) {
30
+ const { taskId, taskTitle, files = [], mode, stepConfig = {}, learnings } = options;
31
+
32
+ // Ensure knowledge base directory exists
33
+ if (!fs.existsSync(KNOWLEDGE_DIR)) {
34
+ fs.mkdirSync(KNOWLEDGE_DIR, { recursive: true });
35
+ }
36
+
37
+ // Detect potential learnings based on task
38
+ const detectedLearnings = detectLearnings(files, taskTitle);
39
+
40
+ if (detectedLearnings.length === 0 && !learnings) {
41
+ return { passed: true, message: 'No learnings detected to document' };
42
+ }
43
+
44
+ // In prompt mode, suggest documentation
45
+ if (mode === 'prompt') {
46
+ console.log(colors.yellow + '\n Potential learnings to document:' + colors.reset);
47
+
48
+ if (learnings) {
49
+ console.log(` - ${learnings}`);
50
+ }
51
+
52
+ detectedLearnings.forEach(l => {
53
+ console.log(` - ${l.type}: ${l.description}`);
54
+ });
55
+
56
+ console.log(colors.cyan + '\n Knowledge base location: .claude/docs/knowledge-base/' + colors.reset);
57
+
58
+ // Suggest where to document
59
+ const suggestion = suggestKnowledgeFile(detectedLearnings, taskTitle);
60
+ if (suggestion) {
61
+ console.log(colors.cyan + ` Suggested file: ${suggestion}` + colors.reset);
62
+ }
63
+
64
+ return {
65
+ passed: true,
66
+ message: 'Documentation prompt shown',
67
+ suggestion: `Document learnings in ${suggestion || 'knowledge-base'}`,
68
+ detectedLearnings,
69
+ };
70
+ }
71
+
72
+ // In auto mode, we could auto-create entries (future enhancement)
73
+ return {
74
+ passed: true,
75
+ message: `${detectedLearnings.length} potential learning(s) detected`,
76
+ suggestion: 'Consider documenting these patterns',
77
+ detectedLearnings,
78
+ };
79
+ }
80
+
81
+ /**
82
+ * Detect potential learnings based on files and task
83
+ */
84
+ function detectLearnings(files, taskTitle) {
85
+ const learnings = [];
86
+
87
+ // Check for new patterns
88
+ const hasNewComponent = files.some(f =>
89
+ f.includes('/components/') && !f.includes('.test.') && !f.includes('.spec.')
90
+ );
91
+ if (hasNewComponent) {
92
+ learnings.push({
93
+ type: 'component',
94
+ description: 'New component created - document usage patterns',
95
+ category: 'components',
96
+ });
97
+ }
98
+
99
+ // Check for new hooks
100
+ const hasNewHook = files.some(f =>
101
+ f.includes('/hooks/') || (f.includes('use') && f.endsWith('.ts'))
102
+ );
103
+ if (hasNewHook) {
104
+ learnings.push({
105
+ type: 'hook',
106
+ description: 'Custom hook created - document API and usage',
107
+ category: 'hooks',
108
+ });
109
+ }
110
+
111
+ // Check for API endpoints
112
+ const hasApiChange = files.some(f =>
113
+ f.includes('/api/') || f.includes('.controller.') || f.includes('.routes.')
114
+ );
115
+ if (hasApiChange) {
116
+ learnings.push({
117
+ type: 'api',
118
+ description: 'API endpoint modified - document request/response format',
119
+ category: 'api',
120
+ });
121
+ }
122
+
123
+ // Check for configuration changes
124
+ const hasConfigChange = files.some(f =>
125
+ f.includes('config') || f.endsWith('.env.example') || f.includes('settings')
126
+ );
127
+ if (hasConfigChange) {
128
+ learnings.push({
129
+ type: 'configuration',
130
+ description: 'Configuration changed - document options',
131
+ category: 'configuration',
132
+ });
133
+ }
134
+
135
+ // Check for database/model changes
136
+ const hasModelChange = files.some(f =>
137
+ f.includes('/models/') || f.includes('/entities/') || f.includes('.schema.')
138
+ );
139
+ if (hasModelChange) {
140
+ learnings.push({
141
+ type: 'data-model',
142
+ description: 'Data model changed - document schema',
143
+ category: 'data-models',
144
+ });
145
+ }
146
+
147
+ // Check task title for patterns
148
+ const titleLower = (taskTitle || '').toLowerCase();
149
+ if (titleLower.includes('fix') || titleLower.includes('bug')) {
150
+ learnings.push({
151
+ type: 'bugfix',
152
+ description: 'Bug fixed - document root cause and solution',
153
+ category: 'troubleshooting',
154
+ });
155
+ }
156
+
157
+ if (titleLower.includes('performance') || titleLower.includes('optim')) {
158
+ learnings.push({
159
+ type: 'performance',
160
+ description: 'Performance improvement - document technique',
161
+ category: 'performance',
162
+ });
163
+ }
164
+
165
+ return learnings;
166
+ }
167
+
168
+ /**
169
+ * Suggest knowledge base file based on learnings
170
+ */
171
+ function suggestKnowledgeFile(learnings, taskTitle) {
172
+ if (learnings.length === 0) return null;
173
+
174
+ const primary = learnings[0];
175
+ const category = primary.category || 'general';
176
+
177
+ // Check if category file exists
178
+ const categoryFile = path.join(KNOWLEDGE_DIR, `${category}.md`);
179
+ if (fs.existsSync(categoryFile)) {
180
+ return `knowledge-base/${category}.md`;
181
+ }
182
+
183
+ // Check subdirectories
184
+ const categoryDir = path.join(KNOWLEDGE_DIR, category);
185
+ if (fs.existsSync(categoryDir)) {
186
+ return `knowledge-base/${category}/`;
187
+ }
188
+
189
+ // Suggest new file
190
+ return `knowledge-base/${category}.md (new)`;
191
+ }
192
+
193
+ module.exports = { run, detectLearnings };