git-repo-analyzer-test 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/.github/copilot-instructions.md +108 -0
  2. package/.idea/aianalyzer.iml +9 -0
  3. package/.idea/misc.xml +6 -0
  4. package/.idea/modules.xml +8 -0
  5. package/.idea/vcs.xml +6 -0
  6. package/API_REFERENCE.md +244 -0
  7. package/ENHANCEMENTS.md +282 -0
  8. package/README.md +179 -0
  9. package/USAGE.md +189 -0
  10. package/analysis.txt +0 -0
  11. package/bin/cli.js +135 -0
  12. package/docs/SONARCLOUD_ANALYSIS_COVERED.md +144 -0
  13. package/docs/SonarCloud_Presentation_Points.md +81 -0
  14. package/docs/UI_IMPROVEMENTS.md +117 -0
  15. package/package-lock_cmd.json +542 -0
  16. package/package.json +44 -0
  17. package/package_command.json +16 -0
  18. package/public/analysis-options.json +31 -0
  19. package/public/images/README.txt +2 -0
  20. package/public/images/rws-logo.png +0 -0
  21. package/public/index.html +2433 -0
  22. package/repositories.example.txt +17 -0
  23. package/sample-repos.txt +20 -0
  24. package/src/analyzers/accessibility.js +47 -0
  25. package/src/analyzers/cicd-enhanced.js +113 -0
  26. package/src/analyzers/codeReview-enhanced.js +599 -0
  27. package/src/analyzers/codeReview-enhanced.js:Zone.Identifier +3 -0
  28. package/src/analyzers/codeReview.js +171 -0
  29. package/src/analyzers/codeReview.js:Zone.Identifier +3 -0
  30. package/src/analyzers/documentation-enhanced.js +137 -0
  31. package/src/analyzers/performance-enhanced.js +747 -0
  32. package/src/analyzers/performance-enhanced.js:Zone.Identifier +3 -0
  33. package/src/analyzers/performance.js +211 -0
  34. package/src/analyzers/performance.js:Zone.Identifier +3 -0
  35. package/src/analyzers/performance_cmd.js +216 -0
  36. package/src/analyzers/quality-enhanced.js +386 -0
  37. package/src/analyzers/quality-enhanced.js:Zone.Identifier +3 -0
  38. package/src/analyzers/quality.js +92 -0
  39. package/src/analyzers/quality.js:Zone.Identifier +3 -0
  40. package/src/analyzers/security-enhanced.js +512 -0
  41. package/src/analyzers/security-enhanced.js:Zone.Identifier +3 -0
  42. package/src/analyzers/snyk-ai.js:Zone.Identifier +3 -0
  43. package/src/analyzers/sonarcloud.js +928 -0
  44. package/src/analyzers/vulnerability.js +185 -0
  45. package/src/analyzers/vulnerability.js:Zone.Identifier +3 -0
  46. package/src/cli.js:Zone.Identifier +3 -0
  47. package/src/config.js +43 -0
  48. package/src/core/analyzerEngine.js +68 -0
  49. package/src/core/reportGenerator.js +21 -0
  50. package/src/gemini.js +321 -0
  51. package/src/github/client.js +124 -0
  52. package/src/github/client.js:Zone.Identifier +3 -0
  53. package/src/index.js +93 -0
  54. package/src/index_cmd.js +130 -0
  55. package/src/openai.js +297 -0
  56. package/src/report/generator.js +459 -0
  57. package/src/report/generator_cmd.js +459 -0
  58. package/src/report/pdf-generator.js +387 -0
  59. package/src/report/pdf-generator.js:Zone.Identifier +3 -0
  60. package/src/server.js +431 -0
  61. package/src/server.js:Zone.Identifier +3 -0
  62. package/src/server_cmd.js +434 -0
  63. package/src/sonarcloud/client.js +365 -0
  64. package/src/sonarcloud/scanner.js +171 -0
  65. package/src.zip +0 -0
