devcompass 2.3.0 → 2.4.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
@@ -1,25 +1,50 @@
1
1
  # 🧭 DevCompass
2
2
 
3
- **Dependency health checker with ecosystem intelligence for JavaScript/TypeScript projects**
3
+ **Dependency health checker with ecosystem intelligence and real-time GitHub issue tracking for JavaScript/TypeScript projects**
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/devcompass.svg)](https://www.npmjs.com/package/devcompass)
6
6
  [![npm downloads](https://img.shields.io/npm/dm/devcompass.svg)](https://www.npmjs.com/package/devcompass)
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
8
 
9
- Analyze your JavaScript projects to find unused dependencies, outdated packages, **detect security vulnerabilities**, **check bundle sizes**, **verify licenses**, and **automatically fix issues** with a single command. Perfect for **CI/CD pipelines** with JSON output and exit codes.
9
+ Analyze your JavaScript projects to find unused dependencies, outdated packages, **detect security vulnerabilities**, **monitor GitHub issues in real-time**, **check bundle sizes**, **verify licenses**, and **automatically fix issues** with a single command. Perfect for **CI/CD pipelines** with JSON output and exit codes.
10
10
 
11
+ > **NEW in v2.4.0:** Real-time GitHub issue tracking & predictive warnings! šŸ”®
12
+ > **NEW in v2.3.1:** Fixed all security vulnerabilities! Health score: 2.5/10 → 8/10 šŸ”’
11
13
  > **NEW in v2.3:** Security scanning, bundle analysis & license checker! šŸ”
12
14
  > **NEW in v2.2:** CI/CD integration with JSON output & smart caching! šŸš€
13
15
  > **NEW in v2.1:** Auto-fix command! šŸ”§ Fix critical issues automatically!
14
16
  > **NEW in v2.0:** Real-time ecosystem alerts for known issues! 🚨
15
17
 
18
+ ## šŸŽ‰ Latest Update: v2.4.0
19
+
20
+ **Real-time GitHub issue tracking is here!** DevCompass now monitors live GitHub activity for 14+ popular packages:
21
+
22
+ - šŸ”® **Predictive warnings** based on recent bug activity
23
+ - šŸ“Š **Risk scoring** (high/medium/low severity)
24
+ - šŸ“ˆ **Trend analysis** (increasing/stable/decreasing)
25
+ - ⚔ **93% faster** with smart caching (8s → 0.5s)
26
+ - šŸ”— **Direct links** to GitHub repositories
27
+
28
+ **Example warning:**
29
+ ```
30
+ šŸ”® PREDICTIVE WARNINGS (1)
31
+
32
+ 🟔 express
33
+ Increased issue activity
34
+ 15 new issues in last 7 days
35
+ → Monitor for stability
36
+ GitHub: https://github.com/expressjs/express
37
+ ```
38
+
16
39
  ## ✨ Features
17
40
 
18
- - šŸ” **Security Scanning** (NEW in v2.3!) - npm audit integration with severity breakdown
19
- - šŸ“¦ **Bundle Size Analysis** (NEW in v2.3!) - Identify heavy packages (> 1MB)
20
- - āš–ļø **License Checker** (NEW in v2.3!) - Detect restrictive licenses (GPL, AGPL)
41
+ - šŸ”® **GitHub Issue Tracking** (v2.4) - Real-time monitoring of package health
42
+ - šŸ“ˆ **Predictive Warnings** (v2.4) - Detect issues before they're announced
43
+ - šŸ” **Security Scanning** (v2.3) - npm audit integration with severity breakdown
44
+ - šŸ“¦ **Bundle Size Analysis** (v2.3) - Identify heavy packages (> 1MB)
45
+ - āš–ļø **License Checker** (v2.3) - Detect restrictive licenses (GPL, AGPL)
21
46
  - šŸš€ **CI/CD Integration** (v2.2) - JSON output, exit codes, and silent mode
22
- - ⚔ **Smart Caching** (v2.2) - 70% faster on repeated runs
47
+ - ⚔ **Smart Caching** (v2.2) - 93% faster on repeated runs
23
48
  - šŸŽ›ļø **Advanced Filtering** (v2.2) - Control alerts by severity level
24
49
  - šŸ”§ **Auto-Fix Command** (v2.1) - Fix issues automatically with one command
25
50
  - 🚨 **Ecosystem Intelligence** (v2.0) - Detect known issues before they break production
@@ -65,11 +90,60 @@ devcompass analyze --ci
65
90
  devcompass analyze --silent
66
91
  ```
67
92
 
68
- ## šŸ” NEW in v2.3: Security & Compliance Features
93
+ ## šŸ”® Predictive Warnings (v2.4.0)
94
+
95
+ DevCompass now monitors **real-time GitHub activity** to detect potential issues before they're officially reported!
96
+
97
+ ### What it tracks:
98
+ - šŸ› **Open bug reports** in the last 7/30 days
99
+ - šŸ”„ **High-activity packages** with unusual issue spikes
100
+ - šŸ“ˆ **Trend analysis** (increasing/stable/decreasing)
101
+ - āš ļø **Critical issues** flagged by maintainers
102
+
103
+ ### Currently tracked packages (14+):
104
+ - **axios**, **lodash**, **moment**, **express**
105
+ - **react**, **vue**, **next**, **webpack**
106
+ - **typescript**, **eslint**, **jest**, **prettier**
107
+ - **node-fetch**, **chalk**
108
+
109
+ ### Example Output:
110
+ ```
111
+ šŸ”® PREDICTIVE WARNINGS (2)
112
+
113
+ Based on recent GitHub activity:
114
+
115
+ 🟠 axios
116
+ High bug activity detected
117
+ 15 new issues in last 7 days
118
+ → Consider delaying upgrade or monitoring closely
119
+ GitHub: https://github.com/axios/axios
120
+
121
+ 🟔 webpack
122
+ Increased issue activity
123
+ 8 issues opened recently
124
+ → Monitor for stability
125
+ GitHub: https://github.com/webpack/webpack
126
+ ```
127
+
128
+ ### How it works:
129
+ 1. Fetches live issue data from GitHub API
130
+ 2. Analyzes issue frequency (last 7/30 days)
131
+ 3. Detects critical issues via labels
132
+ 4. Calculates risk scores
133
+ 5. Provides actionable recommendations
134
+
135
+ ### Performance:
136
+ - **First run:** ~8 seconds (fetches GitHub data for 14 packages)
137
+ - **Cached runs:** ~0.5 seconds (93% faster!)
138
+ - **Cache duration:** 1 hour
139
+
140
+ > More packages being added in v2.5.0 (expanding to top 500)!
141
+
142
+ ## šŸ” Security & Compliance Features
69
143
 
70
144
  ### Security Vulnerability Scanning
71
145
 
72
- DevCompass now integrates with **npm audit** to detect security vulnerabilities automatically!
146
+ DevCompass integrates with **npm audit** to detect security vulnerabilities automatically!
73
147
 
74
148
  **Example Output:**
75
149
  ```
@@ -141,22 +215,18 @@ Detect restrictive licenses that may require legal review!
141
215
  - āš ļø **Restrictive:** GPL, AGPL, LGPL
142
216
  - ā“ **Unknown:** Missing or custom licenses
143
217
 
144
- ### Combined Analysis Example (v2.3)
218
+ ### Combined Analysis Example
145
219
 
146
220
  **Full Output:**
147
221
  ```
148
- šŸ” DevCompass v2.3.0 - Analyzing your project...
222
+ šŸ” DevCompass v2.4.0 - Analyzing your project...
149
223
  āœ” Scanned 25 dependencies in project
150
224
 
151
225
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
152
226
 
153
- šŸ” SECURITY VULNERABILITIES (5)
227
+ āœ… SECURITY VULNERABILITIES
154
228
 
155
- šŸ”“ CRITICAL: 1
156
- 🟠 HIGH: 2
157
- 🟔 MODERATE: 2
158
-
159
- Run npm audit fix to fix vulnerabilities
229
+ No vulnerabilities detected!
160
230
 
161
231
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
162
232
 
@@ -169,6 +239,18 @@ Detect restrictive licenses that may require legal review!
169
239
 
170
240
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
171
241
 
242
+ šŸ”® PREDICTIVE WARNINGS (1)
243
+
244
+ Based on recent GitHub activity:
245
+
246
+ 🟔 express
247
+ Increased issue activity
248
+ 8 issues opened recently
249
+ → Monitor for stability
250
+ GitHub: https://github.com/expressjs/express
251
+
252
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
253
+
172
254
  šŸ“¦ HEAVY PACKAGES (2)
173
255
 
174
256
  Packages larger than 1MB:
@@ -178,42 +260,37 @@ Detect restrictive licenses that may require legal review!
178
260
 
179
261
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
180
262
 
181
- āš–ļø LICENSE WARNINGS (1)
263
+ āœ… LICENSE COMPLIANCE
182
264
 
183
- sharp - Restrictive (LGPL-3.0)
265
+ All licenses are permissive!
184
266
 
185
267
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
186
268
 
187
269
  šŸ“Š PROJECT HEALTH
188
270
 
189
- Overall Score: 6.2/10
271
+ Overall Score: 8.5/10
190
272
  Total Dependencies: 25
191
- Security Vulnerabilities: 5
192
273
  Ecosystem Alerts: 1
274
+ Predictive Warnings: 1
193
275
  Unused: 0
194
- Outdated: 3
276
+ Outdated: 2
195
277
 
196
278
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
197
279
 
198
280
  šŸ’” QUICK WINS
199
281
 
200
- šŸ” Fix security vulnerabilities:
201
-
202
- npm audit fix
203
-
204
282
  šŸ”“ Fix critical issues:
205
283
 
206
284
  npm install axios@1.6.2
207
285
 
208
286
  Expected impact:
209
- āœ“ Resolve security vulnerabilities
210
287
  āœ“ Resolve critical stability issues
211
- āœ“ Improve health score → 8.7/10
288
+ āœ“ Improve health score → 10/10
212
289
 
213
290
  šŸ’” TIP: Run 'devcompass fix' to apply these fixes automatically!
214
291
  ```
215
292
 
216
- ## šŸš€ CI/CD Integration (v2.2)
293
+ ## šŸš€ CI/CD Integration
217
294
 
218
295
  ### JSON Output
219
296
  Perfect for parsing in CI/CD pipelines:
@@ -221,29 +298,45 @@ Perfect for parsing in CI/CD pipelines:
221
298
  devcompass analyze --json
222
299
  ```
223
300
 
224
- **Output (v2.3):**
301
+ **Output:**
225
302
  ```json
226
303
  {
227
- "version": "2.3.0",
228
- "timestamp": "2026-04-02T10:30:00.000Z",
304
+ "version": "2.4.0",
305
+ "timestamp": "2026-04-04T10:30:00.000Z",
229
306
  "summary": {
230
- "healthScore": 6.2,
307
+ "healthScore": 8.5,
231
308
  "totalDependencies": 25,
232
- "securityVulnerabilities": 5,
309
+ "securityVulnerabilities": 0,
233
310
  "ecosystemAlerts": 1,
311
+ "predictiveWarnings": 1,
234
312
  "unusedDependencies": 0,
235
- "outdatedPackages": 3,
313
+ "outdatedPackages": 2,
236
314
  "heavyPackages": 2,
237
- "licenseWarnings": 1
315
+ "licenseWarnings": 0
238
316
  },
239
317
  "security": {
240
- "total": 5,
241
- "critical": 1,
242
- "high": 2,
243
- "moderate": 2,
318
+ "total": 0,
319
+ "critical": 0,
320
+ "high": 0,
321
+ "moderate": 0,
244
322
  "low": 0,
245
- "vulnerabilities": [...]
323
+ "vulnerabilities": []
246
324
  },
325
+ "predictiveWarnings": [
326
+ {
327
+ "package": "express",
328
+ "severity": "medium",
329
+ "title": "Increased issue activity",
330
+ "description": "8 issues opened recently",
331
+ "recommendation": "Monitor for stability",
332
+ "githubData": {
333
+ "totalIssues": 234,
334
+ "recentIssues": 8,
335
+ "trend": "increasing",
336
+ "repoUrl": "https://github.com/expressjs/express"
337
+ }
338
+ }
339
+ ],
247
340
  "bundleAnalysis": {
248
341
  "heavyPackages": [
249
342
  { "name": "typescript", "size": "8.1 MB" },
@@ -251,12 +344,10 @@ devcompass analyze --json
251
344
  ]
252
345
  },
253
346
  "licenses": {
254
- "warnings": [
255
- { "package": "sharp", "license": "LGPL-3.0", "type": "restrictive" }
256
- ]
347
+ "warnings": []
257
348
  },
258
349
  "ecosystemAlerts": [...],
259
- "unusedDependencies": [...],
350
+ "unusedDependencies": [],
260
351
  "outdatedPackages": [...]
261
352
  }
262
353
  ```
@@ -293,16 +384,18 @@ devcompass analyze --silent
293
384
  echo $? # Check exit code
294
385
  ```
295
386
 
296
- ## ⚔ Smart Caching (v2.2)
387
+ ## ⚔ Smart Caching
297
388
 
298
389
  DevCompass caches results to improve performance:
299
390
 
300
- - **First run:** Normal speed (fetches all data)
301
- - **Cached runs:** ~70% faster
391
+ - **First run:** ~8 seconds (fetches GitHub + npm data)
392
+ - **Cached runs:** ~0.5 seconds (93% faster!)
302
393
  - **Cache duration:** 1 hour
303
394
  - **Cache file:** `.devcompass-cache.json` (auto-gitignored)
304
395
 
305
396
  **What gets cached:**
397
+ - GitHub issue data (NEW in v2.4.0)
398
+ - Predictive warnings (NEW in v2.4.0)
306
399
  - Security vulnerabilities
307
400
  - Ecosystem alerts
308
401
  - Unused dependencies
@@ -318,7 +411,7 @@ DevCompass caches results to improve performance:
318
411
  }
319
412
  ```
320
413
 
321
- ## šŸŽ›ļø Advanced Configuration (v2.2)
414
+ ## šŸŽ›ļø Advanced Configuration
322
415
 
323
416
  Create `devcompass.config.json` in your project root:
324
417
  ```json
@@ -373,7 +466,7 @@ Create `devcompass.config.json` in your project root:
373
466
  }
374
467
  ```
375
468
 
376
- ## šŸ”§ Auto-Fix Command (v2.1)
469
+ ## šŸ”§ Auto-Fix Command
377
470
 
378
471
  DevCompass can **automatically fix issues** in your project!
379
472
 
@@ -382,6 +475,7 @@ DevCompass can **automatically fix issues** in your project!
382
475
  - 🧹 **Removes unused dependencies** - Cleans up packages you're not using
383
476
  - ā¬†ļø **Safe updates** - Applies patch and minor updates automatically
384
477
  - āš ļø **Skips breaking changes** - Major updates require manual review
478
+ - šŸ”„ **Clears cache** - Ensures fresh analysis after fixes (NEW in v2.4.0)
385
479
 
386
480
  ### Usage
387
481
  ```bash
@@ -401,6 +495,7 @@ devcompass fix --path /path/to/project
401
495
  - āœ… Requires confirmation (unless `--yes` flag used)
402
496
  - āœ… Skips major updates (may have breaking changes)
403
497
  - āœ… Groups actions by priority (critical → cleanup → updates)
498
+ - āœ… Clears cache after fixes (NEW in v2.4.0)
404
499
  - āœ… Provides clear summary of changes
405
500
 
406
501
  ### Workflow Example
@@ -415,7 +510,7 @@ devcompass fix
415
510
  devcompass analyze
416
511
  ```
417
512
 
418
- ## 🚨 Ecosystem Intelligence (v2.0)
513
+ ## 🚨 Ecosystem Intelligence
419
514
 
420
515
  DevCompass tracks **real-world issues** in popular packages and warns you before they break production!
421
516
 
@@ -468,7 +563,7 @@ DevCompass won't flag these as unused (they're typically used in config files):
468
563
  - Shows current vs latest versions
469
564
  - Indicates update type (major/minor/patch)
470
565
 
471
- ### Health Score (Enhanced in v2.3)
566
+ ### Health Score
472
567
  Calculated from 0-10 based on:
473
568
  - Percentage of unused dependencies (āˆ’4 points per 100%)
474
569
  - Percentage of outdated packages (āˆ’3 points per 100%)
@@ -615,6 +710,8 @@ If you encounter a false positive, please [report it](https://github.com/AjayBTh
615
710
  8. **Use JSON output** - Integrate with your monitoring tools
616
711
  9. **Review major updates** - Always check changelogs before major version bumps
617
712
  10. **Verify before uninstalling** - DevCompass helps identify candidates, but always verify
713
+ 11. **Watch predictive warnings** - Monitor packages with increasing issue activity (NEW)
714
+ 12. **Cache for speed** - First run takes ~8s, cached runs ~0.5s (NEW)
618
715
 
619
716
  ## šŸ¤ Contributing
620
717
 
@@ -698,7 +795,7 @@ Check out DevCompass stats:
698
795
 
699
796
  ## 🌟 What's Next?
700
797
 
701
- ### Roadmap (v2.4+)
798
+ ### Roadmap
702
799
  - [x] ~~Automatic fix command~~ āœ… **Added in v2.1!**
703
800
  - [x] ~~CI/CD integration with JSON output~~ āœ… **Added in v2.2!**
704
801
  - [x] ~~Smart caching system~~ āœ… **Added in v2.2!**
@@ -706,13 +803,17 @@ Check out DevCompass stats:
706
803
  - [x] ~~npm audit integration~~ āœ… **Added in v2.3!**
707
804
  - [x] ~~Bundle size analysis~~ āœ… **Added in v2.3!**
708
805
  - [x] ~~License compliance checker~~ āœ… **Added in v2.3!**
709
- - [ ] GitHub Issues API for real-time issue tracking (v2.4.0)
710
- - [ ] Automated security patch suggestions (v2.4.0)
711
- - [ ] Dependency graph visualization (v2.5.0)
712
- - [ ] Web dashboard for team health monitoring (v2.5.0)
713
- - [ ] More tracked packages (React, Next.js, Vue, Angular) (v2.5.0)
714
- - [ ] Team collaboration features (v2.6.0)
715
- - [ ] Slack/Discord notifications (v2.6.0)
806
+ - [x] ~~Fix all security vulnerabilities~~ āœ… **Fixed in v2.3.1!**
807
+ - [x] ~~GitHub Issues API for real-time issue tracking~~ āœ… **Added in v2.4.0!**
808
+ - [x] ~~Predictive warnings based on bug activity~~ āœ… **Added in v2.4.0!**
809
+ - [ ] Expand to top 500 npm packages (v2.5.0)
810
+ - [ ] Performance optimizations (v2.6.0)
811
+ - [ ] Advanced security features with Snyk (v2.7.0)
812
+ - [ ] Enhanced fix command improvements (v2.8.0)
813
+ - [ ] Dependency graph visualization (v3.0.0)
814
+ - [ ] Web dashboard for team health monitoring (v3.0.0)
815
+ - [ ] Team collaboration features (v3.1.0)
816
+ - [ ] Slack/Discord notifications (v3.1.0)
716
817
 
717
818
  Want to contribute? Pick an item and open an issue! šŸš€
718
819
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "devcompass",
3
- "version": "2.3.0",
4
- "description": "Dependency health checker with ecosystem intelligence for JavaScript/TypeScript projects",
3
+ "version": "2.4.0",
4
+ "description": "Dependency health checker with ecosystem intelligence and real-time GitHub issue tracking for JavaScript/TypeScript projects",
5
5
  "main": "src/index.js",
6
6
  "bin": {
7
7
  "devcompass": "./bin/devcompass.js"
@@ -36,7 +36,12 @@
36
36
  "json-output",
37
37
  "npm-audit",
38
38
  "bundle-size",
39
- "license-checker"
39
+ "license-checker",
40
+ "github-issues",
41
+ "predictive-warnings",
42
+ "risk-detection",
43
+ "dependency-monitoring",
44
+ "issue-tracking"
40
45
  ],
41
46
  "author": "Ajay Thorat <ajaythorat988@gmail.com>",
42
47
  "license": "MIT",
@@ -44,7 +49,7 @@
44
49
  "chalk": "^4.1.2",
45
50
  "commander": "^11.1.0",
46
51
  "depcheck": "^1.4.7",
47
- "npm-check-updates": "^16.14.12",
52
+ "npm-check-updates": "^20.0.0",
48
53
  "ora": "^5.4.1",
49
54
  "semver": "^7.6.0"
50
55
  },
@@ -59,4 +64,4 @@
59
64
  "url": "https://github.com/AjayBThorat-20/devcompass/issues"
60
65
  },
61
66
  "homepage": "https://github.com/AjayBThorat-20/devcompass#readme"
62
- }
67
+ }
@@ -0,0 +1,177 @@
1
+ // src/alerts/github-tracker.js
2
+ const https = require('https');
3
+
4
+ // GitHub repos we track (you can expand this)
5
+ const TRACKED_REPOS = {
6
+ 'axios': 'axios/axios',
7
+ 'lodash': 'lodash/lodash',
8
+ 'moment': 'moment/moment',
9
+ 'express': 'expressjs/express',
10
+ 'react': 'facebook/react',
11
+ 'vue': 'vuejs/core',
12
+ 'next': 'vercel/next.js',
13
+ 'webpack': 'webpack/webpack',
14
+ 'typescript': 'microsoft/TypeScript',
15
+ 'eslint': 'eslint/eslint',
16
+ 'jest': 'jestjs/jest',
17
+ 'prettier': 'prettier/prettier',
18
+ 'node-fetch': 'node-fetch/node-fetch',
19
+ 'chalk': 'chalk/chalk'
20
+ };
21
+
22
+ /**
23
+ * Fetch GitHub issues for a package
24
+ */
25
+ async function fetchGitHubIssues(packageName) {
26
+ const repo = TRACKED_REPOS[packageName];
27
+
28
+ if (!repo) {
29
+ return null; // Not tracked
30
+ }
31
+
32
+ try {
33
+ const data = await makeGitHubRequest(`/repos/${repo}/issues`, {
34
+ state: 'open',
35
+ per_page: 100,
36
+ labels: 'bug'
37
+ });
38
+
39
+ return analyzeIssues(data, packageName);
40
+ } catch (error) {
41
+ console.error(`GitHub API error for ${packageName}:`, error.message);
42
+ return null;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Make GitHub API request
48
+ */
49
+ function makeGitHubRequest(path, params = {}) {
50
+ return new Promise((resolve, reject) => {
51
+ const queryString = Object.entries(params)
52
+ .map(([key, val]) => `${key}=${encodeURIComponent(val)}`)
53
+ .join('&');
54
+
55
+ const options = {
56
+ hostname: 'api.github.com',
57
+ path: `${path}?${queryString}`,
58
+ method: 'GET',
59
+ headers: {
60
+ 'User-Agent': 'DevCompass',
61
+ 'Accept': 'application/vnd.github.v3+json'
62
+ }
63
+ };
64
+
65
+ const req = https.request(options, (res) => {
66
+ let data = '';
67
+
68
+ res.on('data', (chunk) => {
69
+ data += chunk;
70
+ });
71
+
72
+ res.on('end', () => {
73
+ if (res.statusCode === 200) {
74
+ try {
75
+ resolve(JSON.parse(data));
76
+ } catch (error) {
77
+ reject(new Error('Failed to parse GitHub response'));
78
+ }
79
+ } else {
80
+ reject(new Error(`GitHub API returned ${res.statusCode}`));
81
+ }
82
+ });
83
+ });
84
+
85
+ req.on('error', reject);
86
+ req.end();
87
+ });
88
+ }
89
+
90
+ /**
91
+ * Analyze issues to detect trends
92
+ */
93
+ function analyzeIssues(issues, packageName) {
94
+ const now = Date.now();
95
+ const day = 24 * 60 * 60 * 1000;
96
+
97
+ // Count issues by recency
98
+ const last7Days = issues.filter(i =>
99
+ (now - new Date(i.created_at).getTime()) < 7 * day
100
+ ).length;
101
+
102
+ const last30Days = issues.filter(i =>
103
+ (now - new Date(i.created_at).getTime()) < 30 * day
104
+ ).length;
105
+
106
+ // Detect critical issues (high priority labels)
107
+ const criticalLabels = ['critical', 'security', 'regression', 'breaking'];
108
+ const criticalIssues = issues.filter(issue =>
109
+ issue.labels.some(label =>
110
+ criticalLabels.some(critical =>
111
+ label.name.toLowerCase().includes(critical)
112
+ )
113
+ )
114
+ );
115
+
116
+ // Calculate risk score
117
+ let riskScore = 0;
118
+ if (last7Days > 15) riskScore += 3;
119
+ else if (last7Days > 10) riskScore += 2;
120
+ else if (last7Days > 5) riskScore += 1;
121
+
122
+ if (criticalIssues.length > 5) riskScore += 2;
123
+ else if (criticalIssues.length > 2) riskScore += 1;
124
+
125
+ return {
126
+ package: packageName,
127
+ totalIssues: issues.length,
128
+ last7Days,
129
+ last30Days,
130
+ criticalIssues: criticalIssues.length,
131
+ riskScore,
132
+ trend: determineTrend(last7Days, last30Days),
133
+ repoUrl: `https://github.com/${TRACKED_REPOS[packageName]}`
134
+ };
135
+ }
136
+
137
+ /**
138
+ * Determine trend (increasing/stable/decreasing)
139
+ */
140
+ function determineTrend(last7Days, last30Days) {
141
+ const weeklyAverage = last30Days / 4;
142
+
143
+ if (last7Days > weeklyAverage * 1.5) {
144
+ return 'increasing';
145
+ } else if (last7Days < weeklyAverage * 0.5) {
146
+ return 'decreasing';
147
+ } else {
148
+ return 'stable';
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Check GitHub issues for multiple packages
154
+ */
155
+ async function checkGitHubIssues(packages) {
156
+ const results = [];
157
+
158
+ // Process in batches to avoid rate limits
159
+ for (const packageName of packages) {
160
+ const result = await fetchGitHubIssues(packageName);
161
+
162
+ if (result) {
163
+ results.push(result);
164
+ }
165
+
166
+ // Rate limit: wait 1 second between requests
167
+ await new Promise(resolve => setTimeout(resolve, 1000));
168
+ }
169
+
170
+ return results;
171
+ }
172
+
173
+ module.exports = {
174
+ checkGitHubIssues,
175
+ fetchGitHubIssues,
176
+ TRACKED_REPOS
177
+ };
@@ -1,54 +1,84 @@
1
1
  // src/alerts/predictive.js
2
+ const { checkGitHubIssues } = require('./github-tracker');
2
3
 
3
4
  /**
4
- * Analyze package health trends
5
- * NOTE: This is a simplified version without GitHub API
6
- * For production, integrate with GitHub Issues API
5
+ * Generate predictive warnings based on GitHub activity
7
6
  */
8
- async function analyzeTrends(packageName) {
9
- // Placeholder for future GitHub API integration
10
- // For now, return basic analysis
11
-
12
- return {
13
- package: packageName,
14
- recentIssues: 0,
15
- trend: 'stable',
16
- recommendation: null
17
- };
7
+ async function generatePredictiveWarnings(packages) {
8
+ try {
9
+ const packageNames = Object.keys(packages);
10
+ const githubData = await checkGitHubIssues(packageNames);
11
+
12
+ const warnings = [];
13
+
14
+ for (const data of githubData) {
15
+ // High risk: many recent issues
16
+ if (data.riskScore >= 3) {
17
+ warnings.push({
18
+ package: data.package,
19
+ severity: 'high',
20
+ type: 'predictive',
21
+ title: 'High bug activity detected',
22
+ description: `${data.last7Days} new issues in last 7 days`,
23
+ recommendation: 'Consider delaying upgrade or monitoring closely',
24
+ data: {
25
+ totalIssues: data.totalIssues,
26
+ recentIssues: data.last7Days,
27
+ criticalIssues: data.criticalIssues,
28
+ trend: data.trend,
29
+ repoUrl: data.repoUrl
30
+ }
31
+ });
32
+ }
33
+
34
+ // Medium risk: increasing trend
35
+ else if (data.riskScore >= 2 || data.trend === 'increasing') {
36
+ warnings.push({
37
+ package: data.package,
38
+ severity: 'medium',
39
+ type: 'predictive',
40
+ title: 'Increased issue activity',
41
+ description: `${data.last7Days} issues opened recently`,
42
+ recommendation: 'Monitor for stability',
43
+ data: {
44
+ totalIssues: data.totalIssues,
45
+ recentIssues: data.last7Days,
46
+ trend: data.trend,
47
+ repoUrl: data.repoUrl
48
+ }
49
+ });
50
+ }
51
+ }
52
+
53
+ return warnings;
54
+ } catch (error) {
55
+ console.error('Error generating predictive warnings:', error.message);
56
+ return [];
57
+ }
18
58
  }
19
59
 
20
60
  /**
21
- * Calculate risk score based on trends
61
+ * Calculate risk score for a package
22
62
  */
23
- function calculateRiskScore(trends) {
24
- let risk = 0;
63
+ function calculateRiskScore(githubData) {
64
+ let score = 0;
25
65
 
26
- // High issue activity = higher risk
27
- if (trends.recentIssues > 20) {
28
- risk += 3;
29
- } else if (trends.recentIssues > 10) {
30
- risk += 2;
31
- } else if (trends.recentIssues > 5) {
32
- risk += 1;
33
- }
66
+ // High recent activity
67
+ if (githubData.last7Days > 20) score += 3;
68
+ else if (githubData.last7Days > 10) score += 2;
69
+ else if (githubData.last7Days > 5) score += 1;
34
70
 
35
- return risk;
36
- }
37
-
38
- /**
39
- * Generate predictive warnings
40
- */
41
- function generatePredictiveWarnings(packages) {
42
- const warnings = [];
71
+ // Critical issues
72
+ if (githubData.criticalIssues > 5) score += 2;
73
+ else if (githubData.criticalIssues > 2) score += 1;
43
74
 
44
- // This is a placeholder
45
- // In production, this would analyze GitHub activity
75
+ // Trend
76
+ if (githubData.trend === 'increasing') score += 1;
46
77
 
47
- return warnings;
78
+ return score;
48
79
  }
49
80
 
50
81
  module.exports = {
51
- analyzeTrends,
52
- calculateRiskScore,
53
- generatePredictiveWarnings
82
+ generatePredictiveWarnings,
83
+ calculateRiskScore
54
84
  };
@@ -161,7 +161,7 @@ async function analyze(options) {
161
161
  }
162
162
  }
163
163
 
164
- // Check security vulnerabilities (NEW)
164
+ // Check security vulnerabilities
165
165
  spinner.text = 'Checking security vulnerabilities...';
166
166
  let securityData = { vulnerabilities: [], metadata: { total: 0, critical: 0, high: 0, moderate: 0, low: 0 } };
167
167
 
@@ -184,7 +184,32 @@ async function analyze(options) {
184
184
  }
185
185
  }
186
186
 
187
- // Analyze bundle sizes (NEW)
187
+ // Check for predictive warnings (GitHub Issues) - NEW
188
+ spinner.text = 'Checking GitHub activity...';
189
+ let predictiveWarnings = [];
190
+
191
+ if (config.cache) {
192
+ predictiveWarnings = getCached(projectPath, 'predictive');
193
+ }
194
+
195
+ if (!predictiveWarnings) {
196
+ try {
197
+ const { generatePredictiveWarnings } = require('../alerts/predictive');
198
+ predictiveWarnings = await generatePredictiveWarnings(dependencies);
199
+
200
+ if (config.cache && predictiveWarnings.length > 0) {
201
+ setCache(projectPath, 'predictive', predictiveWarnings);
202
+ }
203
+ } catch (error) {
204
+ if (outputMode !== 'silent') {
205
+ console.log(chalk.yellow('\nāš ļø Could not check GitHub activity'));
206
+ console.log(chalk.gray(` Error: ${error.message}\n`));
207
+ }
208
+ predictiveWarnings = [];
209
+ }
210
+ }
211
+
212
+ // Analyze bundle sizes
188
213
  spinner.text = 'Analyzing bundle sizes...';
189
214
  let bundleSizes = [];
190
215
 
@@ -204,7 +229,7 @@ async function analyze(options) {
204
229
  }
205
230
  }
206
231
 
207
- // Check licenses (NEW)
232
+ // Check licenses
208
233
  spinner.text = 'Checking licenses...';
209
234
  let licenses = [];
210
235
 
@@ -224,7 +249,7 @@ async function analyze(options) {
224
249
  }
225
250
  }
