@iservu-inc/adf-cli 0.3.0 → 0.4.12
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/.project/chats/{current → complete}/2025-10-03_AGENTS-MD-AND-TOOL-GENERATORS.md +82 -17
- package/.project/chats/complete/2025-10-03_AI-PROVIDER-INTEGRATION.md +568 -0
- package/.project/chats/complete/2025-10-03_FRAMEWORK-UPDATE-SYSTEM.md +497 -0
- package/.project/chats/complete/2025-10-04_CONFIG-COMMAND.md +503 -0
- package/.project/chats/current/2025-10-04_PHASE-4-1-SMART-FILTERING.md +381 -0
- package/.project/chats/current/SESSION-STATUS.md +168 -0
- package/.project/docs/AI-PROVIDER-INTEGRATION.md +600 -0
- package/.project/docs/FRAMEWORK-UPDATE-INTEGRATION.md +421 -0
- package/.project/docs/FRAMEWORK-UPDATE-SYSTEM.md +832 -0
- package/.project/docs/PHASE-4-2-LEARNING-SYSTEM.md +881 -0
- package/.project/docs/PROJECT-STRUCTURE-EXPLANATION.md +500 -0
- package/.project/docs/SMART-FILTERING-SYSTEM.md +385 -0
- package/.project/docs/architecture/SYSTEM-DESIGN.md +122 -1
- package/.project/docs/goals/PROJECT-VISION.md +61 -34
- package/CHANGELOG.md +257 -1
- package/README.md +476 -292
- package/bin/adf.js +7 -0
- package/lib/ai/ai-client.js +328 -0
- package/lib/ai/ai-config.js +398 -0
- package/lib/analyzers/project-analyzer.js +380 -0
- package/lib/commands/config.js +221 -0
- package/lib/commands/init.js +56 -10
- package/lib/filters/question-filter.js +480 -0
- package/lib/frameworks/interviewer.js +271 -12
- package/lib/frameworks/progress-tracker.js +8 -1
- package/lib/learning/learning-manager.js +447 -0
- package/lib/learning/pattern-detector.js +376 -0
- package/lib/learning/rule-generator.js +304 -0
- package/lib/learning/skip-tracker.js +260 -0
- package/lib/learning/storage.js +296 -0
- package/package.json +70 -57
- package/tests/learning-storage.test.js +184 -0
- package/tests/pattern-detector.test.js +297 -0
- package/tests/project-analyzer.test.js +221 -0
- package/tests/question-filter.test.js +297 -0
- package/tests/skip-tracker.test.js +198 -0
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
const inquirer = require('inquirer');
|
|
2
|
+
const chalk = require('chalk');
|
|
3
|
+
const storage = require('./storage');
|
|
4
|
+
const { analyzeSkipPatterns } = require('./skip-tracker');
|
|
5
|
+
const { detectPatterns, getPatternSummary } = require('./pattern-detector');
|
|
6
|
+
const { getActiveRules, toggleRule, removeRule } = require('./rule-generator');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Learning Manager - CLI interface for managing learning data
|
|
10
|
+
*
|
|
11
|
+
* Provides:
|
|
12
|
+
* - View skip history
|
|
13
|
+
* - Review detected patterns
|
|
14
|
+
* - Enable/disable learning
|
|
15
|
+
* - Clear learning data
|
|
16
|
+
* - Export learning data
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
class LearningManager {
|
|
20
|
+
constructor(projectPath) {
|
|
21
|
+
this.projectPath = projectPath;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Show main learning management menu
|
|
26
|
+
*/
|
|
27
|
+
async showMenu() {
|
|
28
|
+
// Load stats
|
|
29
|
+
const stats = await storage.getLearningStats(this.projectPath);
|
|
30
|
+
const config = await storage.getLearningConfig(this.projectPath);
|
|
31
|
+
const patterns = await detectPatterns(this.projectPath);
|
|
32
|
+
const patternSummary = getPatternSummary(patterns);
|
|
33
|
+
const dataSize = await storage.getLearningDataSize(this.projectPath);
|
|
34
|
+
|
|
35
|
+
console.log(chalk.cyan.bold('\n┌─────────────────────────────────────────────────────┐'));
|
|
36
|
+
console.log(chalk.cyan.bold('│ Learning System Configuration │'));
|
|
37
|
+
console.log(chalk.cyan.bold('├─────────────────────────────────────────────────────┤'));
|
|
38
|
+
console.log(chalk.cyan('│'));
|
|
39
|
+
console.log(chalk.cyan(`│ 📊 Learning Statistics`));
|
|
40
|
+
console.log(chalk.cyan(`│ Sessions analyzed: ${stats.totalSessions}`));
|
|
41
|
+
console.log(chalk.cyan(`│ Questions tracked: ${stats.totalAnswers + stats.totalSkips}`));
|
|
42
|
+
console.log(chalk.cyan(`│ Patterns detected: ${patternSummary.total}`));
|
|
43
|
+
console.log(chalk.cyan(`│ Storage used: ${(dataSize / 1024).toFixed(1)} KB`));
|
|
44
|
+
console.log(chalk.cyan('│'));
|
|
45
|
+
|
|
46
|
+
if (patternSummary.total > 0) {
|
|
47
|
+
console.log(chalk.cyan(`│ 🎯 Detected Patterns`));
|
|
48
|
+
|
|
49
|
+
const allPatterns = [
|
|
50
|
+
...patterns.consistentSkips.slice(0, 2),
|
|
51
|
+
...patterns.categoryPatterns.slice(0, 1)
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
for (const pattern of allPatterns.slice(0, 3)) {
|
|
55
|
+
const icon = pattern.confidence >= 80 ? '🔴' : pattern.confidence >= 60 ? '🟡' : '🟢';
|
|
56
|
+
if (pattern.type === 'consistent_skip') {
|
|
57
|
+
console.log(chalk.cyan(`│ ${icon} Skip "${pattern.questionText?.substring(0, 35)}..." (${pattern.confidence}%)`));
|
|
58
|
+
} else if (pattern.type === 'category_skip') {
|
|
59
|
+
console.log(chalk.cyan(`│ ${icon} Skip ${pattern.category} questions (${pattern.confidence}%)`));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (patternSummary.total > 3) {
|
|
64
|
+
console.log(chalk.cyan(`│ ... and ${patternSummary.total - 3} more`));
|
|
65
|
+
}
|
|
66
|
+
console.log(chalk.cyan('│'));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
console.log(chalk.cyan(`│ ⚙️ Options`));
|
|
70
|
+
console.log(chalk.cyan(`│ 1. View Skip History`));
|
|
71
|
+
console.log(chalk.cyan(`│ 2. Review Detected Patterns`));
|
|
72
|
+
console.log(chalk.cyan(`│ 3. Manage Learned Rules`));
|
|
73
|
+
console.log(chalk.cyan(`│ 4. Learning Settings ${config.enabled ? chalk.green('(✓ Enabled)') : chalk.yellow('(○ Disabled)')}`));
|
|
74
|
+
console.log(chalk.cyan(`│ 5. Clear Learning Data`));
|
|
75
|
+
console.log(chalk.cyan(`│ 6. Back to Main Menu`));
|
|
76
|
+
console.log(chalk.cyan('│'));
|
|
77
|
+
console.log(chalk.cyan.bold('└─────────────────────────────────────────────────────┘\n'));
|
|
78
|
+
|
|
79
|
+
const { choice } = await inquirer.prompt([
|
|
80
|
+
{
|
|
81
|
+
type: 'list',
|
|
82
|
+
name: 'choice',
|
|
83
|
+
message: 'Select an option:',
|
|
84
|
+
choices: [
|
|
85
|
+
{ name: '1. View Skip History', value: 'history' },
|
|
86
|
+
{ name: '2. Review Detected Patterns', value: 'patterns' },
|
|
87
|
+
{ name: '3. Manage Learned Rules', value: 'rules' },
|
|
88
|
+
{ name: '4. Learning Settings', value: 'settings' },
|
|
89
|
+
{ name: '5. Clear Learning Data', value: 'clear' },
|
|
90
|
+
{ name: '6. Back to Main Menu', value: 'back' }
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
]);
|
|
94
|
+
|
|
95
|
+
switch (choice) {
|
|
96
|
+
case 'history':
|
|
97
|
+
await this.viewSkipHistory();
|
|
98
|
+
break;
|
|
99
|
+
case 'patterns':
|
|
100
|
+
await this.reviewPatterns();
|
|
101
|
+
break;
|
|
102
|
+
case 'rules':
|
|
103
|
+
await this.manageRules();
|
|
104
|
+
break;
|
|
105
|
+
case 'settings':
|
|
106
|
+
await this.manageSettings();
|
|
107
|
+
break;
|
|
108
|
+
case 'clear':
|
|
109
|
+
await this.clearLearningData();
|
|
110
|
+
break;
|
|
111
|
+
case 'back':
|
|
112
|
+
return 'back';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return 'continue';
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* View skip history
|
|
120
|
+
*/
|
|
121
|
+
async viewSkipHistory() {
|
|
122
|
+
const analysis = await analyzeSkipPatterns(this.projectPath);
|
|
123
|
+
|
|
124
|
+
console.log(chalk.cyan.bold('\n📋 Skip History\n'));
|
|
125
|
+
|
|
126
|
+
if (analysis.totalSessions === 0) {
|
|
127
|
+
console.log(chalk.yellow('No skip history available yet.\n'));
|
|
128
|
+
console.log(chalk.gray('Skip history will be tracked as you complete interviews.\n'));
|
|
129
|
+
await this.pressEnterToContinue();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
console.log(chalk.gray(`Total Sessions: ${analysis.totalSessions}`));
|
|
134
|
+
console.log(chalk.gray(`Total Skips: ${analysis.totalSkips} (${analysis.manualSkips} manual, ${analysis.filteredSkips} filtered)\n`));
|
|
135
|
+
|
|
136
|
+
if (analysis.mostSkippedQuestions.length > 0) {
|
|
137
|
+
console.log(chalk.cyan('Most Skipped Questions:\n'));
|
|
138
|
+
for (const q of analysis.mostSkippedQuestions.slice(0, 10)) {
|
|
139
|
+
const percentage = Math.round((q.count / analysis.totalSessions) * 100);
|
|
140
|
+
console.log(chalk.white(` ${q.count}x (${percentage}%) - ${q.text.substring(0, 60)}${q.text.length > 60 ? '...' : ''}`));
|
|
141
|
+
if (q.category) {
|
|
142
|
+
console.log(chalk.gray(` Category: ${q.category}`));
|
|
143
|
+
}
|
|
144
|
+
console.log('');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (analysis.mostSkippedCategories.length > 0) {
|
|
149
|
+
console.log(chalk.cyan('Most Skipped Categories:\n'));
|
|
150
|
+
for (const cat of analysis.mostSkippedCategories) {
|
|
151
|
+
console.log(chalk.white(` ${cat.category}: ${cat.count} skips`));
|
|
152
|
+
}
|
|
153
|
+
console.log('');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
await this.pressEnterToContinue();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Review detected patterns
|
|
161
|
+
*/
|
|
162
|
+
async reviewPatterns() {
|
|
163
|
+
const patterns = await detectPatterns(this.projectPath);
|
|
164
|
+
const patternSummary = getPatternSummary(patterns);
|
|
165
|
+
|
|
166
|
+
console.log(chalk.cyan.bold('\n🔍 Detected Patterns\n'));
|
|
167
|
+
|
|
168
|
+
if (patternSummary.total === 0) {
|
|
169
|
+
console.log(chalk.yellow('No patterns detected yet.\n'));
|
|
170
|
+
console.log(chalk.gray('Patterns will be detected after 3+ interview sessions.\n'));
|
|
171
|
+
await this.pressEnterToContinue();
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
console.log(chalk.gray(`Total Patterns: ${patternSummary.total}`));
|
|
176
|
+
console.log(chalk.gray(`High Confidence (≥80%): ${patternSummary.highConfidence}`));
|
|
177
|
+
console.log(chalk.gray(`Medium Confidence (60-79%): ${patternSummary.mediumConfidence}`));
|
|
178
|
+
console.log(chalk.gray(`Low Confidence (<60%): ${patternSummary.lowConfidence}\n`));
|
|
179
|
+
|
|
180
|
+
// Show high confidence patterns
|
|
181
|
+
if (patternSummary.highConfidence > 0) {
|
|
182
|
+
console.log(chalk.red.bold('🔴 High Confidence (>80%)\n'));
|
|
183
|
+
|
|
184
|
+
const highPatterns = [
|
|
185
|
+
...patterns.consistentSkips.filter(p => p.confidence >= 80),
|
|
186
|
+
...patterns.categoryPatterns.filter(p => p.confidence >= 80)
|
|
187
|
+
];
|
|
188
|
+
|
|
189
|
+
for (const pattern of highPatterns.slice(0, 5)) {
|
|
190
|
+
if (pattern.type === 'consistent_skip') {
|
|
191
|
+
console.log(chalk.white(` • Skip question: "${pattern.questionText}"`));
|
|
192
|
+
console.log(chalk.gray(` Confidence: ${pattern.confidence}% (${pattern.skipCount} of ${pattern.sessionsAnalyzed} sessions)`));
|
|
193
|
+
console.log(chalk.green(` ✓ Recommendation: ${pattern.recommendation}`));
|
|
194
|
+
} else if (pattern.type === 'category_skip') {
|
|
195
|
+
console.log(chalk.white(` • Skip ${pattern.category} questions`));
|
|
196
|
+
console.log(chalk.gray(` Confidence: ${pattern.confidence}% (${pattern.skipCount} of ${pattern.totalQuestions} questions)`));
|
|
197
|
+
console.log(chalk.green(` ✓ Recommendation: ${pattern.recommendation}`));
|
|
198
|
+
}
|
|
199
|
+
console.log('');
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Show medium confidence patterns
|
|
204
|
+
if (patternSummary.mediumConfidence > 0) {
|
|
205
|
+
console.log(chalk.yellow.bold('🟡 Medium Confidence (60-80%)\n'));
|
|
206
|
+
|
|
207
|
+
const mediumPatterns = [
|
|
208
|
+
...patterns.consistentSkips.filter(p => p.confidence >= 60 && p.confidence < 80),
|
|
209
|
+
...patterns.categoryPatterns.filter(p => p.confidence >= 60 && p.confidence < 80),
|
|
210
|
+
...patterns.userPreferences
|
|
211
|
+
];
|
|
212
|
+
|
|
213
|
+
for (const pattern of mediumPatterns.slice(0, 3)) {
|
|
214
|
+
if (pattern.type === 'user_preference') {
|
|
215
|
+
console.log(chalk.white(` • User preference: ${pattern.preference.replace('_', ' ')}`));
|
|
216
|
+
console.log(chalk.gray(` Category: ${pattern.category}, Avg: ${pattern.avgWordCount} words`));
|
|
217
|
+
console.log(chalk.green(` ℹ️ ${pattern.recommendation}`));
|
|
218
|
+
} else {
|
|
219
|
+
console.log(chalk.gray(` • ${pattern.recommendation} (${pattern.confidence}%)`));
|
|
220
|
+
}
|
|
221
|
+
console.log('');
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
await this.pressEnterToContinue();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Manage learned rules
|
|
230
|
+
*/
|
|
231
|
+
async manageRules() {
|
|
232
|
+
const rules = await getActiveRules(this.projectPath);
|
|
233
|
+
|
|
234
|
+
console.log(chalk.cyan.bold('\n⚙️ Learned Rules\n'));
|
|
235
|
+
|
|
236
|
+
if (rules.length === 0) {
|
|
237
|
+
console.log(chalk.yellow('No learned rules yet.\n'));
|
|
238
|
+
console.log(chalk.gray('Rules are automatically created from high-confidence patterns.\n'));
|
|
239
|
+
await this.pressEnterToContinue();
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
console.log(chalk.gray(`Total Rules: ${rules.length} active\n`));
|
|
244
|
+
|
|
245
|
+
// Show rules
|
|
246
|
+
for (let i = 0; i < rules.length; i++) {
|
|
247
|
+
const rule = rules[i];
|
|
248
|
+
const status = rule.enabled ? chalk.green('✓ Enabled') : chalk.yellow('○ Disabled');
|
|
249
|
+
|
|
250
|
+
console.log(chalk.white(`${i + 1}. ${status}`));
|
|
251
|
+
console.log(chalk.gray(` Type: ${rule.type}`));
|
|
252
|
+
console.log(chalk.gray(` ${rule.reason}`));
|
|
253
|
+
console.log(chalk.gray(` Confidence: ${rule.confidence}%`));
|
|
254
|
+
console.log('');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const { action } = await inquirer.prompt([
|
|
258
|
+
{
|
|
259
|
+
type: 'list',
|
|
260
|
+
name: 'action',
|
|
261
|
+
message: 'What would you like to do?',
|
|
262
|
+
choices: [
|
|
263
|
+
{ name: 'Enable/Disable a rule', value: 'toggle' },
|
|
264
|
+
{ name: 'Back', value: 'back' }
|
|
265
|
+
]
|
|
266
|
+
}
|
|
267
|
+
]);
|
|
268
|
+
|
|
269
|
+
if (action === 'toggle') {
|
|
270
|
+
const { ruleIndex } = await inquirer.prompt([
|
|
271
|
+
{
|
|
272
|
+
type: 'number',
|
|
273
|
+
name: 'ruleIndex',
|
|
274
|
+
message: 'Enter rule number:',
|
|
275
|
+
validate: (input) => {
|
|
276
|
+
if (input < 1 || input > rules.length) {
|
|
277
|
+
return `Please enter a number between 1 and ${rules.length}`;
|
|
278
|
+
}
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
]);
|
|
283
|
+
|
|
284
|
+
const rule = rules[ruleIndex - 1];
|
|
285
|
+
await toggleRule(this.projectPath, rule.id, !rule.enabled);
|
|
286
|
+
|
|
287
|
+
console.log(chalk.green(`\n✓ Rule ${rule.enabled ? 'disabled' : 'enabled'}\n`));
|
|
288
|
+
await this.pressEnterToContinue();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Manage learning settings
|
|
294
|
+
*/
|
|
295
|
+
async manageSettings() {
|
|
296
|
+
const config = await storage.getLearningConfig(this.projectPath);
|
|
297
|
+
|
|
298
|
+
console.log(chalk.cyan.bold('\n⚙️ Learning System Settings\n'));
|
|
299
|
+
|
|
300
|
+
const { action } = await inquirer.prompt([
|
|
301
|
+
{
|
|
302
|
+
type: 'list',
|
|
303
|
+
name: 'action',
|
|
304
|
+
message: 'What would you like to configure?',
|
|
305
|
+
choices: [
|
|
306
|
+
{
|
|
307
|
+
name: `Learning System: ${config.enabled ? chalk.green('✓ Enabled') : chalk.yellow('○ Disabled')}`,
|
|
308
|
+
value: 'toggle_enabled'
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: `Track Skip Actions: ${config.trackSkips ? chalk.green('✓') : chalk.yellow('○')}`,
|
|
312
|
+
value: 'toggle_skips'
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
name: `Track Answers: ${config.trackAnswers ? chalk.green('✓') : chalk.yellow('○')}`,
|
|
316
|
+
value: 'toggle_answers'
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
name: `Detect Patterns: ${config.detectPatterns ? chalk.green('✓') : chalk.yellow('○')}`,
|
|
320
|
+
value: 'toggle_patterns'
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
name: `Apply Learned Filters: ${config.applyLearnedFilters ? chalk.green('✓') : chalk.yellow('○')}`,
|
|
324
|
+
value: 'toggle_filters'
|
|
325
|
+
},
|
|
326
|
+
{ name: `Minimum sessions for pattern: ${config.minSessionsForPattern}`, value: 'min_sessions' },
|
|
327
|
+
{ name: `Minimum confidence for auto-filter: ${config.minConfidenceForAutoFilter}%`, value: 'min_confidence' },
|
|
328
|
+
{ name: 'Reset to defaults', value: 'reset' },
|
|
329
|
+
{ name: 'Back', value: 'back' }
|
|
330
|
+
]
|
|
331
|
+
}
|
|
332
|
+
]);
|
|
333
|
+
|
|
334
|
+
if (action === 'back') return;
|
|
335
|
+
|
|
336
|
+
if (action === 'toggle_enabled') {
|
|
337
|
+
config.enabled = !config.enabled;
|
|
338
|
+
await storage.saveLearningConfig(this.projectPath, config);
|
|
339
|
+
console.log(chalk.green(`\n✓ Learning system ${config.enabled ? 'enabled' : 'disabled'}\n`));
|
|
340
|
+
} else if (action === 'toggle_skips') {
|
|
341
|
+
config.trackSkips = !config.trackSkips;
|
|
342
|
+
await storage.saveLearningConfig(this.projectPath, config);
|
|
343
|
+
console.log(chalk.green(`\n✓ Skip tracking ${config.trackSkips ? 'enabled' : 'disabled'}\n`));
|
|
344
|
+
} else if (action === 'toggle_answers') {
|
|
345
|
+
config.trackAnswers = !config.trackAnswers;
|
|
346
|
+
await storage.saveLearningConfig(this.projectPath, config);
|
|
347
|
+
console.log(chalk.green(`\n✓ Answer tracking ${config.trackAnswers ? 'enabled' : 'disabled'}\n`));
|
|
348
|
+
} else if (action === 'toggle_patterns') {
|
|
349
|
+
config.detectPatterns = !config.detectPatterns;
|
|
350
|
+
await storage.saveLearningConfig(this.projectPath, config);
|
|
351
|
+
console.log(chalk.green(`\n✓ Pattern detection ${config.detectPatterns ? 'enabled' : 'disabled'}\n`));
|
|
352
|
+
} else if (action === 'toggle_filters') {
|
|
353
|
+
config.applyLearnedFilters = !config.applyLearnedFilters;
|
|
354
|
+
await storage.saveLearningConfig(this.projectPath, config);
|
|
355
|
+
console.log(chalk.green(`\n✓ Learned filters ${config.applyLearnedFilters ? 'enabled' : 'disabled'}\n`));
|
|
356
|
+
} else if (action === 'min_sessions') {
|
|
357
|
+
const { value } = await inquirer.prompt([
|
|
358
|
+
{
|
|
359
|
+
type: 'number',
|
|
360
|
+
name: 'value',
|
|
361
|
+
message: 'Minimum sessions for pattern detection:',
|
|
362
|
+
default: config.minSessionsForPattern,
|
|
363
|
+
validate: (input) => input >= 1 && input <= 10
|
|
364
|
+
}
|
|
365
|
+
]);
|
|
366
|
+
config.minSessionsForPattern = value;
|
|
367
|
+
await storage.saveLearningConfig(this.projectPath, config);
|
|
368
|
+
console.log(chalk.green(`\n✓ Minimum sessions updated to ${value}\n`));
|
|
369
|
+
} else if (action === 'min_confidence') {
|
|
370
|
+
const { value } = await inquirer.prompt([
|
|
371
|
+
{
|
|
372
|
+
type: 'number',
|
|
373
|
+
name: 'value',
|
|
374
|
+
message: 'Minimum confidence for auto-filter (%):',
|
|
375
|
+
default: config.minConfidenceForAutoFilter,
|
|
376
|
+
validate: (input) => input >= 50 && input <= 100
|
|
377
|
+
}
|
|
378
|
+
]);
|
|
379
|
+
config.minConfidenceForAutoFilter = value;
|
|
380
|
+
await storage.saveLearningConfig(this.projectPath, config);
|
|
381
|
+
console.log(chalk.green(`\n✓ Minimum confidence updated to ${value}%\n`));
|
|
382
|
+
} else if (action === 'reset') {
|
|
383
|
+
const defaultConfig = {
|
|
384
|
+
version: '1.0',
|
|
385
|
+
enabled: true,
|
|
386
|
+
trackSkips: true,
|
|
387
|
+
trackAnswers: true,
|
|
388
|
+
detectPatterns: true,
|
|
389
|
+
applyLearnedFilters: true,
|
|
390
|
+
shareAnonymousPatterns: false,
|
|
391
|
+
minSessionsForPattern: 3,
|
|
392
|
+
minConfidenceForAutoFilter: 75
|
|
393
|
+
};
|
|
394
|
+
await storage.saveLearningConfig(this.projectPath, defaultConfig);
|
|
395
|
+
console.log(chalk.green('\n✓ Settings reset to defaults\n'));
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
await this.pressEnterToContinue();
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Clear all learning data
|
|
403
|
+
*/
|
|
404
|
+
async clearLearningData() {
|
|
405
|
+
console.log(chalk.yellow.bold('\n⚠️ Clear Learning Data\n'));
|
|
406
|
+
console.log(chalk.gray('This will delete:'));
|
|
407
|
+
console.log(chalk.gray(' • Skip history'));
|
|
408
|
+
console.log(chalk.gray(' • Answer history'));
|
|
409
|
+
console.log(chalk.gray(' • Detected patterns'));
|
|
410
|
+
console.log(chalk.gray(' • Learned rules'));
|
|
411
|
+
console.log(chalk.gray(' • Statistics\n'));
|
|
412
|
+
console.log(chalk.red('This action cannot be undone.\n'));
|
|
413
|
+
|
|
414
|
+
const { confirm } = await inquirer.prompt([
|
|
415
|
+
{
|
|
416
|
+
type: 'confirm',
|
|
417
|
+
name: 'confirm',
|
|
418
|
+
message: 'Are you sure you want to clear all learning data?',
|
|
419
|
+
default: false
|
|
420
|
+
}
|
|
421
|
+
]);
|
|
422
|
+
|
|
423
|
+
if (confirm) {
|
|
424
|
+
await storage.clearLearningData(this.projectPath);
|
|
425
|
+
console.log(chalk.green('\n✓ Learning data cleared\n'));
|
|
426
|
+
} else {
|
|
427
|
+
console.log(chalk.gray('\nCancelled\n'));
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
await this.pressEnterToContinue();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Helper to pause for user input
|
|
435
|
+
*/
|
|
436
|
+
async pressEnterToContinue() {
|
|
437
|
+
await inquirer.prompt([
|
|
438
|
+
{
|
|
439
|
+
type: 'input',
|
|
440
|
+
name: 'continue',
|
|
441
|
+
message: 'Press Enter to continue...',
|
|
442
|
+
}
|
|
443
|
+
]);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
module.exports = LearningManager;
|