@@ -0,0 +1,17 @@
1
+ # Example: repositories.txt
2
+
3
+ Add repositories you want to analyze, one per line. Example:
4
+
5
+ facebook/react
6
+ google/angular
7
+ vuejs/vue
8
+ pytorch/pytorch
9
+ tensorflow/tensorflow
10
+ angular/angular
11
+ golang/go
12
+ kubernetes/kubernetes
13
+ nodejs/node
14
+ rust-lang/rust
15
+
16
+ # Save this file and run:
17
+ # npm run analyze -- batch repositories.txt --output-dir ./reports
@@ -0,0 +1,20 @@
1
+ facebook/react
2
+ google/angular
3
+ vuejs/vue
4
+ nodejs/node
5
+ torvalds/linux
6
+ kubernetes/kubernetes
7
+ tensorflow/tensorflow
8
+ pytorch/pytorch
9
+ golang/go
10
+ rust-lang/rust
11
+ microsoft/vscode
12
+ apache/kafka
13
+ elastic/elasticsearch
14
+ mongodb/mongo
15
+ redis/redis
16
+ docker/cli
17
+ ansible/ansible
18
+ jenkins-ci/jenkins
19
+ prometheus/prometheus
20
+ grafana/grafana
@@ -0,0 +1,47 @@
1
+ import OpenAI from "openai";
2
+ process.env.OPENAI_API_KEY="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";
3
+
4
+ const client = new OpenAI({
5
+ apiKey: process.env.OPENAI_API_KEY
6
+ });
7
+
8
+ export class AccessibilityAnalyzer {
9
+ async analyze(repoUrl) {
10
+ const prompt = `
11
+ You are an Accessibility expert (WCAG 2.1 AA).
12
+
13
+ Analyze the following GitHub repository:
14
+ ${repoUrl}
15
+
16
+ Check:
17
+ - Semantic HTML usage
18
+ - ARIA roles
19
+ - Forms (labels, inputs)
20
+ - Keyboard accessibility
21
+ - Images (alt text)
22
+ - Color contrast issues
23
+
24
+ Return JSON:
25
+ {
26
+ "score": 0-100,
27
+ "issues": [
28
+ {
29
+ "severity": "high|medium|low",
30
+ "issue": "...",
31
+ "file": "...",
32
+ "fix": "..."
33
+ }
34
+ ],
35
+ "summary": "..."
36
+ }
37
+ `;
38
+
39
+ const response = await client.chat.completions.create({
40
+ model: "gpt-4o-mini",
41
+ messages: [{ role: "user", content: prompt }],
42
+ temperature: 0.3
43
+ });
44
+ return response.choices[0].message.content;
45
+ // return JSON.parse(response.choices[0].message.content);
46
+ }
47
+ }
@@ -0,0 +1,113 @@
1
+ /**
2
+ * CI/CD & automation analyzer
3
+ * Checks for GitHub Actions workflows, branch protection signals, and automation health
4
+ */
5
+
6
+ export class CICDAnalyzer {
7
+ constructor(githubClient) {
8
+ this.client = githubClient;
9
+ }
10
+
11
+ async analyzeCICD(owner, repo) {
12
+ let workflows = [];
13
+ try {
14
+ const contents = await this.client.getRepositoryContents(owner, repo, '.github/workflows');
15
+ if (Array.isArray(contents)) workflows = contents.filter((f) => f.name && (f.name.endsWith('.yml') || f.name.endsWith('.yaml')));
16
+ } catch {
17
+ // no workflows
18
+ }
19
+
20
+ const workflowNames = workflows.map((f) => f.name || '');
21
+ const hasTest = workflowNames.some(
22
+ (n) => /test|ci|build|verify/i.test(n)
23
+ );
24
+ const hasLint = workflowNames.some(
25
+ (n) => /lint|format|check/i.test(n)
26
+ );
27
+ const hasRelease = workflowNames.some(
28
+ (n) => /release|deploy|publish/i.test(n)
29
+ );
30
+ const hasDependabot = workflowNames.some((n) => /dependabot|dependabot/i.test(n));
31
+
32
+ let dependabotConfig = false;
33
+ try {
34
+ const githubRoot = await this.client.getRepositoryContents(owner, repo, '.github');
35
+ const list = Array.isArray(githubRoot) ? githubRoot : [githubRoot];
36
+ dependabotConfig = list.some((f) => (f.name || '').toLowerCase() === 'dependabot.yml');
37
+ } catch {
38
+ // ignore
39
+ }
40
+
41
+ const repoData = await this.client.getRepository(owner, repo);
42
+ const defaultBranch = repoData.default_branch || 'main';
43
+ const hasBranchProtection = !!repoData.permissions?.admin; // we can't always see rules; use as hint
44
+ const isArchived = !!repoData.archived;
45
+
46
+ const checks = {
47
+ workflowCount: workflows.length,
48
+ hasTest,
49
+ hasLint,
50
+ hasRelease,
51
+ hasDependabot,
52
+ dependabotConfig,
53
+ defaultBranch,
54
+ isArchived,
55
+ workflowFiles: workflowNames,
56
+ };
57
+
58
+ const score = this.calculateScore(checks);
59
+ const rating = this.getRating(score);
60
+
61
+ return {
62
+ score,
63
+ rating,
64
+ checks,
65
+ recommendations: this.getRecommendations(checks),
66
+ summary: {
67
+ totalWorkflows: workflows.length,
68
+ categories: { test: hasTest, lint: hasLint, release: hasRelease },
69
+ },
70
+ };
71
+ }
72
+
73
+ calculateScore(checks) {
74
+ let s = 0;
75
+ if (checks.workflowCount > 0) s += 2;
76
+ if (checks.hasTest) s += 2.5;
77
+ if (checks.hasLint) s += 1.5;
78
+ if (checks.hasRelease) s += 1.5;
79
+ if (checks.dependabotConfig || checks.hasDependabot) s += 1;
80
+ if (checks.workflowCount >= 2) s += 0.5;
81
+ if (checks.isArchived) s = Math.max(0, s - 2);
82
+ return Math.min(10, Math.round(s * 10) / 10);
83
+ }
84
+
85
+ getRating(score) {
86
+ if (score >= 9) return 'A+';
87
+ if (score >= 8) return 'A';
88
+ if (score >= 7) return 'B+';
89
+ if (score >= 6) return 'B';
90
+ if (score >= 5) return 'C+';
91
+ if (score >= 4) return 'C';
92
+ return 'F';
93
+ }
94
+
95
+ getRecommendations(checks) {
96
+ const recs = [];
97
+ if (checks.workflowCount === 0) {
98
+ recs.push({ priority: 'HIGH', title: 'Add CI', action: 'Add GitHub Actions workflows for tests and linting.' });
99
+ } else {
100
+ if (!checks.hasTest) recs.push({ priority: 'HIGH', title: 'Add test workflow', action: 'Add a workflow that runs tests on push/PR.' });
101
+ if (!checks.hasLint) recs.push({ priority: 'MEDIUM', title: 'Add lint workflow', action: 'Add a workflow for linting/formatting checks.' });
102
+ }
103
+ if (!checks.dependabotConfig && !checks.hasDependabot) {
104
+ recs.push({ priority: 'MEDIUM', title: 'Enable Dependabot', action: 'Add .github/dependabot.yml or enable in repo settings.' });
105
+ }
106
+ if (checks.isArchived) {
107
+ recs.push({ priority: 'LOW', title: 'Repository archived', action: 'Consider unarchiving if the project is maintained.' });
108
+ }
109
+ return recs;
110
+ }
111
+ }
112
+
113
+ export default CICDAnalyzer;