226
251
 
227
- // Calculate score (UPDATED)
252
+ // Calculate score
228
253
  const alertPenalty = calculateAlertPenalty(alerts);
229
254
  const securityPenalty = calculateSecurityPenalty(securityData.metadata);
230
255
 
@@ -241,15 +266,15 @@ async function analyze(options) {
241
266
 
242
267
  // Handle different output modes
243
268
  if (outputMode === 'json') {
244
- const jsonOutput = formatAsJson(alerts, unusedDeps, outdatedDeps, score, totalDeps, securityData, bundleSizes, licenses);
269
+ const jsonOutput = formatAsJson(alerts, unusedDeps, outdatedDeps, score, totalDeps, securityData, bundleSizes, licenses, predictiveWarnings);
245
270
  console.log(jsonOutput);
246
271
  } else if (outputMode === 'ci') {
247
- displayResults(alerts, unusedDeps, outdatedDeps, score, totalDeps, securityData, bundleSizes, licenses);
272
+ displayResults(alerts, unusedDeps, outdatedDeps, score, totalDeps, securityData, bundleSizes, licenses, predictiveWarnings);
248
273
  handleCiMode(score, config, alerts, unusedDeps);
249
274
  } else if (outputMode === 'silent') {
250
275
  // Silent mode - no output
251
276
  } else {
252
- displayResults(alerts, unusedDeps, outdatedDeps, score, totalDeps, securityData, bundleSizes, licenses);
277
+ displayResults(alerts, unusedDeps, outdatedDeps, score, totalDeps, securityData, bundleSizes, licenses, predictiveWarnings);
253
278
  }
254
279
 
255
280
  } catch (error) {
@@ -262,10 +287,10 @@ async function analyze(options) {
262
287
  }
263
288
  }
