@theihtisham/agent-shadow-brain 6.2.0 ā 7.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.
- package/CHANGELOG.md +411 -372
- package/LICENSE +21 -21
- package/README.md +428 -427
- package/dist/adapters/aider.js +13 -13
- package/dist/adapters/base-adapter.js +14 -14
- package/dist/adapters/codex.js +8 -8
- package/dist/adapters/roo-code.js +18 -18
- package/dist/brain/adr-engine.js +11 -11
- package/dist/brain/analyzer.js +30 -30
- package/dist/brain/auto-update.js +1 -1
- package/dist/brain/global-brain.d.ts +55 -46
- package/dist/brain/global-brain.d.ts.map +1 -1
- package/dist/brain/global-brain.js +586 -258
- package/dist/brain/global-brain.js.map +1 -1
- package/dist/brain/health-score.js +19 -19
- package/dist/brain/learning-engine.js +59 -59
- package/dist/brain/mcp-server.d.ts +2 -0
- package/dist/brain/mcp-server.d.ts.map +1 -1
- package/dist/brain/mcp-server.js +46 -5
- package/dist/brain/mcp-server.js.map +1 -1
- package/dist/brain/plugin-system.js +23 -23
- package/dist/brain/pr-generator.js +19 -19
- package/dist/brain/project-context.js +1 -1
- package/dist/brain/project-context.js.map +1 -1
- package/dist/brain/report-generator.js +270 -270
- package/dist/cli.js +105 -34
- package/dist/cli.js.map +1 -1
- package/dist/dashboard/server.js +2 -2
- package/dist/dashboard/server.js.map +1 -1
- package/dist/dashboard/v6-dashboard-html.d.ts +1 -1
- package/dist/dashboard/v6-dashboard-html.d.ts.map +1 -1
- package/dist/dashboard/v6-dashboard-html.js +10 -5
- package/dist/dashboard/v6-dashboard-html.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +50 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/watchers/git-watcher.d.ts.map +1 -1
- package/dist/watchers/git-watcher.js +1 -1
- package/dist/watchers/git-watcher.js.map +1 -1
- package/docs/launch/RELEASE_CHECKLIST_v7.0.0.md +24 -0
- package/docs/launch/RELEASE_NOTES_v7.0.0.md +44 -0
- package/package.json +17 -14
- package/docs/launch/README.md +0 -61
|
@@ -26,130 +26,130 @@ export class ReportGenerator {
|
|
|
26
26
|
const highCount = insights.filter(i => i.priority === 'high').length;
|
|
27
27
|
const mediumCount = insights.filter(i => i.priority === 'medium').length;
|
|
28
28
|
const gradeColor = health ? (health.overall >= 85 ? '#22c55e' : health.overall >= 70 ? '#eab308' : health.overall >= 50 ? '#f97316' : '#ef4444') : '#6b7280';
|
|
29
|
-
return `<!DOCTYPE html>
|
|
30
|
-
<html lang="en">
|
|
31
|
-
<head>
|
|
32
|
-
<meta charset="UTF-8">
|
|
33
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
34
|
-
<title>Shadow Brain Report ā ${context.name}</title>
|
|
35
|
-
<style>
|
|
36
|
-
* { margin:0; padding:0; box-sizing:border-box; }
|
|
37
|
-
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background:#0f0f1a; color:#e2e8f0; min-height:100vh; }
|
|
38
|
-
.header { background:linear-gradient(135deg, #1e1b4b 0%, #312e81 50%, #1e1b4b 100%); padding:32px 48px; border-bottom:1px solid #312e81; }
|
|
39
|
-
.header h1 { font-size:28px; font-weight:700; color:#a5b4fc; display:flex; align-items:center; gap:12px; }
|
|
40
|
-
.header .meta { color:#6b7280; font-size:14px; margin-top:8px; }
|
|
41
|
-
.container { max-width:1100px; margin:0 auto; padding:32px 48px; }
|
|
42
|
-
.score-card { background:linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); border:1px solid #312e81; border-radius:16px; padding:28px; margin-bottom:32px; display:grid; grid-template-columns:200px 1fr; gap:28px; }
|
|
43
|
-
.score-circle { width:140px; height:140px; border-radius:50%; border:6px solid ${gradeColor}; display:flex; flex-direction:column; align-items:center; justify-content:center; box-shadow:0 0 30px ${gradeColor}33; }
|
|
44
|
-
.score-number { font-size:42px; font-weight:800; color:${gradeColor}; line-height:1; }
|
|
45
|
-
.score-label { font-size:13px; color:#6b7280; margin-top:4px; }
|
|
46
|
-
.score-grade { font-size:22px; font-weight:700; color:${gradeColor}; margin-top:4px; }
|
|
47
|
-
.score-dims { display:grid; gap:12px; }
|
|
48
|
-
.dim-row { display:grid; grid-template-columns:120px 1fr 50px; align-items:center; gap:12px; }
|
|
49
|
-
.dim-name { font-size:13px; color:#94a3b8; }
|
|
50
|
-
.dim-bar { height:8px; background:#1e293b; border-radius:4px; overflow:hidden; }
|
|
51
|
-
.dim-fill { height:100%; border-radius:4px; transition:width .3s ease; }
|
|
52
|
-
.dim-val { font-size:13px; color:#94a3b8; text-align:right; }
|
|
53
|
-
.stats { display:grid; grid-template-columns:repeat(4, 1fr); gap:16px; margin-bottom:32px; }
|
|
54
|
-
.stat { background:#1a1a2e; border:1px solid #312e81; border-radius:12px; padding:20px; text-align:center; }
|
|
55
|
-
.stat-num { font-size:32px; font-weight:800; }
|
|
56
|
-
.stat-label { font-size:12px; color:#6b7280; margin-top:4px; }
|
|
57
|
-
.critical { color:#f87171; } .high { color:#fb923c; } .medium { color:#facc15; } .low { color:#4ade80; }
|
|
58
|
-
.section-title { font-size:18px; font-weight:600; color:#a5b4fc; margin-bottom:16px; display:flex; align-items:center; gap:8px; }
|
|
59
|
-
.insight-card { background:#1a1a2e; border:1px solid #1e293b; border-radius:12px; padding:20px; margin-bottom:12px; border-left:4px solid; }
|
|
60
|
-
.insight-card.critical { border-left-color:#f87171; }
|
|
61
|
-
.insight-card.high { border-left-color:#fb923c; }
|
|
62
|
-
.insight-card.medium { border-left-color:#facc15; }
|
|
63
|
-
.insight-card.low { border-left-color:#4ade80; }
|
|
64
|
-
.insight-header { display:flex; align-items:center; gap:10px; margin-bottom:10px; }
|
|
65
|
-
.badge { font-size:11px; font-weight:600; padding:3px 8px; border-radius:20px; text-transform:uppercase; }
|
|
66
|
-
.badge-critical { background:#7f1d1d; color:#fca5a5; }
|
|
67
|
-
.badge-high { background:#7c2d12; color:#fdba74; }
|
|
68
|
-
.badge-medium { background:#713f12; color:#fde047; }
|
|
69
|
-
.badge-low { background:#14532d; color:#86efac; }
|
|
70
|
-
.insight-title { font-size:15px; font-weight:600; color:#e2e8f0; }
|
|
71
|
-
.insight-content { color:#94a3b8; font-size:14px; line-height:1.6; }
|
|
72
|
-
.insight-files { margin-top:8px; display:flex; flex-wrap:wrap; gap:6px; }
|
|
73
|
-
.file-tag { background:#0f172a; border:1px solid #1e293b; border-radius:6px; padding:2px 8px; font-size:11px; font-family:monospace; color:#64748b; }
|
|
74
|
-
.fix-card { background:#0d1b0d; border:1px solid #14532d; border-radius:12px; padding:20px; margin-bottom:12px; }
|
|
75
|
-
.fix-label { font-size:11px; font-weight:600; color:#4ade80; text-transform:uppercase; margin-bottom:4px; }
|
|
76
|
-
pre { background:#0f0f1a; border:1px solid #1e293b; border-radius:8px; padding:14px; font-size:13px; overflow-x:auto; white-space:pre-wrap; }
|
|
77
|
-
pre.before { border-color:#7f1d1d; background:#1a0000; color:#fca5a5; }
|
|
78
|
-
pre.after { border-color:#14532d; background:#001a00; color:#86efac; }
|
|
79
|
-
.explanation { color:#64748b; font-size:13px; margin-top:10px; font-style:italic; }
|
|
80
|
-
.trend { font-size:13px; color:#6b7280; }
|
|
81
|
-
.trend.improving { color:#4ade80; }
|
|
82
|
-
.trend.declining { color:#f87171; }
|
|
83
|
-
footer { text-align:center; padding:32px; color:#374151; font-size:12px; border-top:1px solid #1e293b; margin-top:40px; }
|
|
84
|
-
</style>
|
|
85
|
-
</head>
|
|
86
|
-
<body>
|
|
87
|
-
<div class="header">
|
|
88
|
-
<h1>š§ Shadow Brain Report</h1>
|
|
89
|
-
<div class="meta">Project: <strong>${context.name}</strong> Ā· ${new Date().toLocaleString()} Ā· Branch: ${context.gitBranch || 'N/A'}</div>
|
|
90
|
-
</div>
|
|
91
|
-
<div class="container">
|
|
92
|
-
|
|
93
|
-
${health ? `
|
|
94
|
-
<div class="score-card">
|
|
95
|
-
<div class="score-circle">
|
|
96
|
-
<div class="score-number">${health.overall}</div>
|
|
97
|
-
<div class="score-label">out of 100</div>
|
|
98
|
-
<div class="score-grade">${health.grade}</div>
|
|
99
|
-
</div>
|
|
100
|
-
<div>
|
|
101
|
-
<div style="font-size:16px; font-weight:600; color:#e2e8f0; margin-bottom:4px;">Code Health Score</div>
|
|
102
|
-
<div class="trend ${health.trend}">Trend: ${health.trend === 'improving' ? 'ā Improving' : health.trend === 'declining' ? 'ā Declining' : 'ā Stable'}</div>
|
|
103
|
-
<div class="score-dims" style="margin-top:16px;">
|
|
29
|
+
return `<!DOCTYPE html>
|
|
30
|
+
<html lang="en">
|
|
31
|
+
<head>
|
|
32
|
+
<meta charset="UTF-8">
|
|
33
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
34
|
+
<title>Shadow Brain Report ā ${context.name}</title>
|
|
35
|
+
<style>
|
|
36
|
+
* { margin:0; padding:0; box-sizing:border-box; }
|
|
37
|
+
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background:#0f0f1a; color:#e2e8f0; min-height:100vh; }
|
|
38
|
+
.header { background:linear-gradient(135deg, #1e1b4b 0%, #312e81 50%, #1e1b4b 100%); padding:32px 48px; border-bottom:1px solid #312e81; }
|
|
39
|
+
.header h1 { font-size:28px; font-weight:700; color:#a5b4fc; display:flex; align-items:center; gap:12px; }
|
|
40
|
+
.header .meta { color:#6b7280; font-size:14px; margin-top:8px; }
|
|
41
|
+
.container { max-width:1100px; margin:0 auto; padding:32px 48px; }
|
|
42
|
+
.score-card { background:linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); border:1px solid #312e81; border-radius:16px; padding:28px; margin-bottom:32px; display:grid; grid-template-columns:200px 1fr; gap:28px; }
|
|
43
|
+
.score-circle { width:140px; height:140px; border-radius:50%; border:6px solid ${gradeColor}; display:flex; flex-direction:column; align-items:center; justify-content:center; box-shadow:0 0 30px ${gradeColor}33; }
|
|
44
|
+
.score-number { font-size:42px; font-weight:800; color:${gradeColor}; line-height:1; }
|
|
45
|
+
.score-label { font-size:13px; color:#6b7280; margin-top:4px; }
|
|
46
|
+
.score-grade { font-size:22px; font-weight:700; color:${gradeColor}; margin-top:4px; }
|
|
47
|
+
.score-dims { display:grid; gap:12px; }
|
|
48
|
+
.dim-row { display:grid; grid-template-columns:120px 1fr 50px; align-items:center; gap:12px; }
|
|
49
|
+
.dim-name { font-size:13px; color:#94a3b8; }
|
|
50
|
+
.dim-bar { height:8px; background:#1e293b; border-radius:4px; overflow:hidden; }
|
|
51
|
+
.dim-fill { height:100%; border-radius:4px; transition:width .3s ease; }
|
|
52
|
+
.dim-val { font-size:13px; color:#94a3b8; text-align:right; }
|
|
53
|
+
.stats { display:grid; grid-template-columns:repeat(4, 1fr); gap:16px; margin-bottom:32px; }
|
|
54
|
+
.stat { background:#1a1a2e; border:1px solid #312e81; border-radius:12px; padding:20px; text-align:center; }
|
|
55
|
+
.stat-num { font-size:32px; font-weight:800; }
|
|
56
|
+
.stat-label { font-size:12px; color:#6b7280; margin-top:4px; }
|
|
57
|
+
.critical { color:#f87171; } .high { color:#fb923c; } .medium { color:#facc15; } .low { color:#4ade80; }
|
|
58
|
+
.section-title { font-size:18px; font-weight:600; color:#a5b4fc; margin-bottom:16px; display:flex; align-items:center; gap:8px; }
|
|
59
|
+
.insight-card { background:#1a1a2e; border:1px solid #1e293b; border-radius:12px; padding:20px; margin-bottom:12px; border-left:4px solid; }
|
|
60
|
+
.insight-card.critical { border-left-color:#f87171; }
|
|
61
|
+
.insight-card.high { border-left-color:#fb923c; }
|
|
62
|
+
.insight-card.medium { border-left-color:#facc15; }
|
|
63
|
+
.insight-card.low { border-left-color:#4ade80; }
|
|
64
|
+
.insight-header { display:flex; align-items:center; gap:10px; margin-bottom:10px; }
|
|
65
|
+
.badge { font-size:11px; font-weight:600; padding:3px 8px; border-radius:20px; text-transform:uppercase; }
|
|
66
|
+
.badge-critical { background:#7f1d1d; color:#fca5a5; }
|
|
67
|
+
.badge-high { background:#7c2d12; color:#fdba74; }
|
|
68
|
+
.badge-medium { background:#713f12; color:#fde047; }
|
|
69
|
+
.badge-low { background:#14532d; color:#86efac; }
|
|
70
|
+
.insight-title { font-size:15px; font-weight:600; color:#e2e8f0; }
|
|
71
|
+
.insight-content { color:#94a3b8; font-size:14px; line-height:1.6; }
|
|
72
|
+
.insight-files { margin-top:8px; display:flex; flex-wrap:wrap; gap:6px; }
|
|
73
|
+
.file-tag { background:#0f172a; border:1px solid #1e293b; border-radius:6px; padding:2px 8px; font-size:11px; font-family:monospace; color:#64748b; }
|
|
74
|
+
.fix-card { background:#0d1b0d; border:1px solid #14532d; border-radius:12px; padding:20px; margin-bottom:12px; }
|
|
75
|
+
.fix-label { font-size:11px; font-weight:600; color:#4ade80; text-transform:uppercase; margin-bottom:4px; }
|
|
76
|
+
pre { background:#0f0f1a; border:1px solid #1e293b; border-radius:8px; padding:14px; font-size:13px; overflow-x:auto; white-space:pre-wrap; }
|
|
77
|
+
pre.before { border-color:#7f1d1d; background:#1a0000; color:#fca5a5; }
|
|
78
|
+
pre.after { border-color:#14532d; background:#001a00; color:#86efac; }
|
|
79
|
+
.explanation { color:#64748b; font-size:13px; margin-top:10px; font-style:italic; }
|
|
80
|
+
.trend { font-size:13px; color:#6b7280; }
|
|
81
|
+
.trend.improving { color:#4ade80; }
|
|
82
|
+
.trend.declining { color:#f87171; }
|
|
83
|
+
footer { text-align:center; padding:32px; color:#374151; font-size:12px; border-top:1px solid #1e293b; margin-top:40px; }
|
|
84
|
+
</style>
|
|
85
|
+
</head>
|
|
86
|
+
<body>
|
|
87
|
+
<div class="header">
|
|
88
|
+
<h1>š§ Shadow Brain Report</h1>
|
|
89
|
+
<div class="meta">Project: <strong>${context.name}</strong> Ā· ${new Date().toLocaleString()} Ā· Branch: ${context.gitBranch || 'N/A'}</div>
|
|
90
|
+
</div>
|
|
91
|
+
<div class="container">
|
|
92
|
+
|
|
93
|
+
${health ? `
|
|
94
|
+
<div class="score-card">
|
|
95
|
+
<div class="score-circle">
|
|
96
|
+
<div class="score-number">${health.overall}</div>
|
|
97
|
+
<div class="score-label">out of 100</div>
|
|
98
|
+
<div class="score-grade">${health.grade}</div>
|
|
99
|
+
</div>
|
|
100
|
+
<div>
|
|
101
|
+
<div style="font-size:16px; font-weight:600; color:#e2e8f0; margin-bottom:4px;">Code Health Score</div>
|
|
102
|
+
<div class="trend ${health.trend}">Trend: ${health.trend === 'improving' ? 'ā Improving' : health.trend === 'declining' ? 'ā Declining' : 'ā Stable'}</div>
|
|
103
|
+
<div class="score-dims" style="margin-top:16px;">
|
|
104
104
|
${health.dimensions.map(d => {
|
|
105
105
|
const fillColor = d.score >= 90 ? '#22c55e' : d.score >= 75 ? '#3b82f6' : d.score >= 55 ? '#eab308' : '#ef4444';
|
|
106
|
-
return `<div class="dim-row">
|
|
107
|
-
<div class="dim-name">${d.name}</div>
|
|
108
|
-
<div class="dim-bar"><div class="dim-fill" style="width:${d.score}%; background:${fillColor};"></div></div>
|
|
109
|
-
<div class="dim-val">${d.score}%</div>
|
|
106
|
+
return `<div class="dim-row">
|
|
107
|
+
<div class="dim-name">${d.name}</div>
|
|
108
|
+
<div class="dim-bar"><div class="dim-fill" style="width:${d.score}%; background:${fillColor};"></div></div>
|
|
109
|
+
<div class="dim-val">${d.score}%</div>
|
|
110
110
|
</div>`;
|
|
111
|
-
}).join('')}
|
|
112
|
-
</div>
|
|
113
|
-
</div>
|
|
114
|
-
</div>` : ''}
|
|
115
|
-
|
|
116
|
-
<div class="stats">
|
|
117
|
-
<div class="stat"><div class="stat-num critical">${criticalCount}</div><div class="stat-label">Critical</div></div>
|
|
118
|
-
<div class="stat"><div class="stat-num high">${highCount}</div><div class="stat-label">High Priority</div></div>
|
|
119
|
-
<div class="stat"><div class="stat-num medium">${mediumCount}</div><div class="stat-label">Medium</div></div>
|
|
120
|
-
<div class="stat"><div class="stat-num" style="color:#a5b4fc;">${insights.length}</div><div class="stat-label">Total Insights</div></div>
|
|
121
|
-
</div>
|
|
122
|
-
|
|
123
|
-
<div class="section-title">š Insights</div>
|
|
111
|
+
}).join('')}
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
</div>` : ''}
|
|
115
|
+
|
|
116
|
+
<div class="stats">
|
|
117
|
+
<div class="stat"><div class="stat-num critical">${criticalCount}</div><div class="stat-label">Critical</div></div>
|
|
118
|
+
<div class="stat"><div class="stat-num high">${highCount}</div><div class="stat-label">High Priority</div></div>
|
|
119
|
+
<div class="stat"><div class="stat-num medium">${mediumCount}</div><div class="stat-label">Medium</div></div>
|
|
120
|
+
<div class="stat"><div class="stat-num" style="color:#a5b4fc;">${insights.length}</div><div class="stat-label">Total Insights</div></div>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<div class="section-title">š Insights</div>
|
|
124
124
|
${insights.sort((a, b) => {
|
|
125
125
|
const order = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
126
126
|
return order[a.priority] - order[b.priority];
|
|
127
|
-
}).map(i => `
|
|
128
|
-
<div class="insight-card ${i.priority}">
|
|
129
|
-
<div class="insight-header">
|
|
130
|
-
<span class="badge badge-${i.priority}">${i.priority}</span>
|
|
131
|
-
<span class="badge" style="background:#1e293b;color:#64748b;">${i.type}</span>
|
|
132
|
-
<span class="insight-title">${i.title}</span>
|
|
133
|
-
</div>
|
|
134
|
-
<div class="insight-content">${i.content.replace(/\n/g, '<br>')}</div>
|
|
135
|
-
${i.files && i.files.length > 0 ? `<div class="insight-files">${i.files.map(f => `<span class="file-tag">${f}</span>`).join('')}</div>` : ''}
|
|
136
|
-
</div>`).join('')}
|
|
137
|
-
|
|
138
|
-
${fixes && fixes.length > 0 ? `
|
|
139
|
-
<div class="section-title" style="margin-top:32px;">š§ Smart Fix Suggestions</div>
|
|
140
|
-
${fixes.map(f => `
|
|
141
|
-
<div class="fix-card">
|
|
142
|
-
<div style="font-size:15px; font-weight:600; color:#86efac; margin-bottom:12px;">${f.issue}</div>
|
|
143
|
-
<div style="display:grid; grid-template-columns:1fr 1fr; gap:16px;">
|
|
144
|
-
<div><div class="fix-label">Before</div><pre class="before">${f.before}</pre></div>
|
|
145
|
-
<div><div class="fix-label">After</div><pre class="after">${f.after}</pre></div>
|
|
146
|
-
</div>
|
|
147
|
-
<div class="explanation">š” ${f.explanation}</div>
|
|
148
|
-
</div>`).join('')}` : ''}
|
|
149
|
-
|
|
150
|
-
</div>
|
|
151
|
-
<footer>Generated by <strong>Agent Shadow Brain</strong> Ā· @theihtisham/agent-shadow-brain Ā· <a href="https://github.com/theihtisham/agent-shadow-brain" style="color:#4ade80;">GitHub</a></footer>
|
|
152
|
-
</body>
|
|
127
|
+
}).map(i => `
|
|
128
|
+
<div class="insight-card ${i.priority}">
|
|
129
|
+
<div class="insight-header">
|
|
130
|
+
<span class="badge badge-${i.priority}">${i.priority}</span>
|
|
131
|
+
<span class="badge" style="background:#1e293b;color:#64748b;">${i.type}</span>
|
|
132
|
+
<span class="insight-title">${i.title}</span>
|
|
133
|
+
</div>
|
|
134
|
+
<div class="insight-content">${i.content.replace(/\n/g, '<br>')}</div>
|
|
135
|
+
${i.files && i.files.length > 0 ? `<div class="insight-files">${i.files.map(f => `<span class="file-tag">${f}</span>`).join('')}</div>` : ''}
|
|
136
|
+
</div>`).join('')}
|
|
137
|
+
|
|
138
|
+
${fixes && fixes.length > 0 ? `
|
|
139
|
+
<div class="section-title" style="margin-top:32px;">š§ Smart Fix Suggestions</div>
|
|
140
|
+
${fixes.map(f => `
|
|
141
|
+
<div class="fix-card">
|
|
142
|
+
<div style="font-size:15px; font-weight:600; color:#86efac; margin-bottom:12px;">${f.issue}</div>
|
|
143
|
+
<div style="display:grid; grid-template-columns:1fr 1fr; gap:16px;">
|
|
144
|
+
<div><div class="fix-label">Before</div><pre class="before">${f.before}</pre></div>
|
|
145
|
+
<div><div class="fix-label">After</div><pre class="after">${f.after}</pre></div>
|
|
146
|
+
</div>
|
|
147
|
+
<div class="explanation">š” ${f.explanation}</div>
|
|
148
|
+
</div>`).join('')}` : ''}
|
|
149
|
+
|
|
150
|
+
</div>
|
|
151
|
+
<footer>Generated by <strong>Agent Shadow Brain</strong> Ā· @theihtisham/agent-shadow-brain Ā· <a href="https://github.com/theihtisham/agent-shadow-brain" style="color:#4ade80;">GitHub</a></footer>
|
|
152
|
+
</body>
|
|
153
153
|
</html>`;
|
|
154
154
|
}
|
|
155
155
|
// āāā Markdown āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
@@ -225,161 +225,161 @@ export class ReportGenerator {
|
|
|
225
225
|
const hasPython = context.language?.some(l => l === 'Python');
|
|
226
226
|
const hasGo = context.language?.some(l => l === 'Go');
|
|
227
227
|
const hasRust = context.language?.some(l => l === 'Rust');
|
|
228
|
-
return `# .github/workflows/shadow-brain.yml
|
|
229
|
-
# Auto-generated by Agent Shadow Brain ā https://github.com/theihtisham/agent-shadow-brain
|
|
230
|
-
name: Shadow Brain CI
|
|
231
|
-
|
|
232
|
-
on:
|
|
233
|
-
push:
|
|
234
|
-
branches: [main, master, develop]
|
|
235
|
-
pull_request:
|
|
236
|
-
branches: [main, master]
|
|
237
|
-
|
|
238
|
-
permissions:
|
|
239
|
-
contents: read
|
|
240
|
-
pull-requests: write
|
|
241
|
-
|
|
242
|
-
jobs:
|
|
243
|
-
shadow-brain-review:
|
|
244
|
-
name: AI Code Review
|
|
245
|
-
runs-on: ubuntu-latest
|
|
246
|
-
steps:
|
|
247
|
-
- name: Checkout
|
|
248
|
-
uses: actions/checkout@v4
|
|
249
|
-
with:
|
|
250
|
-
fetch-depth: 0 # Need full history for git diff
|
|
251
|
-
|
|
252
|
-
- name: Setup Node.js
|
|
253
|
-
uses: actions/setup-node@v4
|
|
254
|
-
with:
|
|
255
|
-
node-version: '20'
|
|
256
|
-
|
|
257
|
-
- name: Install Shadow Brain
|
|
258
|
-
run: npm install -g @theihtisham/agent-shadow-brain
|
|
259
|
-
|
|
260
|
-
- name: Run Shadow Brain Review
|
|
261
|
-
run: |
|
|
262
|
-
shadow-brain review . \\
|
|
263
|
-
--provider ollama \\
|
|
264
|
-
--depth standard \\
|
|
265
|
-
--output json > shadow-brain-report.json
|
|
266
|
-
continue-on-error: true
|
|
267
|
-
|
|
268
|
-
- name: Upload Report
|
|
269
|
-
uses: actions/upload-artifact@v4
|
|
270
|
-
with:
|
|
271
|
-
name: shadow-brain-report
|
|
272
|
-
path: shadow-brain-report.json
|
|
273
|
-
|
|
274
|
-
- name: Comment PR
|
|
275
|
-
if: github.event_name == 'pull_request'
|
|
276
|
-
uses: actions/github-script@v7
|
|
277
|
-
with:
|
|
278
|
-
script: |
|
|
279
|
-
const fs = require('fs');
|
|
280
|
-
let report = {};
|
|
281
|
-
try { report = JSON.parse(fs.readFileSync('shadow-brain-report.json', 'utf8')); } catch {}
|
|
282
|
-
|
|
283
|
-
const critical = report.summary?.critical || 0;
|
|
284
|
-
const high = report.summary?.high || 0;
|
|
285
|
-
const score = report.health?.overall || 'N/A';
|
|
286
|
-
const grade = report.health?.grade || '';
|
|
287
|
-
const insightsText = (report.insights || []).slice(0, 5).map(i =>
|
|
288
|
-
\`- **[\${i.priority.toUpperCase()}]** \${i.title}\`
|
|
289
|
-
).join('\\n');
|
|
290
|
-
|
|
291
|
-
const body = \`## š§ Shadow Brain Review
|
|
292
|
-
|
|
293
|
-
| Metric | Value |
|
|
294
|
-
|--------|-------|
|
|
295
|
-
| Health Score | \${score}/100 (\${grade}) |
|
|
296
|
-
| Critical Issues | \${critical} |
|
|
297
|
-
| High Priority | \${high} |
|
|
298
|
-
|
|
299
|
-
**Top Insights:**
|
|
300
|
-
\${insightsText || 'No issues found!'}
|
|
301
|
-
|
|
302
|
-
_Generated by [Agent Shadow Brain](https://github.com/theihtisham/agent-shadow-brain)_\`;
|
|
303
|
-
|
|
304
|
-
github.rest.issues.createComment({
|
|
305
|
-
issue_number: context.issue.number,
|
|
306
|
-
owner: context.repo.owner,
|
|
307
|
-
repo: context.repo.repo,
|
|
308
|
-
body,
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
${hasNode ? `
|
|
312
|
-
lint-and-type-check:
|
|
313
|
-
name: Lint & Type Check
|
|
314
|
-
runs-on: ubuntu-latest
|
|
315
|
-
steps:
|
|
316
|
-
- uses: actions/checkout@v4
|
|
317
|
-
- uses: actions/setup-node@v4
|
|
318
|
-
with:
|
|
319
|
-
node-version: '20'
|
|
320
|
-
cache: 'npm'
|
|
321
|
-
- run: npm ci
|
|
322
|
-
- run: npm run build --if-present
|
|
323
|
-
- run: npm test --if-present
|
|
324
|
-
` : ''}${hasPython ? `
|
|
325
|
-
python-checks:
|
|
326
|
-
name: Python Checks
|
|
327
|
-
runs-on: ubuntu-latest
|
|
328
|
-
steps:
|
|
329
|
-
- uses: actions/checkout@v4
|
|
330
|
-
- uses: actions/setup-python@v5
|
|
331
|
-
with:
|
|
332
|
-
python-version: '3.12'
|
|
333
|
-
- run: pip install ruff mypy pytest
|
|
334
|
-
- run: ruff check .
|
|
335
|
-
- run: pytest --tb=short
|
|
336
|
-
` : ''}${hasGo ? `
|
|
337
|
-
go-checks:
|
|
338
|
-
name: Go Checks
|
|
339
|
-
runs-on: ubuntu-latest
|
|
340
|
-
steps:
|
|
341
|
-
- uses: actions/checkout@v4
|
|
342
|
-
- uses: actions/setup-go@v5
|
|
343
|
-
with:
|
|
344
|
-
go-version: '1.22'
|
|
345
|
-
- run: go vet ./...
|
|
346
|
-
- run: go test ./...
|
|
347
|
-
` : ''}${hasRust ? `
|
|
348
|
-
rust-checks:
|
|
349
|
-
name: Rust Checks
|
|
350
|
-
runs-on: ubuntu-latest
|
|
351
|
-
steps:
|
|
352
|
-
- uses: actions/checkout@v4
|
|
353
|
-
- uses: dtolnay/rust-toolchain@stable
|
|
354
|
-
with:
|
|
355
|
-
components: clippy
|
|
356
|
-
- run: cargo clippy -- -D warnings
|
|
357
|
-
- run: cargo test
|
|
228
|
+
return `# .github/workflows/shadow-brain.yml
|
|
229
|
+
# Auto-generated by Agent Shadow Brain ā https://github.com/theihtisham/agent-shadow-brain
|
|
230
|
+
name: Shadow Brain CI
|
|
231
|
+
|
|
232
|
+
on:
|
|
233
|
+
push:
|
|
234
|
+
branches: [main, master, develop]
|
|
235
|
+
pull_request:
|
|
236
|
+
branches: [main, master]
|
|
237
|
+
|
|
238
|
+
permissions:
|
|
239
|
+
contents: read
|
|
240
|
+
pull-requests: write
|
|
241
|
+
|
|
242
|
+
jobs:
|
|
243
|
+
shadow-brain-review:
|
|
244
|
+
name: AI Code Review
|
|
245
|
+
runs-on: ubuntu-latest
|
|
246
|
+
steps:
|
|
247
|
+
- name: Checkout
|
|
248
|
+
uses: actions/checkout@v4
|
|
249
|
+
with:
|
|
250
|
+
fetch-depth: 0 # Need full history for git diff
|
|
251
|
+
|
|
252
|
+
- name: Setup Node.js
|
|
253
|
+
uses: actions/setup-node@v4
|
|
254
|
+
with:
|
|
255
|
+
node-version: '20'
|
|
256
|
+
|
|
257
|
+
- name: Install Shadow Brain
|
|
258
|
+
run: npm install -g @theihtisham/agent-shadow-brain
|
|
259
|
+
|
|
260
|
+
- name: Run Shadow Brain Review
|
|
261
|
+
run: |
|
|
262
|
+
shadow-brain review . \\
|
|
263
|
+
--provider ollama \\
|
|
264
|
+
--depth standard \\
|
|
265
|
+
--output json > shadow-brain-report.json
|
|
266
|
+
continue-on-error: true
|
|
267
|
+
|
|
268
|
+
- name: Upload Report
|
|
269
|
+
uses: actions/upload-artifact@v4
|
|
270
|
+
with:
|
|
271
|
+
name: shadow-brain-report
|
|
272
|
+
path: shadow-brain-report.json
|
|
273
|
+
|
|
274
|
+
- name: Comment PR
|
|
275
|
+
if: github.event_name == 'pull_request'
|
|
276
|
+
uses: actions/github-script@v7
|
|
277
|
+
with:
|
|
278
|
+
script: |
|
|
279
|
+
const fs = require('fs');
|
|
280
|
+
let report = {};
|
|
281
|
+
try { report = JSON.parse(fs.readFileSync('shadow-brain-report.json', 'utf8')); } catch {}
|
|
282
|
+
|
|
283
|
+
const critical = report.summary?.critical || 0;
|
|
284
|
+
const high = report.summary?.high || 0;
|
|
285
|
+
const score = report.health?.overall || 'N/A';
|
|
286
|
+
const grade = report.health?.grade || '';
|
|
287
|
+
const insightsText = (report.insights || []).slice(0, 5).map(i =>
|
|
288
|
+
\`- **[\${i.priority.toUpperCase()}]** \${i.title}\`
|
|
289
|
+
).join('\\n');
|
|
290
|
+
|
|
291
|
+
const body = \`## š§ Shadow Brain Review
|
|
292
|
+
|
|
293
|
+
| Metric | Value |
|
|
294
|
+
|--------|-------|
|
|
295
|
+
| Health Score | \${score}/100 (\${grade}) |
|
|
296
|
+
| Critical Issues | \${critical} |
|
|
297
|
+
| High Priority | \${high} |
|
|
298
|
+
|
|
299
|
+
**Top Insights:**
|
|
300
|
+
\${insightsText || 'No issues found!'}
|
|
301
|
+
|
|
302
|
+
_Generated by [Agent Shadow Brain](https://github.com/theihtisham/agent-shadow-brain)_\`;
|
|
303
|
+
|
|
304
|
+
github.rest.issues.createComment({
|
|
305
|
+
issue_number: context.issue.number,
|
|
306
|
+
owner: context.repo.owner,
|
|
307
|
+
repo: context.repo.repo,
|
|
308
|
+
body,
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
${hasNode ? `
|
|
312
|
+
lint-and-type-check:
|
|
313
|
+
name: Lint & Type Check
|
|
314
|
+
runs-on: ubuntu-latest
|
|
315
|
+
steps:
|
|
316
|
+
- uses: actions/checkout@v4
|
|
317
|
+
- uses: actions/setup-node@v4
|
|
318
|
+
with:
|
|
319
|
+
node-version: '20'
|
|
320
|
+
cache: 'npm'
|
|
321
|
+
- run: npm ci
|
|
322
|
+
- run: npm run build --if-present
|
|
323
|
+
- run: npm test --if-present
|
|
324
|
+
` : ''}${hasPython ? `
|
|
325
|
+
python-checks:
|
|
326
|
+
name: Python Checks
|
|
327
|
+
runs-on: ubuntu-latest
|
|
328
|
+
steps:
|
|
329
|
+
- uses: actions/checkout@v4
|
|
330
|
+
- uses: actions/setup-python@v5
|
|
331
|
+
with:
|
|
332
|
+
python-version: '3.12'
|
|
333
|
+
- run: pip install ruff mypy pytest
|
|
334
|
+
- run: ruff check .
|
|
335
|
+
- run: pytest --tb=short
|
|
336
|
+
` : ''}${hasGo ? `
|
|
337
|
+
go-checks:
|
|
338
|
+
name: Go Checks
|
|
339
|
+
runs-on: ubuntu-latest
|
|
340
|
+
steps:
|
|
341
|
+
- uses: actions/checkout@v4
|
|
342
|
+
- uses: actions/setup-go@v5
|
|
343
|
+
with:
|
|
344
|
+
go-version: '1.22'
|
|
345
|
+
- run: go vet ./...
|
|
346
|
+
- run: go test ./...
|
|
347
|
+
` : ''}${hasRust ? `
|
|
348
|
+
rust-checks:
|
|
349
|
+
name: Rust Checks
|
|
350
|
+
runs-on: ubuntu-latest
|
|
351
|
+
steps:
|
|
352
|
+
- uses: actions/checkout@v4
|
|
353
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
354
|
+
with:
|
|
355
|
+
components: clippy
|
|
356
|
+
- run: cargo clippy -- -D warnings
|
|
357
|
+
- run: cargo test
|
|
358
358
|
` : ''}`;
|
|
359
359
|
}
|
|
360
360
|
generatePreCommitHook() {
|
|
361
|
-
return `#!/bin/sh
|
|
362
|
-
# .git/hooks/pre-commit ā Auto-generated by Shadow Brain
|
|
363
|
-
# Install: chmod +x .git/hooks/pre-commit
|
|
364
|
-
|
|
365
|
-
echo "\\nš§ Shadow Brain pre-commit review...\\n"
|
|
366
|
-
|
|
367
|
-
# Run shadow brain quick review
|
|
368
|
-
shadow-brain review . --depth quick --output text
|
|
369
|
-
|
|
370
|
-
# Ask if review found critical issues
|
|
371
|
-
CRITICAL=$(shadow-brain review . --depth quick --output json 2>/dev/null | node -e "try{const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));console.log(d.summary?.critical||0)}catch{console.log(0)}")
|
|
372
|
-
|
|
373
|
-
if [ "$CRITICAL" -gt "0" ]; then
|
|
374
|
-
echo "\\nšØ Shadow Brain found $CRITICAL critical issue(s). Commit anyway? [y/N]"
|
|
375
|
-
read -r answer
|
|
376
|
-
if [ "$answer" != "y" ] && [ "$answer" != "Y" ]; then
|
|
377
|
-
echo "Commit aborted."
|
|
378
|
-
exit 1
|
|
379
|
-
fi
|
|
380
|
-
fi
|
|
381
|
-
|
|
382
|
-
echo "ā Shadow Brain check complete\\n"
|
|
361
|
+
return `#!/bin/sh
|
|
362
|
+
# .git/hooks/pre-commit ā Auto-generated by Shadow Brain
|
|
363
|
+
# Install: chmod +x .git/hooks/pre-commit
|
|
364
|
+
|
|
365
|
+
echo "\\nš§ Shadow Brain pre-commit review...\\n"
|
|
366
|
+
|
|
367
|
+
# Run shadow brain quick review
|
|
368
|
+
shadow-brain review . --depth quick --output text
|
|
369
|
+
|
|
370
|
+
# Ask if review found critical issues
|
|
371
|
+
CRITICAL=$(shadow-brain review . --depth quick --output json 2>/dev/null | node -e "try{const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));console.log(d.summary?.critical||0)}catch{console.log(0)}")
|
|
372
|
+
|
|
373
|
+
if [ "$CRITICAL" -gt "0" ]; then
|
|
374
|
+
echo "\\nšØ Shadow Brain found $CRITICAL critical issue(s). Commit anyway? [y/N]"
|
|
375
|
+
read -r answer
|
|
376
|
+
if [ "$answer" != "y" ] && [ "$answer" != "Y" ]; then
|
|
377
|
+
echo "Commit aborted."
|
|
378
|
+
exit 1
|
|
379
|
+
fi
|
|
380
|
+
fi
|
|
381
|
+
|
|
382
|
+
echo "ā Shadow Brain check complete\\n"
|
|
383
383
|
`;
|
|
384
384
|
}
|
|
385
385
|
}
|