@iservu-inc/adf-cli 0.10.0 → 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/CHANGELOG.md CHANGED
@@ -5,6 +5,237 @@ All notable changes to `@iservu-inc/adf-cli` will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.11.0] - 2025-11-04
9
+
10
+ ### 📊 Learning Analytics Dashboard - Phase 6.2
11
+
12
+ **MAJOR FEATURE:** Comprehensive analytics dashboard for visualizing and analyzing learning system performance with 10+ metrics and multi-format export.
13
+
14
+ #### What's New
15
+
16
+ **Analytics Dashboard:**
17
+ - **Interactive CLI Dashboard** - Navigate through multiple analytics views with intuitive menu
18
+ - **10+ Key Metrics** - Overview stats, skip trends, category preferences, pattern distribution, effectiveness
19
+ - **ASCII Visualizations** - Bar charts, distribution displays, and heatmaps in the terminal
20
+ - **Multi-Format Export** - Export analytics as JSON (single file) or CSV (5 separate files)
21
+ - **Pattern Health Tracking** - Monitor pattern decay status (healthy/warning/critical)
22
+ - **Time-Based Trends** - 12-week skip trend analysis with skip rate calculations
23
+ - **Effectiveness Metrics** - Track time saved, pattern accuracy, and rule performance
24
+
25
+ #### Core Components
26
+
27
+ **Analytics Engine (lib/learning/analytics.js - 680 lines):**
28
+ - `generateAnalytics()` - Main analytics generation with comprehensive data aggregation
29
+ - `calculateOverviewStats()` - Total sessions, skips, answers, patterns, rules, learning age
30
+ - `calculateSkipTrends()` - 12-week trend analysis with skip rates
31
+ - `calculateCategoryPreferences()` - Category-level skip rates and preference levels
32
+ - `calculatePatternDistribution()` - Confidence distribution (high/medium/low/veryLow)
33
+ - `calculateDecayStatus()` - Pattern health categorization (healthy/warning/critical)
34
+ - `calculateEffectiveness()` - Time saved, pattern accuracy, rule applications, overall effectiveness
35
+ - `calculateSessionTimeline()` - Session frequency and history analysis
36
+ - `calculateImpactfulPatterns()` - Top patterns by time saved and applications
37
+ - `calculateQuestionStats()` - Most answered/skipped questions
38
+
39
+ **Dashboard UI (lib/learning/analytics-view.js - 530 lines):**
40
+ - `showAnalyticsDashboard()` - Main dashboard entry point
41
+ - `showMainDashboard()` - Overview, trends, and effectiveness view
42
+ - `showCategoryView()` - Detailed category breakdown with heatmap
43
+ - `showPatternHealthView()` - Pattern confidence and decay status
44
+ - `showTimelineView()` - Session history and frequency
45
+ - `showQuestionStatsView()` - Question statistics and insights
46
+ - `showImpactfulPatternsView()` - Top performing patterns
47
+ - `handleExport()` - Export functionality integration
48
+
49
+ **Export Module (lib/learning/analytics-exporter.js - 240 lines):**
50
+ - `exportAnalytics()` - Main export router (JSON/CSV)
51
+ - `exportJSON()` - Single comprehensive JSON file export
52
+ - `exportCSV()` - Multi-file CSV export (5 files)
53
+ - CSV generators for: overview, skip trends, categories, patterns, effectiveness
54
+ - Proper CSV escaping and timestamp-based filenames
55
+
56
+ #### Analytics Metrics
57
+
58
+ **Overview Statistics:**
59
+ - Total sessions count
60
+ - Total skips (manual + filtered breakdown)
61
+ - Total answers count
62
+ - Active patterns and rules
63
+ - Learning system age (days since first session)
64
+
65
+ **Skip Trends (12 weeks):**
66
+ - Weekly skip counts (manual vs filtered)
67
+ - Skip rate percentage per week
68
+ - Week-over-week comparison
69
+
70
+ **Category Preferences:**
71
+ - Skip rate by category (0-100%)
72
+ - Preference levels: High Skip (≥70%), Medium Skip (40-69%), Low Skip (<40%)
73
+ - Total questions per category
74
+ - Sorted by skip rate descending
75
+
76
+ **Pattern Distribution:**
77
+ - Total patterns count
78
+ - Distribution by confidence:
79
+ - High (≥90%) - Very strong patterns
80
+ - Medium (75-89%) - Strong patterns
81
+ - Low (50-74%) - Weak patterns
82
+ - Very Low (<50%) - Very weak patterns
83
+ - Average confidence score
84
+ - Patterns at risk count (confidence <50 or inactive 5+ months)
85
+
86
+ **Pattern Decay Status:**
87
+ - Healthy patterns (confidence ≥75%, active <3 months)
88
+ - Warning patterns (confidence 50-74%, active 3-5 months)
89
+ - Critical patterns (confidence <50 or inactive 5+ months)
90
+ - Recently renewed count (last 30 days)
91
+ - Average pattern age (days)
92
+
93
+ **Effectiveness Metrics:**
94
+ - Time saved (minutes and hours)
95
+ - Questions filtered count
96
+ - False positives and rate
97
+ - Pattern accuracy (% user-approved)
98
+ - Total rule applications
99
+ - Average applications per rule
100
+ - Overall effectiveness score
101
+
102
+ **Session Timeline:**
103
+ - Total sessions count
104
+ - Average sessions per week
105
+ - Session history with dates
106
+ - First and last session dates
107
+
108
+ **Impactful Patterns:**
109
+ - Top 10 by time saved (most effective filters)
110
+ - Top 10 by applications (most frequently used)
111
+
112
+ **Question Statistics:**
113
+ - Top 10 most answered questions
114
+ - Top 10 most skipped questions
115
+ - Total unique questions encountered
116
+
117
+ #### Export Formats
118
+
119
+ **JSON Export:**
120
+ - Single comprehensive file with all analytics
121
+ - Structure: `analytics-YYYY-MM-DDTHH-MM-SS.json`
122
+ - Includes all metrics, trends, and metadata
123
+ - Size: ~50-100 KB for typical datasets
124
+
125
+ **CSV Export:**
126
+ - 5 separate CSV files for different metrics:
127
+ 1. `analytics-overview-*.csv` - Overview statistics
128
+ 2. `analytics-skip-trends-*.csv` - 12-week trends
129
+ 3. `analytics-categories-*.csv` - Category preferences
130
+ 4. `analytics-patterns-*.csv` - Pattern distribution and decay
131
+ 5. `analytics-effectiveness-*.csv` - Effectiveness metrics
132
+ - Timestamp-based filenames
133
+ - Proper CSV escaping for special characters
134
+
135
+ #### Access & Usage
136
+
137
+ **Dashboard Access:**
138
+ ```bash
139
+ adf config
140
+ # → Learning System
141
+ # → 4. 📊 Analytics Dashboard (NEW)
142
+ ```
143
+
144
+ **Navigation:**
145
+ - Main Dashboard → Overview, Trends, Effectiveness
146
+ - Category Breakdown → Skip rates by category with heatmap
147
+ - Pattern Health → Confidence distribution and decay status
148
+ - Session Timeline → Session history and frequency
149
+ - Question Statistics → Most answered/skipped questions
150
+ - Impactful Patterns → Top performers by time saved/applications
151
+ - Export Analytics → JSON or CSV format
152
+
153
+ **Export Location:**
154
+ ```
155
+ .adf/learning/exports/
156
+ ├── analytics-2025-11-04T10-30-45.json
157
+ └── analytics-overview-2025-11-04T10-30-45.csv
158
+ └── analytics-skip-trends-2025-11-04T10-30-45.csv
159
+ └── analytics-categories-2025-11-04T10-30-45.csv
160
+ └── analytics-patterns-2025-11-04T10-30-45.csv
161
+ └── analytics-effectiveness-2025-11-04T10-30-45.csv
162
+ ```
163
+
164
+ #### Testing
165
+
166
+ **Test Coverage:**
167
+ - `analytics.test.js` - 25/25 tests passing (100%) ✅
168
+ - `analytics-exporter.test.js` - 23/23 tests passing (100%) ✅
169
+ - `analytics-view.test.js` - 4/13 tests passing (31% - integration tests)
170
+ - **Overall:** 52/61 analytics tests (85.2%)
171
+ - **Project-wide:** 276/300 tests (92%)
172
+
173
+ **Test Data Generator:**
174
+ - `scripts/generate-test-data.js` - Mock data generator for testing
175
+ - 5 scenarios: empty, new user, active user, power user, edge cases
176
+ - Generates realistic learning data for dashboard testing
177
+
178
+ #### Performance
179
+
180
+ **Load Time Target:** < 2 seconds for 100+ sessions
181
+ **Memory Efficiency:** Streaming data processing for large datasets
182
+ **Visualization:** Lightweight ASCII charts for terminal rendering
183
+
184
+ #### Configuration
185
+
186
+ No additional configuration required. Analytics uses existing learning data from:
187
+ - `.adf/learning/skip-history.json`
188
+ - `.adf/learning/answer-history.json`
189
+ - `.adf/learning/patterns.json`
190
+ - `.adf/learning/learned-rules.json`
191
+ - `.adf/learning/stats.json`
192
+
193
+ #### Benefits
194
+
195
+ **For Users:**
196
+ - Understand learning system behavior and effectiveness
197
+ - Identify patterns in skip/answer behavior
198
+ - Track pattern health and decay status
199
+ - Monitor time savings from automated filtering
200
+ - Make data-driven decisions about pattern approval
201
+
202
+ **For Debugging:**
203
+ - Verify pattern detection is working correctly
204
+ - Validate decay algorithm effectiveness
205
+ - Identify false positives
206
+ - Analyze category-specific behavior
207
+ - Export data for external analysis
208
+
209
+ #### Use Cases
210
+
211
+ **Use Case 1: Review Learning System Performance**
212
+ - View overview to see total sessions and effectiveness
213
+ - Check skip trends to understand behavior over time
214
+ - Review pattern accuracy to validate system
215
+
216
+ **Use Case 2: Optimize Pattern Management**
217
+ - Check pattern health view to identify critical patterns
218
+ - Review impactful patterns to see which provide most value
219
+ - Export data for deeper analysis
220
+
221
+ **Use Case 3: Category-Specific Analysis**
222
+ - View category breakdown to identify high-skip categories
223
+ - Understand which question types are most relevant
224
+ - Adjust workflow based on insights
225
+
226
+ **Use Case 4: Export for Reporting**
227
+ - Generate JSON export for programmatic analysis
228
+ - Create CSV exports for spreadsheet analysis
229
+ - Share analytics with team members
230
+
231
+ #### Breaking Changes
232
+
233
+ None. Fully backward compatible with existing learning data.
234
+
235
+ #### Migration
236
+
237
+ No migration required. Analytics reads existing learning data without modifications.
238
+
8
239
  ## [0.10.0] - 2025-10-27
9
240
 
10
241
  ### 🧠 Pattern Decay Algorithm - Phase 6
package/README.md CHANGED
@@ -291,7 +291,13 @@ ADF CLI includes an intelligent Learning System that improves your interview exp
291
291
  - Framework-specific skips (e.g., routing questions for Next.js projects)
292
292
  - Answer style preferences (brief vs detailed)
293
293
  3. **Rule Generation** - Converts high-confidence patterns (≥75%) into learned rules
294
- 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)
295
301
 
296
302
  ### Managing Learning Data
297
303
 
@@ -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
+ };