264
289
 
265
- function displayResults(alerts, unusedDeps, outdatedDeps, score, totalDeps, securityData, bundleSizes, licenses) {
290
+ function displayResults(alerts, unusedDeps, outdatedDeps, score, totalDeps, securityData, bundleSizes, licenses, predictiveWarnings) {
266
291
  logDivider();
267
292
 
268
- // SECURITY VULNERABILITIES (NEW SECTION)
293
+ // SECURITY VULNERABILITIES
269
294
  if (securityData.metadata.total > 0) {
270
295
  const criticalCount = securityData.metadata.critical;
271
296
  const highCount = securityData.metadata.high;
@@ -335,6 +360,33 @@ function displayResults(alerts, unusedDeps, outdatedDeps, score, totalDeps, secu
335
360
 
336
361
  logDivider();
337
362
 
363
+ // PREDICTIVE WARNINGS (NEW SECTION)
364
+ if (predictiveWarnings.length > 0) {
365
+ logSection('šŸ”® PREDICTIVE WARNINGS', predictiveWarnings.length);
366
+
367
+ log(chalk.gray(' Based on recent GitHub activity:\n'));
368
+
369
+ predictiveWarnings.forEach(warning => {
370
+ const display = getSeverityDisplay(warning.severity);
371
+
372
+ log(`${display.emoji} ${display.color(warning.package)}`);
373
+ log(` ${chalk.yellow(warning.title)}`);
374
+ log(` ${warning.description}`);
375
+ log(` ${chalk.cyan('→')} ${warning.recommendation}`);
376
+
377
+ if (warning.data && warning.data.repoUrl) {
378
+ log(chalk.gray(` GitHub: ${warning.data.repoUrl}`));
379
+ }
380
+
381
+ log('');
382
+ });
383
+ } else {
384
+ logSection('āœ… PREDICTIVE ANALYSIS');
385
+ log(chalk.green(' No unusual activity detected!\n'));
386
+ }
387
+
388
+ logDivider();
389
+
338
390
  // UNUSED DEPENDENCIES
339
391
  if (unusedDeps.length > 0) {
340
392
  logSection('šŸ”“ UNUSED DEPENDENCIES', unusedDeps.length);
@@ -376,7 +428,7 @@ function displayResults(alerts, unusedDeps, outdatedDeps, score, totalDeps, secu
376
428
 
377
429
  logDivider();
378
430
 
379
- // BUNDLE SIZE (NEW SECTION)
431
+ // BUNDLE SIZE
380
432
  const heavyPackages = findHeavyPackages(bundleSizes);
381
433
  if (heavyPackages.length > 0) {
382
434
  logSection('šŸ“¦ HEAVY PACKAGES', heavyPackages.length);
@@ -396,7 +448,7 @@ function displayResults(alerts, unusedDeps, outdatedDeps, score, totalDeps, secu
396
448
  logDivider();
397
449
  }
398
450
 
399
- // LICENSE WARNINGS (NEW SECTION - ALWAYS SHOW)
451
+ // LICENSE WARNINGS
400
452
  const problematicLicenses = findProblematicLicenses(licenses);
401
453
  if (problematicLicenses.length > 0) {
402
454
  logSection('āš–ļø LICENSE WARNINGS', problematicLicenses.length);
@@ -431,6 +483,10 @@ function displayResults(alerts, unusedDeps, outdatedDeps, score, totalDeps, secu
431
483
  log(` Ecosystem Alerts: ${chalk.red(alerts.length)}`);
432
484
  }
433
485
 
486
+ if (predictiveWarnings.length > 0) {
487
+ log(` Predictive Warnings: ${chalk.yellow(predictiveWarnings.length)}`);
488
+ }
489
+
434
490
  log(` Unused: ${chalk.red(unusedDeps.length)}`);
435
491
  log(` Outdated: ${chalk.yellow(outdatedDeps.length)}\n`);
436
492
 
@@ -3,11 +3,13 @@ const chalk = require('chalk');
3
3
  const ora = require('ora');
4
4
  const { execSync } = require('child_process');
5
5
  const readline = require('readline');
6
+ const path = require('path');
6
7
 
7
8
  const { findUnusedDeps } = require('../analyzers/unused-deps');
8
9
  const { findOutdatedDeps } = require('../analyzers/outdated');
9
10
  const { checkEcosystemAlerts } = require('../alerts');
10
11
  const { getSeverityDisplay } = require('../alerts/formatter');
12
+ const { clearCache } = require('../cache/manager');
11
13
 
12
14
  async function fix(options) {
13
15
  const projectPath = options.path || process.cwd();
@@ -22,7 +24,6 @@ async function fix(options) {
22
24
 
23
25
  try {
24
26
  const fs = require('fs');
25
- const path = require('path');
26
27
  const packageJsonPath = path.join(projectPath, 'package.json');
27
28
 
28
29
  if (!fs.existsSync(packageJsonPath)) {
@@ -52,7 +53,7 @@ async function fix(options) {
52
53
  spinner.succeed(chalk.green('Analysis complete!\n'));
53
54
 
54
55
  // Show what will be fixed
55
- await showFixPlan(criticalAlerts, unusedDeps, outdatedDeps, options);
56
+ await showFixPlan(criticalAlerts, unusedDeps, outdatedDeps, options, projectPath);
56
57
 
57
58
  } catch (error) {
58
59
  spinner.fail(chalk.red('Analysis failed'));
@@ -61,7 +62,7 @@ async function fix(options) {
61
62
  }
62
63
  }
63
64
 
64
- async function showFixPlan(criticalAlerts, unusedDeps, outdatedDeps, options) {
65
+ async function showFixPlan(criticalAlerts, unusedDeps, outdatedDeps, options, projectPath) {
65
66
  const actions = [];
66
67
 
67
68
  // Critical alerts
@@ -160,19 +161,19 @@ async function showFixPlan(criticalAlerts, unusedDeps, outdatedDeps, options) {
160
161
 
161
162
  // Confirm
162
163
  if (options.yes) {
163
- await applyFixes(actions);
164
+ await applyFixes(actions, projectPath);
164
165
  } else {
165
166
  const confirmed = await askConfirmation('\nā“ Apply these fixes?');
166
167
 
167
168
  if (confirmed) {
168
- await applyFixes(actions);
169
+ await applyFixes(actions, projectPath);
169
170
  } else {
170
171
  console.log(chalk.yellow('\nāš ļø Fix cancelled. No changes made.\n'));
171
172
  }
172
173
  }
173
174
  }
174
175
 
175
- async function applyFixes(actions) {
176
+ async function applyFixes(actions, projectPath) {
176
177
  console.log(chalk.cyan.bold('\nšŸ”§ Applying fixes...\n'));
177
178
 
178
179
  const spinner = ora('Processing...').start();
@@ -222,6 +223,11 @@ async function applyFixes(actions) {
222
223
  console.log(chalk.green.bold('\n✨ All fixes applied successfully!\n'));
223
224
  console.log(chalk.cyan('šŸ’” Run') + chalk.bold(' devcompass analyze ') + chalk.cyan('to see the new health score.\n'));
224
225
 
226
+ // Clear cache after fixes - ADDED
227
+ spinner.text = 'Clearing cache...';
228
+ clearCache(projectPath);
229
+ spinner.succeed(chalk.gray('Cache cleared'));
230
+
225
231
  } catch (error) {
226
232
  spinner.fail(chalk.red('Fix failed'));
227
233
  console.log(chalk.red(`\nāŒ Error: ${error.message}\n`));
@@ -244,4 +250,4 @@ function askConfirmation(question) {
244
250
  });
245
251
  }
246
252
 
247
- module.exports = { fix };
253
+ module.exports = { fix };
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  * Format analysis results as JSON
5
5
  */
6
- function formatAsJson(alerts, unusedDeps, outdatedDeps, score, totalDeps, securityData, bundleSizes, licenses) {
6
+ function formatAsJson(alerts, unusedDeps, outdatedDeps, score, totalDeps, securityData, bundleSizes, licenses, predictiveWarnings = []) {
7
7
  const problematicLicenses = licenses.filter(l => l.type === 'restrictive' || l.type === 'unknown');
8
8
  const heavyPackages = bundleSizes.filter(p => p.size > 1024);
9
9
 
@@ -15,6 +15,7 @@ function formatAsJson(alerts, unusedDeps, outdatedDeps, score, totalDeps, securi
15
15
  totalDependencies: totalDeps,
16
16
  securityVulnerabilities: securityData.metadata.total,
17
17
  ecosystemAlerts: alerts.length,
18
+ predictiveWarnings: predictiveWarnings.length,
18
19
  unusedDependencies: unusedDeps.length,
19
20
  outdatedPackages: outdatedDeps.length,
20
21
  heavyPackages: heavyPackages.length,
@@ -44,6 +45,14 @@ function formatAsJson(alerts, unusedDeps, outdatedDeps, score, totalDeps, securi
44
45
  source: alert.source,
45
46
  reported: alert.reported
46
47
  })),
48
+ predictiveWarnings: predictiveWarnings.map(warning => ({
49
+ package: warning.package,
50
+ severity: warning.severity,
51
+ title: warning.title,
52
+ description: warning.description,
53
+ recommendation: warning.recommendation,
54
+ githubData: warning.data
55
+ })),
47
56
  unusedDependencies: unusedDeps.map(dep => ({
48
57
  name: dep.name
49
58
  })),