@iservu-inc/adf-cli 0.9.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -62,7 +62,7 @@ adf init --rapid --tool cursor
62
62
 
63
63
  ### Configure ADF Settings
64
64
 
65
- Configure ADF settings like AI provider, learning system, and more:
65
+ Configure ADF settings like AI provider, AI analysis settings, learning system, and more:
66
66
 
67
67
  ```bash
68
68
  adf config
@@ -70,14 +70,17 @@ adf config
70
70
 
71
71
  This command provides an interactive menu with:
72
72
  - **AI Provider Setup** - Configure Anthropic, OpenAI, Google Gemini, or OpenRouter
73
+ - **AI Analysis Settings** - Configure performance modes and AI features
74
+ - **IDE Deployment** - Deploy to multiple IDEs
73
75
  - **Learning System** - Manage interview learning data and preferences
74
76
  - Status indicators showing what's configured (green ✓), disabled (yellow ○), or has data
75
- - Future configuration options (coming soon)
76
77
 
77
78
  You can run `adf config` anytime to:
78
79
  - Configure AI for the first time
79
80
  - Switch AI providers or models
80
81
  - Update your API keys
82
+ - Adjust AI analysis performance and features
83
+ - Deploy to development tools
81
84
  - Review learning patterns and manage learned preferences
82
85
 
83
86
  ### Deploy to Development Tool
@@ -203,6 +206,78 @@ Select "AI Provider Setup" and you'll see:
203
206
 
204
207
  Your previous API keys remain saved in `.adf/.env` for easy switching between providers.
205
208
 
209
+ ## AI Analysis Settings
210
+
211
+ ADF CLI provides three performance modes and five configurable AI features, giving you complete control over the speed vs intelligence tradeoff during interviews.
212
+
213
+ ### Performance Modes
214
+
215
+ Configure via `adf config` → AI Analysis Settings:
216
+
217
+ **Fast Mode:**
218
+ - Zero AI delays (~0.5s per answer)
219
+ - All AI features disabled
220
+ - Best for: Quick workflows, prototyping, low-priority projects
221
+
222
+ **Balanced Mode (Default):**
223
+ - 2-3 seconds per answer
224
+ - Quality Analysis, Smart Filtering, and Pattern Detection enabled
225
+ - Question Reordering and Follow-up Questions disabled
226
+ - Best for: Most projects - optimal balance of speed and intelligence
227
+
228
+ **Comprehensive Mode:**
229
+ - 4-6 seconds per answer
230
+ - All AI features enabled
231
+ - Maximum intelligence and guidance
232
+ - Best for: Complex projects, critical systems, maximum thoroughness
233
+
234
+ ### Configurable AI Features
235
+
236
+ Five AI features can be toggled individually:
237
+
238
+ 1. **AI-Powered Quality Analysis** (Medium Impact: 1-2s)
239
+ - Real-time answer quality scoring (0-100)
240
+ - Improvement suggestions for low-quality answers
241
+ - Helps ensure comprehensive requirements gathering
242
+
243
+ 2. **Intelligent Question Reordering** (High Impact: 2-3s)
244
+ - Dynamically reorders questions based on extracted knowledge
245
+ - Prioritizes fundamental questions first
246
+ - Adapts interview flow to your answers
247
+
248
+ 3. **AI-Generated Follow-Up Questions** (Medium Impact: 1-2s when triggered)
249
+ - Context-specific follow-ups for incomplete answers
250
+ - Only triggers for low-quality answers (< 70 score)
251
+ - Helps gather missing information intelligently
252
+
253
+ 4. **Pattern Detection & Learning** (Low Impact: minimal)
254
+ - Learns from your skip behavior over time
255
+ - Generates learned rules from patterns
256
+ - Lightweight, runs locally
257
+
258
+ 5. **Smart Question Filtering** (Low Impact: minimal)
259
+ - Analyzes project type and context
260
+ - Filters out irrelevant questions automatically
261
+ - Saves time on specialized projects (CLI tools, APIs, etc.)
262
+
263
+ ### Configuration
264
+
265
+ Access AI Analysis Settings:
266
+
267
+ ```bash
268
+ adf config
269
+ # Select "AI Analysis Settings"
270
+ ```
271
+
272
+ Settings are saved to `.adf/analysis-config.json` and apply to all future interviews.
273
+
274
+ **Performance Mode Display:**
275
+ At interview start, you'll see:
276
+ ```
277
+ 🎛️ AI Analysis Mode: Balanced
278
+ (Configure via: adf config → AI Analysis Settings)
279
+ ```
280
+
206
281
  ## Learning System
207
282
 
208
283
  ADF CLI includes an intelligent Learning System that improves your interview experience by learning from your behavior across sessions.
@@ -216,7 +291,13 @@ ADF CLI includes an intelligent Learning System that improves your interview exp
216
291
  - Framework-specific skips (e.g., routing questions for Next.js projects)
217
292
  - Answer style preferences (brief vs detailed)
218
293
  3. **Rule Generation** - Converts high-confidence patterns (≥75%) into learned rules
219
- 4. **Adaptive Filtering** - Applies learned rules in future interviews (with your approval)
294
+ 4. **Pattern Decay** - Automatically keeps patterns fresh and relevant:
295
+ - Inactive patterns lose confidence over time using exponential decay
296
+ - High-confidence patterns (≥90%) decay slower than weak patterns
297
+ - Patterns reconfirmed by your behavior get +10 confidence boost
298
+ - Stale patterns (confidence <40 or inactive 6+ months) automatically removed
299
+ - User-approved patterns protected (decay at half rate)
300
+ 5. **Adaptive Filtering** - Applies learned rules in future interviews (with your approval)
220
301
 
221
302
  ### Managing Learning Data
222
303
 
@@ -414,27 +495,41 @@ When we release updates to the framework:
414
495
 
415
496
  See [CHANGELOG.md](./CHANGELOG.md) for detailed version history.
416
497
 
417
- **Latest:** v0.4.12
418
- - **Learning System (Phase 4.2)** - Learns from your skip behavior to improve filtering
419
- - Automatic pattern detection across interview sessions
420
- - Learned rule generation from high-confidence patterns
421
- - Adaptive filtering with user approval
422
- - Learning management CLI via `adf config`
423
- - Privacy-first local storage in `.adf/learning/`
424
- - **Smart Question Filtering (Phase 4.1)** - Context-aware question filtering
425
- - Project analysis (type, frameworks, languages)
426
- - Intelligent question relevance scoring
427
- - Time estimation for skipped questions
428
- - User control with confidence thresholds
429
- - Enhanced config command with Learning System integration
430
-
431
- **Previous:** v0.3.6
432
- - AI-guided requirements gathering with multi-provider support
433
- - Real-time answer quality analysis and intelligent follow-ups
434
- - Secure API key persistence in `.adf/.env`
435
- - Dynamic model fetching with autocomplete selection
436
- - Enhanced UX with visible skip instructions
437
- - Automatic deployment to your preferred IDE
498
+ **Latest:** v0.10.0 (2025-10-27)
499
+ - **Pattern Decay Algorithm (v0.10.0)** - Phase 6: Advanced Learning Features
500
+ - Time-based exponential decay for inactive patterns
501
+ - Confidence-based decay rates (high/medium/low)
502
+ - Automatic pattern cleanup and renewal system
503
+ - 40+ comprehensive tests for decay functionality
504
+ - Pattern metadata tracking (timestamps, renewal counts)
505
+ - Removal history and analytics
506
+
507
+ **Previous Release:** v0.9.1 (2025-10-05)
508
+ - **AI Analysis Settings (v0.9.0)** - Performance modes and configurable AI features
509
+ - Three performance modes: Fast, Balanced, Comprehensive
510
+ - Five individually configurable AI features
511
+ - Complete control over speed vs intelligence tradeoff
512
+ - New configuration category in `adf config`
513
+ - Performance mode display at interview start
514
+ - **Resume from Exit (v0.8.0)** - Resume interviews after exit
515
+ - Type `exit` or press Ctrl+C to save progress and quit
516
+ - Resume with `adf init` continues from last question
517
+ - Already-answered questions automatically skipped
518
+ - Graceful quit handling everywhere
519
+ - **UX Improvements (v0.5.1-v0.7.1)** - Enhanced user experience
520
+ - Terminal input restoration (v0.7.1)
521
+ - Better existing project detection with clear options
522
+ - Post-install information display
523
+ - Configuration validation and auto-reset
524
+
525
+ **Previous Releases:**
526
+ - **v0.5.0** - Intelligent Answer Analysis & Dynamic Question Pipeline
527
+ - **v0.4.36** - Multi-IDE Improvements & Config Command Enhancement
528
+ - **v0.4.12** - Learning System (Phase 4.2) & Smart Question Filtering (Phase 4.1)
529
+ - **v0.3.6** - Configuration Command & Optional AI Setup
530
+ - **v0.3.4** - Multi-Provider AI Integration (Anthropic, OpenAI, Google, OpenRouter)
531
+ - **v0.2.0** - Quality-Based Progress Tracking & Resume Capability
532
+ - **v0.1.0** - Initial Release
438
533
 
439
534
  ## Troubleshooting
440
535
 
@@ -0,0 +1,241 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+
4
+ /**
5
+ * Learning Analytics Exporter
6
+ *
7
+ * Handles exporting analytics data in multiple formats:
8
+ * - JSON: Single comprehensive file with all analytics
9
+ * - CSV: Multiple files for different metrics
10
+ */
11
+
12
+ /**
13
+ * Export analytics data
14
+ * @param {Object} analyticsData - Complete analytics data
15
+ * @param {string} projectPath - Project root path
16
+ * @param {string} format - Export format ('json' or 'csv')
17
+ * @returns {Promise<Object>} Export result with file paths
18
+ */
19
+ async function exportAnalytics(analyticsData, projectPath, format = 'json') {
20
+ const learningPath = path.join(projectPath, '.adf', 'learning');
21
+ const exportsPath = path.join(learningPath, 'exports');
22
+
23
+ // Ensure exports directory exists
24
+ await fs.ensureDir(exportsPath);
25
+
26
+ if (format === 'json') {
27
+ return await exportJSON(analyticsData, exportsPath);
28
+ } else if (format === 'csv') {
29
+ return await exportCSV(analyticsData, exportsPath);
30
+ } else {
31
+ throw new Error(`Unsupported export format: ${format}`);
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Export analytics as JSON
37
+ * @param {Object} analyticsData - Analytics data
38
+ * @param {string} exportsPath - Exports directory path
39
+ * @returns {Promise<Object>} Export result
40
+ */
41
+ async function exportJSON(analyticsData, exportsPath) {
42
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
43
+ const filename = `analytics-${timestamp}.json`;
44
+ const filePath = path.join(exportsPath, filename);
45
+
46
+ // Write JSON file
47
+ await fs.writeJSON(filePath, analyticsData, { spaces: 2 });
48
+
49
+ // Get file size
50
+ const stats = await fs.stat(filePath);
51
+ const sizeKB = (stats.size / 1024).toFixed(2);
52
+
53
+ return {
54
+ file: filePath,
55
+ size: `${sizeKB} KB`,
56
+ format: 'json'
57
+ };
58
+ }
59
+
60
+ /**
61
+ * Export analytics as CSV (multiple files)
62
+ * @param {Object} analyticsData - Analytics data
63
+ * @param {string} exportsPath - Exports directory path
64
+ * @returns {Promise<Object>} Export result
65
+ */
66
+ async function exportCSV(analyticsData, exportsPath) {
67
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
68
+ const files = [];
69
+
70
+ // Export overview
71
+ const overviewFile = path.join(exportsPath, `analytics-overview-${timestamp}.csv`);
72
+ await fs.writeFile(overviewFile, generateOverviewCSV(analyticsData.overview));
73
+ files.push(overviewFile);
74
+
75
+ // Export skip trends
76
+ const trendsFile = path.join(exportsPath, `analytics-skip-trends-${timestamp}.csv`);
77
+ await fs.writeFile(trendsFile, generateSkipTrendsCSV(analyticsData.skipTrends));
78
+ files.push(trendsFile);
79
+
80
+ // Export category preferences
81
+ const categoriesFile = path.join(exportsPath, `analytics-categories-${timestamp}.csv`);
82
+ await fs.writeFile(categoriesFile, generateCategoriesCSV(analyticsData.categoryPreferences));
83
+ files.push(categoriesFile);
84
+
85
+ // Export patterns
86
+ const patternsFile = path.join(exportsPath, `analytics-patterns-${timestamp}.csv`);
87
+ await fs.writeFile(patternsFile, generatePatternsCSV(analyticsData.patternDistribution, analyticsData.decayStatus));
88
+ files.push(patternsFile);
89
+
90
+ // Export effectiveness
91
+ const effectivenessFile = path.join(exportsPath, `analytics-effectiveness-${timestamp}.csv`);
92
+ await fs.writeFile(effectivenessFile, generateEffectivenessCSV(analyticsData.effectiveness));
93
+ files.push(effectivenessFile);
94
+
95
+ return {
96
+ files,
97
+ format: 'csv'
98
+ };
99
+ }
100
+
101
+ /**
102
+ * Generate overview CSV
103
+ * @param {Object} overview - Overview data
104
+ * @returns {string} CSV content
105
+ */
106
+ function generateOverviewCSV(overview) {
107
+ const rows = [
108
+ ['Metric', 'Value', 'Unit'],
109
+ ['Total Sessions', overview.totalSessions, 'sessions'],
110
+ ['Total Skips', overview.totalSkips, 'questions'],
111
+ ['Manual Skips', overview.manualSkips, 'questions'],
112
+ ['Filtered Skips', overview.filteredSkips, 'questions'],
113
+ ['Total Answers', overview.totalAnswers, 'questions'],
114
+ ['Active Patterns', overview.activePatterns, 'patterns'],
115
+ ['Active Rules', overview.activeRules, 'rules'],
116
+ ['Learning Age', overview.learningAge, 'days']
117
+ ];
118
+
119
+ return rows.map(row => row.join(',')).join('\n');
120
+ }
121
+
122
+ /**
123
+ * Generate skip trends CSV
124
+ * @param {Array} skipTrends - Skip trends data
125
+ * @returns {string} CSV content
126
+ */
127
+ function generateSkipTrendsCSV(skipTrends) {
128
+ const rows = [
129
+ ['Week', 'Week Number', 'Manual Skips', 'Filtered Skips', 'Total Skips', 'Skip Rate (%)']
130
+ ];
131
+
132
+ for (const trend of skipTrends) {
133
+ rows.push([
134
+ trend.week,
135
+ trend.weekNumber,
136
+ trend.manualSkips,
137
+ trend.filteredSkips,
138
+ trend.totalSkips,
139
+ trend.skipRate
140
+ ]);
141
+ }
142
+
143
+ return rows.map(row => row.join(',')).join('\n');
144
+ }
145
+
146
+ /**
147
+ * Generate categories CSV
148
+ * @param {Array} categories - Category preferences data
149
+ * @returns {string} CSV content
150
+ */
151
+ function generateCategoriesCSV(categories) {
152
+ const rows = [
153
+ ['Category', 'Skips', 'Answers', 'Total', 'Skip Rate (%)', 'Level']
154
+ ];
155
+
156
+ for (const cat of categories) {
157
+ rows.push([
158
+ escapeCSV(cat.category),
159
+ cat.skips,
160
+ cat.answers,
161
+ cat.total,
162
+ cat.skipRate,
163
+ cat.level
164
+ ]);
165
+ }
166
+
167
+ return rows.map(row => row.join(',')).join('\n');
168
+ }
169
+
170
+ /**
171
+ * Generate patterns CSV
172
+ * @param {Object} patternDistribution - Pattern distribution data
173
+ * @param {Object} decayStatus - Decay status data
174
+ * @returns {string} CSV content
175
+ */
176
+ function generatePatternsCSV(patternDistribution, decayStatus) {
177
+ const dist = patternDistribution.distribution || { high: 0, medium: 0, low: 0, veryLow: 0 };
178
+ const decay = decayStatus || { healthy: 0, warning: 0, critical: 0, recentlyRenewed: 0, avgAge: 0 };
179
+
180
+ const rows = [
181
+ ['Metric', 'Value', 'Description'],
182
+ ['Total Patterns', patternDistribution.totalPatterns || 0, 'All patterns'],
183
+ ['High Confidence (90%+)', dist.high, 'Very strong patterns'],
184
+ ['Medium Confidence (75-89%)', dist.medium, 'Strong patterns'],
185
+ ['Low Confidence (50-74%)', dist.low, 'Weak patterns'],
186
+ ['Very Low Confidence (<50%)', dist.veryLow, 'Very weak patterns'],
187
+ ['Average Confidence', (patternDistribution.avgConfidence || 0) + '%', 'Mean confidence score'],
188
+ ['At Risk', patternDistribution.atRiskCount || 0, 'Patterns at risk of removal'],
189
+ ['', '', ''],
190
+ ['Decay Status', '', ''],
191
+ ['Healthy Patterns', decay.healthy, 'Active and strong'],
192
+ ['Warning Patterns', decay.warning, 'Needs attention'],
193
+ ['Critical Patterns', decay.critical, 'May be removed soon'],
194
+ ['Recently Renewed', decay.recentlyRenewed, 'Last 30 days'],
195
+ ['Average Age', decay.avgAge + ' days', 'Mean pattern age']
196
+ ];
197
+
198
+ return rows.map(row => row.join(',')).join('\n');
199
+ }
200
+
201
+ /**
202
+ * Generate effectiveness CSV
203
+ * @param {Object} effectiveness - Effectiveness data
204
+ * @returns {string} CSV content
205
+ */
206
+ function generateEffectivenessCSV(effectiveness) {
207
+ const rows = [
208
+ ['Metric', 'Value', 'Unit'],
209
+ ['Time Saved', effectiveness.timeSavedMinutes, 'minutes'],
210
+ ['Time Saved (Hours)', effectiveness.timeSavedHours, 'hours'],
211
+ ['Questions Filtered', effectiveness.questionsFiltered, 'questions'],
212
+ ['False Positives', effectiveness.falsePositives, 'questions'],
213
+ ['False Positive Rate', effectiveness.falsePositiveRate, '%'],
214
+ ['Pattern Accuracy', effectiveness.patternAccuracy, '%'],
215
+ ['Total Rule Applications', effectiveness.totalRuleApplications, 'applications'],
216
+ ['Avg Applications Per Rule', effectiveness.avgApplicationsPerRule, 'applications'],
217
+ ['Overall Effectiveness', effectiveness.overallEffectiveness, '%']
218
+ ];
219
+
220
+ return rows.map(row => row.join(',')).join('\n');
221
+ }
222
+
223
+ /**
224
+ * Escape CSV value
225
+ * @param {string} value - Value to escape
226
+ * @returns {string} Escaped value
227
+ */
228
+ function escapeCSV(value) {
229
+ if (typeof value !== 'string') return value;
230
+
231
+ // Escape quotes and wrap in quotes if contains special chars
232
+ if (value.includes(',') || value.includes('"') || value.includes('\n')) {
233
+ return '"' + value.replace(/"/g, '""') + '"';
234
+ }
235
+
236
+ return value;
237
+ }
238
+
239
+ module.exports = {
240
+ exportAnalytics
241
+ };