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,458 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Wogi Flow - Capture Corrections
5
+ *
6
+ * Records corrections/learnings to ensure they are preserved and tracked.
7
+ * Supports both interactive and quick CLI modes.
8
+ *
9
+ * Usage:
10
+ * flow correct # Interactive mode
11
+ * flow correct "brief description" # Quick mode
12
+ * flow correct --task TASK-XXX "desc" # Link to task
13
+ * flow correct --skill nestjs "desc" # Link to skill
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+ const readline = require('readline');
19
+ const {
20
+ PATHS,
21
+ PROJECT_ROOT,
22
+ fileExists,
23
+ dirExists,
24
+ readFile,
25
+ writeFile,
26
+ color,
27
+ success,
28
+ warn,
29
+ error
30
+ } = require('./flow-utils');
31
+
32
+ // ============================================================
33
+ // Paths
34
+ // ============================================================
35
+
36
+ function getCorrectionsDir() {
37
+ try {
38
+ const config = JSON.parse(fs.readFileSync(PATHS.config, 'utf-8'));
39
+ const detailPath = config?.corrections?.detailPath;
40
+ if (detailPath) {
41
+ return path.isAbsolute(detailPath) ? detailPath : path.join(PROJECT_ROOT, detailPath);
42
+ }
43
+ } catch (err) {
44
+ // Fall back to default if config can't be read
45
+ }
46
+ return path.join(PROJECT_ROOT, '.workflow', 'corrections');
47
+ }
48
+
49
+ const CORRECTIONS_DIR = getCorrectionsDir();
50
+
51
+ // ============================================================
52
+ // Interactive Prompt Utilities
53
+ // ============================================================
54
+
55
+ function createInterface() {
56
+ return readline.createInterface({
57
+ input: process.stdin,
58
+ output: process.stdout
59
+ });
60
+ }
61
+
62
+ function prompt(rl, question, defaultValue = '') {
63
+ return new Promise((resolve) => {
64
+ const suffix = defaultValue ? ` (${defaultValue})` : '';
65
+ rl.question(`${question}${suffix}: `, (answer) => {
66
+ resolve(answer.trim() || defaultValue);
67
+ });
68
+ });
69
+ }
70
+
71
+ function promptMultiline(rl, question) {
72
+ return new Promise((resolve) => {
73
+ console.log(`${question} (end with empty line):`);
74
+ const lines = [];
75
+
76
+ const readLine = () => {
77
+ rl.question(' ', (line) => {
78
+ if (line === '') {
79
+ resolve(lines.join('\n'));
80
+ } else {
81
+ lines.push(line);
82
+ readLine();
83
+ }
84
+ });
85
+ };
86
+
87
+ readLine();
88
+ });
89
+ }
90
+
91
+ // ============================================================
92
+ // Core Functions
93
+ // ============================================================
94
+
95
+ /**
96
+ * Generate next correction ID
97
+ */
98
+ function getNextCorrectionId() {
99
+ if (!dirExists(CORRECTIONS_DIR)) {
100
+ fs.mkdirSync(CORRECTIONS_DIR, { recursive: true });
101
+ return 'CORR-001';
102
+ }
103
+
104
+ const files = fs.readdirSync(CORRECTIONS_DIR)
105
+ .filter(f => f.startsWith('CORR-') && f.endsWith('.md'));
106
+
107
+ if (files.length === 0) {
108
+ return 'CORR-001';
109
+ }
110
+
111
+ const numbers = files.map(f => {
112
+ const match = f.match(/CORR-(\d+)/);
113
+ return match ? parseInt(match[1], 10) : 0;
114
+ });
115
+
116
+ const maxNum = Math.max(...numbers);
117
+ return `CORR-${String(maxNum + 1).padStart(3, '0')}`;
118
+ }
119
+
120
+ /**
121
+ * Create correction file
122
+ */
123
+ function createCorrectionFile(data) {
124
+ const {
125
+ id,
126
+ brief,
127
+ whatHappened,
128
+ whatShouldHappen,
129
+ rootCause,
130
+ taskId,
131
+ skillName,
132
+ files,
133
+ tags
134
+ } = data;
135
+
136
+ const date = new Date().toISOString().split('T')[0];
137
+ const timestamp = new Date().toISOString();
138
+
139
+ const content = `# ${id} - ${brief}
140
+
141
+ **Date**: ${date}
142
+ **Timestamp**: ${timestamp}
143
+ ${taskId ? `**Task**: ${taskId}` : ''}
144
+ ${skillName ? `**Skill**: ${skillName}` : ''}
145
+ ${tags.length > 0 ? `**Tags**: ${tags.map(t => `#${t}`).join(' ')}` : ''}
146
+
147
+ ## What Happened
148
+
149
+ ${whatHappened || '_Not specified_'}
150
+
151
+ ## What Should Happen
152
+
153
+ ${whatShouldHappen || '_Not specified_'}
154
+
155
+ ## Root Cause
156
+
157
+ ${rootCause || '_Not specified_'}
158
+
159
+ ${files.length > 0 ? `## Files Affected\n\n${files.map(f => `- \`${f}\``).join('\n')}` : ''}
160
+
161
+ ## Status
162
+
163
+ - [ ] Pattern identified
164
+ - [ ] Added to knowledge base
165
+ - [ ] Promoted to instruction file (if pattern repeats)
166
+
167
+ ---
168
+
169
+ _Generated by \`flow correct\`_
170
+ `;
171
+
172
+ const filePath = path.join(CORRECTIONS_DIR, `${id}.md`);
173
+ writeFile(filePath, content);
174
+ return filePath;
175
+ }
176
+
177
+ /**
178
+ * Update feedback-patterns.md with the correction
179
+ */
180
+ function updateFeedbackPatterns(brief, taskId, skillName) {
181
+ const date = new Date().toISOString().split('T')[0];
182
+
183
+ let content = readFile(PATHS.feedbackPatterns, '');
184
+
185
+ // Check if similar correction exists (simple substring match)
186
+ const briefLower = brief.toLowerCase();
187
+ const lines = content.split('\n');
188
+ let existingIndex = -1;
189
+ let existingCount = 1;
190
+
191
+ // Look in the table for similar entries
192
+ for (let i = 0; i < lines.length; i++) {
193
+ const line = lines[i];
194
+ if (line.startsWith('|') && !line.includes('---') && !line.includes('Date')) {
195
+ const cells = line.split('|').map(c => c.trim());
196
+ if (cells[2] && cells[2].toLowerCase().includes(briefLower.slice(0, 20))) {
197
+ // Found similar entry, extract count
198
+ existingIndex = i;
199
+ const countMatch = cells[3]?.match(/(\d+)/);
200
+ existingCount = countMatch ? parseInt(countMatch[1], 10) + 1 : 2;
201
+ break;
202
+ }
203
+ }
204
+ }
205
+
206
+ if (existingIndex > 0) {
207
+ // Update existing entry count
208
+ const cells = lines[existingIndex].split('|');
209
+ cells[1] = ` ${date} `;
210
+ cells[3] = ` ${existingCount} `;
211
+ lines[existingIndex] = cells.join('|');
212
+ content = lines.join('\n');
213
+ } else {
214
+ // Add new entry after the example row
215
+ const tableIndex = content.indexOf('| _example_');
216
+ if (tableIndex > -1) {
217
+ const lineEnd = content.indexOf('\n', tableIndex);
218
+ const newRow = `\n| ${date} | "${brief.slice(0, 40)}${brief.length > 40 ? '...' : ''}" | 1 | - | Pending |`;
219
+ content = content.slice(0, lineEnd) + newRow + content.slice(lineEnd);
220
+ }
221
+ }
222
+
223
+ writeFile(PATHS.feedbackPatterns, content);
224
+ return existingCount;
225
+ }
226
+
227
+ /**
228
+ * Update skill learnings if skill is specified
229
+ */
230
+ function updateSkillLearnings(skillName, data) {
231
+ const skillDir = path.join(PROJECT_ROOT, '.claude', 'skills', skillName, 'knowledge');
232
+ const learningsPath = path.join(skillDir, 'learnings.md');
233
+
234
+ if (!dirExists(skillDir)) {
235
+ warn(`Skill directory not found: ${skillDir}`);
236
+ return false;
237
+ }
238
+
239
+ const date = new Date().toISOString().split('T')[0];
240
+
241
+ let content = readFile(learningsPath, '# Learnings\n\n');
242
+
243
+ const entry = `
244
+ ### ${date} - ${data.brief}
245
+
246
+ **Context**: ${data.whatHappened || 'Correction captured via CLI'}
247
+ **Trigger**: manual
248
+ **Issue**: ${data.rootCause || 'See correction file'}
249
+ **Learning**: ${data.whatShouldHappen || 'See correction file'}
250
+ **Files**: ${data.files.join(', ') || 'N/A'}
251
+ `;
252
+
253
+ // Append after the header
254
+ if (content.includes('# Learnings')) {
255
+ content = content.replace('# Learnings', `# Learnings\n${entry}`);
256
+ } else {
257
+ content += entry;
258
+ }
259
+
260
+ writeFile(learningsPath, content);
261
+ return true;
262
+ }
263
+
264
+ // ============================================================
265
+ // Interactive Mode
266
+ // ============================================================
267
+
268
+ async function runInteractive() {
269
+ const rl = createInterface();
270
+
271
+ console.log(color('cyan', '═══════════════════════════════════════════'));
272
+ console.log(color('cyan', ' Capture Correction'));
273
+ console.log(color('cyan', '═══════════════════════════════════════════'));
274
+ console.log('');
275
+
276
+ try {
277
+ const brief = await prompt(rl, 'Brief description');
278
+ if (!brief) {
279
+ error('Brief description is required');
280
+ rl.close();
281
+ process.exit(1);
282
+ }
283
+
284
+ const whatHappened = await promptMultiline(rl, 'What happened (the mistake)');
285
+ const whatShouldHappen = await promptMultiline(rl, 'What should happen instead');
286
+ const rootCause = await prompt(rl, 'Root cause (optional)');
287
+ const taskId = await prompt(rl, 'Related task ID (optional)');
288
+ const skillName = await prompt(rl, 'Related skill name (optional)');
289
+ const filesStr = await prompt(rl, 'Affected files (comma-separated, optional)');
290
+ const tagsStr = await prompt(rl, 'Tags (comma-separated, optional)');
291
+
292
+ const files = filesStr ? filesStr.split(',').map(f => f.trim()) : [];
293
+ const tags = tagsStr ? tagsStr.split(',').map(t => t.trim()) : [];
294
+
295
+ rl.close();
296
+
297
+ // Create correction
298
+ const id = getNextCorrectionId();
299
+ const data = {
300
+ id,
301
+ brief,
302
+ whatHappened,
303
+ whatShouldHappen,
304
+ rootCause,
305
+ taskId,
306
+ skillName,
307
+ files,
308
+ tags
309
+ };
310
+
311
+ const filePath = createCorrectionFile(data);
312
+ const count = updateFeedbackPatterns(brief, taskId, skillName);
313
+
314
+ if (skillName) {
315
+ updateSkillLearnings(skillName, data);
316
+ }
317
+
318
+ console.log('');
319
+ success(`Correction saved: ${id}`);
320
+ console.log(` File: ${filePath}`);
321
+ console.log(` Pattern count: ${count}`);
322
+
323
+ if (count >= 3) {
324
+ console.log('');
325
+ warn('This pattern has occurred 3+ times!');
326
+ console.log(' Consider promoting to an instruction file:');
327
+ console.log(' - decisions.md (project rules)');
328
+ console.log(' - agents/*.md (process changes)');
329
+ console.log(' - CLAUDE.md (core workflow)');
330
+ }
331
+
332
+ } catch (err) {
333
+ rl.close();
334
+ error(`Failed: ${err.message}`);
335
+ process.exit(1);
336
+ }
337
+ }
338
+
339
+ // ============================================================
340
+ // Quick Mode
341
+ // ============================================================
342
+
343
+ function runQuick(brief, options) {
344
+ const { taskId, skillName } = options;
345
+
346
+ const id = getNextCorrectionId();
347
+ const data = {
348
+ id,
349
+ brief,
350
+ whatHappened: '',
351
+ whatShouldHappen: '',
352
+ rootCause: '',
353
+ taskId: taskId || '',
354
+ skillName: skillName || '',
355
+ files: [],
356
+ tags: []
357
+ };
358
+
359
+ const filePath = createCorrectionFile(data);
360
+ const count = updateFeedbackPatterns(brief, taskId, skillName);
361
+
362
+ if (skillName) {
363
+ updateSkillLearnings(skillName, data);
364
+ }
365
+
366
+ success(`Correction saved: ${id}`);
367
+ console.log(` File: ${filePath}`);
368
+ console.log(` Pattern count: ${count}`);
369
+
370
+ if (count >= 3) {
371
+ console.log('');
372
+ warn('This pattern has occurred 3+ times - consider promoting to instruction file');
373
+ }
374
+ }
375
+
376
+ // ============================================================
377
+ // List Mode
378
+ // ============================================================
379
+
380
+ function listCorrections() {
381
+ if (!dirExists(CORRECTIONS_DIR)) {
382
+ console.log('No corrections recorded yet.');
383
+ return;
384
+ }
385
+
386
+ const files = fs.readdirSync(CORRECTIONS_DIR)
387
+ .filter(f => f.startsWith('CORR-') && f.endsWith('.md'))
388
+ .sort()
389
+ .reverse();
390
+
391
+ if (files.length === 0) {
392
+ console.log('No corrections recorded yet.');
393
+ return;
394
+ }
395
+
396
+ console.log(color('cyan', 'Recent Corrections'));
397
+ console.log('');
398
+
399
+ for (const file of files.slice(0, 10)) {
400
+ const content = readFile(path.join(CORRECTIONS_DIR, file), '');
401
+ const titleMatch = content.match(/^# (CORR-\d+) - (.+)$/m);
402
+ const dateMatch = content.match(/\*\*Date\*\*: (.+)$/m);
403
+
404
+ const id = titleMatch ? titleMatch[1] : file.replace('.md', '');
405
+ const title = titleMatch ? titleMatch[2] : 'Unknown';
406
+ const date = dateMatch ? dateMatch[1] : 'Unknown';
407
+
408
+ console.log(` ${color('yellow', id)} | ${date} | ${title.slice(0, 50)}`);
409
+ }
410
+
411
+ if (files.length > 10) {
412
+ console.log('');
413
+ console.log(` ... and ${files.length - 10} more`);
414
+ }
415
+ }
416
+
417
+ // ============================================================
418
+ // Main
419
+ // ============================================================
420
+
421
+ function main() {
422
+ const args = process.argv.slice(2);
423
+
424
+ // Parse options
425
+ let taskId = '';
426
+ let skillName = '';
427
+ let brief = '';
428
+ let listMode = false;
429
+
430
+ for (let i = 0; i < args.length; i++) {
431
+ if (args[i] === '--task' && args[i + 1]) {
432
+ taskId = args[i + 1];
433
+ i++;
434
+ } else if (args[i] === '--skill' && args[i + 1]) {
435
+ skillName = args[i + 1];
436
+ i++;
437
+ } else if (args[i] === 'list' || args[i] === '--list') {
438
+ listMode = true;
439
+ } else if (!args[i].startsWith('-')) {
440
+ brief = args[i];
441
+ }
442
+ }
443
+
444
+ if (listMode) {
445
+ listCorrections();
446
+ return;
447
+ }
448
+
449
+ if (brief) {
450
+ // Quick mode
451
+ runQuick(brief, { taskId, skillName });
452
+ } else {
453
+ // Interactive mode
454
+ runInteractive();
455
+ }
456
+ }
457
+
458
+ main();