monol-plugin-scout 2.1.3 → 4.1.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 (87) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +244 -0
  3. package/monol-plugin-scout-pkg/CLAUDE.md +125 -8
  4. package/monol-plugin-scout-pkg/api/mock/categories.json +81 -0
  5. package/monol-plugin-scout-pkg/api/mock/insights.json +111 -0
  6. package/monol-plugin-scout-pkg/api/mock/marketplace.json +501 -0
  7. package/monol-plugin-scout-pkg/api/mock/trending.json +96 -0
  8. package/monol-plugin-scout-pkg/commands/console.md +79 -0
  9. package/monol-plugin-scout-pkg/commands/frequency.md +32 -0
  10. package/monol-plugin-scout-pkg/commands/install.md +32 -0
  11. package/monol-plugin-scout-pkg/commands/priority.md +30 -0
  12. package/monol-plugin-scout-pkg/commands/quiet.md +32 -0
  13. package/monol-plugin-scout-pkg/commands/schedule.md +32 -0
  14. package/monol-plugin-scout-pkg/commands/scout.md +8 -5
  15. package/monol-plugin-scout-pkg/commands/skills.md +160 -0
  16. package/monol-plugin-scout-pkg/commands/team.md +32 -0
  17. package/monol-plugin-scout-pkg/commands/timing.md +32 -0
  18. package/monol-plugin-scout-pkg/commands/trust.md +85 -0
  19. package/monol-plugin-scout-pkg/commands/trusted-install.md +98 -0
  20. package/monol-plugin-scout-pkg/commands/uninstall.md +31 -0
  21. package/monol-plugin-scout-pkg/config.yaml +57 -0
  22. package/monol-plugin-scout-pkg/data/.cache/676d5ab664292155e5f509c69d4edae1 +10 -0
  23. package/monol-plugin-scout-pkg/data/.session +8 -0
  24. package/monol-plugin-scout-pkg/data/analytics.json +102 -0
  25. package/monol-plugin-scout-pkg/data/history.json +67 -11
  26. package/monol-plugin-scout-pkg/data/logs/scout.log +1 -0
  27. package/monol-plugin-scout-pkg/data/schedules.json +17 -0
  28. package/monol-plugin-scout-pkg/data/team.json +53 -0
  29. package/monol-plugin-scout-pkg/data/usage.json +100 -7
  30. package/monol-plugin-scout-pkg/docs/ARCHITECTURE.md +201 -0
  31. package/monol-plugin-scout-pkg/hooks/generate-insights.sh +102 -0
  32. package/monol-plugin-scout-pkg/hooks/hooks.json +36 -1
  33. package/monol-plugin-scout-pkg/hooks/on-session-end.sh +136 -0
  34. package/monol-plugin-scout-pkg/hooks/on-session-start.sh +43 -0
  35. package/monol-plugin-scout-pkg/hooks/on-stop.md +79 -0
  36. package/monol-plugin-scout-pkg/hooks/open-console.sh +111 -0
  37. package/monol-plugin-scout-pkg/hooks/open-dashboard.sh +61 -0
  38. package/monol-plugin-scout-pkg/hooks/track-usage.sh +59 -0
  39. package/monol-plugin-scout-pkg/lib/ai-recommender.sh +505 -0
  40. package/monol-plugin-scout-pkg/lib/cache.sh +194 -0
  41. package/monol-plugin-scout-pkg/lib/data-validator.sh +360 -0
  42. package/monol-plugin-scout-pkg/lib/error-handler.sh +296 -0
  43. package/monol-plugin-scout-pkg/lib/logger.sh +263 -0
  44. package/monol-plugin-scout-pkg/lib/plugin-manager.sh +239 -0
  45. package/monol-plugin-scout-pkg/lib/priority-scorer.sh +262 -0
  46. package/monol-plugin-scout-pkg/lib/profile-learner.sh +339 -0
  47. package/monol-plugin-scout-pkg/lib/project-analyzer.sh +281 -0
  48. package/monol-plugin-scout-pkg/lib/recommendation-controller.sh +290 -0
  49. package/monol-plugin-scout-pkg/lib/rejection-learner.sh +232 -0
  50. package/monol-plugin-scout-pkg/lib/scheduler.sh +275 -0
  51. package/monol-plugin-scout-pkg/lib/skill-scout.sh +729 -0
  52. package/monol-plugin-scout-pkg/lib/sync.sh +221 -0
  53. package/monol-plugin-scout-pkg/lib/team-learner.sh +450 -0
  54. package/monol-plugin-scout-pkg/lib/team-manager.sh +369 -0
  55. package/monol-plugin-scout-pkg/lib/trend-learner.sh +428 -0
  56. package/monol-plugin-scout-pkg/lib/trust-manager.sh +261 -0
  57. package/monol-plugin-scout-pkg/lib/trusted-installer.sh +738 -0
  58. package/monol-plugin-scout-pkg/plugin.json +3 -2
  59. package/monol-plugin-scout-pkg/skills/audit.md +6 -0
  60. package/monol-plugin-scout-pkg/skills/cleanup.md +6 -0
  61. package/monol-plugin-scout-pkg/skills/compare.md +6 -0
  62. package/monol-plugin-scout-pkg/skills/console.md +315 -0
  63. package/monol-plugin-scout-pkg/skills/explore.md +6 -0
  64. package/monol-plugin-scout-pkg/skills/fork.md +6 -0
  65. package/monol-plugin-scout-pkg/skills/frequency.md +93 -0
  66. package/monol-plugin-scout-pkg/skills/install.md +127 -0
  67. package/monol-plugin-scout-pkg/skills/priority.md +77 -0
  68. package/monol-plugin-scout-pkg/skills/quiet.md +73 -0
  69. package/monol-plugin-scout-pkg/skills/schedule.md +95 -0
  70. package/monol-plugin-scout-pkg/skills/scout.md +27 -17
  71. package/monol-plugin-scout-pkg/skills/skills.md +230 -0
  72. package/monol-plugin-scout-pkg/skills/team.md +117 -0
  73. package/monol-plugin-scout-pkg/skills/timing.md +97 -0
  74. package/monol-plugin-scout-pkg/skills/trust.md +120 -0
  75. package/monol-plugin-scout-pkg/skills/trusted-install.md +264 -0
  76. package/monol-plugin-scout-pkg/skills/uninstall.md +100 -0
  77. package/monol-plugin-scout-pkg/web/components/activity-chart.js +208 -0
  78. package/monol-plugin-scout-pkg/web/components/index.js +27 -0
  79. package/monol-plugin-scout-pkg/web/components/insight-card.js +365 -0
  80. package/monol-plugin-scout-pkg/web/components/overview.js +154 -0
  81. package/monol-plugin-scout-pkg/web/components/plugin-list.js +242 -0
  82. package/monol-plugin-scout-pkg/web/components/stats-card.js +126 -0
  83. package/monol-plugin-scout-pkg/web/components/team-list.js +346 -0
  84. package/monol-plugin-scout-pkg/web/console.html +2098 -0
  85. package/monol-plugin-scout-pkg/web/dashboard.html +2106 -0
  86. package/monol-plugin-scout-pkg/web/manifest.json +29 -0
  87. package/package.json +1 -1
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Scout Activity Chart Component
3
+ * 플러그인 활동 차트를 표시하는 컴포넌트
4
+ */
5
+
6
+ import { MonolComponent } from '/design-system/component-base.js';
7
+
8
+ export class ScoutActivityChart extends MonolComponent {
9
+ constructor(container, options = {}) {
10
+ super(container, options);
11
+ this.chart = null;
12
+ this.state = {
13
+ period: options.period || '7d',
14
+ data: options.data || null
15
+ };
16
+ }
17
+
18
+ async init() {
19
+ if (this.options.apiUrl) {
20
+ await this.fetchData();
21
+ }
22
+ this.render();
23
+ }
24
+
25
+ async fetchData() {
26
+ try {
27
+ const url = `${this.options.apiUrl}?period=${this.state.period}`;
28
+ const response = await fetch(url);
29
+ this.state.data = await response.json();
30
+ } catch (error) {
31
+ console.error('Failed to fetch activity data:', error);
32
+ }
33
+ }
34
+
35
+ render() {
36
+ this.container.innerHTML = this.html`
37
+ <div class="scout-activity-chart">
38
+ <div class="chart-header">
39
+ <h3 class="chart-title">${this.options.title || 'Plugin Activity'}</h3>
40
+ <div class="chart-controls">
41
+ <button class="period-btn ${this.state.period === '7d' ? 'active' : ''}" data-period="7d">7D</button>
42
+ <button class="period-btn ${this.state.period === '30d' ? 'active' : ''}" data-period="30d">30D</button>
43
+ <button class="period-btn ${this.state.period === '90d' ? 'active' : ''}" data-period="90d">90D</button>
44
+ </div>
45
+ </div>
46
+ <div class="chart-body">
47
+ <canvas id="${this.getCanvasId()}"></canvas>
48
+ </div>
49
+ </div>
50
+ `;
51
+
52
+ this.bindEvents();
53
+ this.renderChart();
54
+ }
55
+
56
+ getCanvasId() {
57
+ return `scout-chart-${this.options.id || Math.random().toString(36).substr(2, 9)}`;
58
+ }
59
+
60
+ renderChart() {
61
+ const canvas = this.container.querySelector('canvas');
62
+ if (!canvas) return;
63
+
64
+ // 기존 차트 파괴
65
+ if (this.chart) {
66
+ this.chart.destroy();
67
+ }
68
+
69
+ const ctx = canvas.getContext('2d');
70
+ const data = this.state.data || this.getMockData();
71
+
72
+ // MonolCharts 사용 가능하면 사용
73
+ if (window.MonolCharts) {
74
+ this.chart = MonolCharts.createLineChart(ctx, data.labels, [{
75
+ label: 'Plugin Usage',
76
+ data: data.values,
77
+ color: MonolCharts.colors.cyan
78
+ }]);
79
+ } else {
80
+ // 직접 Chart.js 사용
81
+ this.chart = new Chart(ctx, {
82
+ type: 'line',
83
+ data: {
84
+ labels: data.labels,
85
+ datasets: [{
86
+ label: 'Plugin Usage',
87
+ data: data.values,
88
+ borderColor: '#39c5cf',
89
+ backgroundColor: 'rgba(57, 197, 207, 0.1)',
90
+ fill: true,
91
+ tension: 0.4
92
+ }]
93
+ },
94
+ options: {
95
+ responsive: true,
96
+ maintainAspectRatio: false,
97
+ plugins: {
98
+ legend: { display: false }
99
+ },
100
+ scales: {
101
+ x: {
102
+ grid: { display: false },
103
+ ticks: { color: '#8b949e' }
104
+ },
105
+ y: {
106
+ grid: { color: '#30363d' },
107
+ ticks: { color: '#8b949e' },
108
+ beginAtZero: true
109
+ }
110
+ }
111
+ }
112
+ });
113
+ }
114
+ }
115
+
116
+ getMockData() {
117
+ const days = this.state.period === '7d' ? 7 : this.state.period === '30d' ? 30 : 90;
118
+ const labels = [];
119
+ const values = [];
120
+
121
+ for (let i = days - 1; i >= 0; i--) {
122
+ const d = new Date();
123
+ d.setDate(d.getDate() - i);
124
+ labels.push(d.toLocaleDateString('ko-KR', { month: 'short', day: 'numeric' }));
125
+ values.push(Math.floor(Math.random() * 100) + 20);
126
+ }
127
+
128
+ return { labels, values };
129
+ }
130
+
131
+ bindEvents() {
132
+ this.container.querySelectorAll('.period-btn').forEach(btn => {
133
+ btn.addEventListener('click', async () => {
134
+ this.state.period = btn.dataset.period;
135
+ if (this.options.apiUrl) {
136
+ await this.fetchData();
137
+ }
138
+ this.render();
139
+ this.emit('period-change', { period: this.state.period });
140
+ });
141
+ });
142
+ }
143
+
144
+ updateData(newData) {
145
+ this.state.data = newData;
146
+ this.renderChart();
147
+ }
148
+
149
+ destroy() {
150
+ if (this.chart) {
151
+ this.chart.destroy();
152
+ }
153
+ super.destroy();
154
+ }
155
+ }
156
+
157
+ // CSS 스타일
158
+ const style = document.createElement('style');
159
+ style.textContent = `
160
+ .scout-activity-chart {
161
+ background: var(--bg-secondary);
162
+ border: 1px solid var(--border-color);
163
+ border-radius: var(--radius-md, 8px);
164
+ overflow: hidden;
165
+ }
166
+ .scout-activity-chart .chart-header {
167
+ display: flex;
168
+ justify-content: space-between;
169
+ align-items: center;
170
+ padding: 16px;
171
+ border-bottom: 1px solid var(--border-color);
172
+ }
173
+ .scout-activity-chart .chart-title {
174
+ font-size: 14px;
175
+ font-weight: 600;
176
+ color: var(--text-primary);
177
+ }
178
+ .scout-activity-chart .chart-controls {
179
+ display: flex;
180
+ gap: 4px;
181
+ }
182
+ .scout-activity-chart .period-btn {
183
+ padding: 4px 10px;
184
+ background: var(--bg-tertiary);
185
+ border: 1px solid var(--border-color);
186
+ border-radius: 4px;
187
+ color: var(--text-secondary);
188
+ font-size: 11px;
189
+ cursor: pointer;
190
+ transition: all 0.2s;
191
+ }
192
+ .scout-activity-chart .period-btn:hover {
193
+ border-color: var(--accent-blue);
194
+ color: var(--text-primary);
195
+ }
196
+ .scout-activity-chart .period-btn.active {
197
+ background: var(--accent-blue);
198
+ border-color: var(--accent-blue);
199
+ color: white;
200
+ }
201
+ .scout-activity-chart .chart-body {
202
+ padding: 16px;
203
+ height: 250px;
204
+ }
205
+ `;
206
+ document.head.appendChild(style);
207
+
208
+ export default ScoutActivityChart;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Scout Components Index
3
+ * 모든 Scout 컴포넌트 export
4
+ */
5
+
6
+ export { ScoutStatsCard } from './stats-card.js';
7
+ export { ScoutPluginList } from './plugin-list.js';
8
+ export { ScoutActivityChart } from './activity-chart.js';
9
+ export { ScoutOverview } from './overview.js';
10
+ export { ScoutTeamList } from './team-list.js';
11
+ export { ScoutInsightCard } from './insight-card.js';
12
+
13
+ // 컴포넌트 레지스트리 등록
14
+ import { ComponentRegistry } from '/design-system/component-base.js';
15
+ import { ScoutStatsCard } from './stats-card.js';
16
+ import { ScoutPluginList } from './plugin-list.js';
17
+ import { ScoutActivityChart } from './activity-chart.js';
18
+ import { ScoutOverview } from './overview.js';
19
+ import { ScoutTeamList } from './team-list.js';
20
+ import { ScoutInsightCard } from './insight-card.js';
21
+
22
+ ComponentRegistry.register('scout-stats', ScoutStatsCard);
23
+ ComponentRegistry.register('scout-plugins', ScoutPluginList);
24
+ ComponentRegistry.register('scout-chart', ScoutActivityChart);
25
+ ComponentRegistry.register('scout-overview', ScoutOverview);
26
+ ComponentRegistry.register('scout-team-list', ScoutTeamList);
27
+ ComponentRegistry.register('scout-insight-card', ScoutInsightCard);
@@ -0,0 +1,365 @@
1
+ /**
2
+ * Scout Insight Card Component
3
+ * 인사이트 카드 컴포넌트
4
+ */
5
+
6
+ import { MonolComponent } from '/design-system/component-base.js';
7
+
8
+ export class ScoutInsightCard extends MonolComponent {
9
+ constructor(container, options = {}) {
10
+ super(container, options);
11
+ this.state = {
12
+ insights: options.insights || [],
13
+ selectedType: 'all',
14
+ loading: true
15
+ };
16
+ }
17
+
18
+ async init() {
19
+ if (this.options.apiUrl) {
20
+ await this.fetchInsights();
21
+ } else {
22
+ this.state.insights = this.getMockInsights();
23
+ }
24
+ this.state.loading = false;
25
+ this.render();
26
+ }
27
+
28
+ getMockInsights() {
29
+ return [
30
+ { id: 'ins-001', type: 'recommendation', title: 'Consider using TypeScript strict mode', description: 'Based on your codebase patterns, enabling strict mode could catch 15% more potential bugs.', impact: 'high', plugin: 'typescript-analyzer' },
31
+ { id: 'ins-002', type: 'warning', title: 'Unused dependencies detected', description: '3 packages in package.json are not imported anywhere: lodash, moment, axios.', impact: 'medium', plugin: 'dep-scanner' },
32
+ { id: 'ins-003', type: 'tip', title: 'New plugin available', description: 'code-reviewer v2.0 released with AI-powered suggestions. Compatible with your project.', impact: 'low', plugin: 'marketplace' },
33
+ { id: 'ins-004', type: 'recommendation', title: 'Optimize bundle size', description: 'Your bundle is 2.3MB. Consider code splitting for 40% size reduction.', impact: 'high', plugin: 'bundle-analyzer' },
34
+ { id: 'ins-005', type: 'tip', title: 'Team activity spike', description: 'Your team had 3x more sessions this week. Consider scheduling a knowledge share.', impact: 'low', plugin: 'team-insights' }
35
+ ];
36
+ }
37
+
38
+ async fetchInsights() {
39
+ try {
40
+ const response = await fetch(this.options.apiUrl);
41
+ this.state.insights = await response.json();
42
+ } catch (error) {
43
+ console.error('Failed to fetch insights:', error);
44
+ this.state.insights = this.getMockInsights();
45
+ }
46
+ }
47
+
48
+ getFilteredInsights() {
49
+ const { insights, selectedType } = this.state;
50
+ if (selectedType === 'all') return insights;
51
+ return insights.filter(i => i.type === selectedType);
52
+ }
53
+
54
+ render() {
55
+ const { loading, selectedType } = this.state;
56
+ const insights = this.getFilteredInsights();
57
+ const counts = {
58
+ all: this.state.insights.length,
59
+ recommendation: this.state.insights.filter(i => i.type === 'recommendation').length,
60
+ warning: this.state.insights.filter(i => i.type === 'warning').length,
61
+ tip: this.state.insights.filter(i => i.type === 'tip').length
62
+ };
63
+
64
+ if (loading) {
65
+ this.container.innerHTML = this.html`
66
+ <div class="scout-insight-card loading">
67
+ <div class="loading-spinner"></div>
68
+ </div>
69
+ `;
70
+ return;
71
+ }
72
+
73
+ this.container.innerHTML = this.html`
74
+ <div class="scout-insight-card">
75
+ <div class="card-header">
76
+ <h3>Insights</h3>
77
+ <span class="insight-count">${insights.length} active</span>
78
+ </div>
79
+ <div class="type-filters">
80
+ <button class="type-btn ${selectedType === 'all' ? 'active' : ''}" data-type="all">
81
+ All <span class="count">${counts.all}</span>
82
+ </button>
83
+ <button class="type-btn type-recommendation ${selectedType === 'recommendation' ? 'active' : ''}" data-type="recommendation">
84
+ &#x1F4A1; Recommendations <span class="count">${counts.recommendation}</span>
85
+ </button>
86
+ <button class="type-btn type-warning ${selectedType === 'warning' ? 'active' : ''}" data-type="warning">
87
+ &#x26A0;&#xFE0F; Warnings <span class="count">${counts.warning}</span>
88
+ </button>
89
+ <button class="type-btn type-tip ${selectedType === 'tip' ? 'active' : ''}" data-type="tip">
90
+ &#x2728; Tips <span class="count">${counts.tip}</span>
91
+ </button>
92
+ </div>
93
+ <div class="insight-items">
94
+ ${insights.length === 0
95
+ ? '<div class="empty-state">No insights available</div>'
96
+ : insights.map(i => this.renderInsight(i)).join('')}
97
+ </div>
98
+ </div>
99
+ `;
100
+
101
+ this.bindEvents();
102
+ }
103
+
104
+ renderInsight(insight) {
105
+ const typeIcon = {
106
+ 'recommendation': '&#x1F4A1;',
107
+ 'warning': '&#x26A0;&#xFE0F;',
108
+ 'tip': '&#x2728;'
109
+ }[insight.type] || '&#x1F4A1;';
110
+
111
+ const impactClass = {
112
+ 'high': 'impact-high',
113
+ 'medium': 'impact-medium',
114
+ 'low': 'impact-low'
115
+ }[insight.impact] || '';
116
+
117
+ return this.html`
118
+ <div class="insight-item type-${insight.type} ${impactClass}" data-id="${insight.id}">
119
+ <div class="insight-icon">${typeIcon}</div>
120
+ <div class="insight-content">
121
+ <div class="insight-title">${insight.title}</div>
122
+ <div class="insight-description">${insight.description}</div>
123
+ <div class="insight-meta">
124
+ <span class="insight-plugin">&#x1F50C; ${insight.plugin}</span>
125
+ <span class="insight-impact impact-badge-${insight.impact}">${insight.impact} impact</span>
126
+ </div>
127
+ </div>
128
+ <div class="insight-actions">
129
+ <button class="action-btn apply-btn" title="Apply">&#x2705;</button>
130
+ <button class="action-btn dismiss-btn" title="Dismiss">&#x274C;</button>
131
+ </div>
132
+ </div>
133
+ `;
134
+ }
135
+
136
+ bindEvents() {
137
+ // Type filter
138
+ this.container.querySelectorAll('.type-btn').forEach(btn => {
139
+ btn.addEventListener('click', () => {
140
+ this.state.selectedType = btn.dataset.type;
141
+ this.render();
142
+ });
143
+ });
144
+
145
+ // Insight actions
146
+ this.container.querySelectorAll('.insight-item').forEach(item => {
147
+ const id = item.dataset.id;
148
+ const insight = this.state.insights.find(i => i.id === id);
149
+
150
+ item.addEventListener('click', () => {
151
+ this.emit('insight-select', insight);
152
+ });
153
+
154
+ item.querySelector('.apply-btn')?.addEventListener('click', (e) => {
155
+ e.stopPropagation();
156
+ this.emit('insight-apply', insight);
157
+ // Remove from list
158
+ this.state.insights = this.state.insights.filter(i => i.id !== id);
159
+ this.render();
160
+ });
161
+
162
+ item.querySelector('.dismiss-btn')?.addEventListener('click', (e) => {
163
+ e.stopPropagation();
164
+ this.emit('insight-dismiss', insight);
165
+ // Remove from list
166
+ this.state.insights = this.state.insights.filter(i => i.id !== id);
167
+ this.render();
168
+ });
169
+ });
170
+ }
171
+ }
172
+
173
+ // CSS
174
+ const style = document.createElement('style');
175
+ style.textContent = `
176
+ .scout-insight-card {
177
+ background: var(--bg-secondary);
178
+ border: 1px solid var(--border-color);
179
+ border-radius: var(--radius-md, 8px);
180
+ padding: 16px;
181
+ }
182
+ .scout-insight-card.loading {
183
+ display: flex;
184
+ justify-content: center;
185
+ align-items: center;
186
+ min-height: 200px;
187
+ }
188
+ .scout-insight-card .loading-spinner {
189
+ width: 24px;
190
+ height: 24px;
191
+ border: 2px solid var(--border-color);
192
+ border-top-color: var(--accent-cyan);
193
+ border-radius: 50%;
194
+ animation: spin 1s linear infinite;
195
+ }
196
+ .scout-insight-card .card-header {
197
+ display: flex;
198
+ justify-content: space-between;
199
+ align-items: center;
200
+ margin-bottom: 12px;
201
+ }
202
+ .scout-insight-card .card-header h3 {
203
+ font-size: 14px;
204
+ font-weight: 600;
205
+ margin: 0;
206
+ }
207
+ .scout-insight-card .insight-count {
208
+ font-size: 12px;
209
+ color: var(--text-secondary);
210
+ }
211
+ .scout-insight-card .type-filters {
212
+ display: flex;
213
+ gap: 4px;
214
+ margin-bottom: 12px;
215
+ flex-wrap: wrap;
216
+ }
217
+ .scout-insight-card .type-btn {
218
+ padding: 6px 10px;
219
+ border: none;
220
+ background: var(--bg-tertiary);
221
+ border-radius: 16px;
222
+ font-size: 11px;
223
+ cursor: pointer;
224
+ color: var(--text-secondary);
225
+ transition: all 0.2s;
226
+ display: flex;
227
+ align-items: center;
228
+ gap: 4px;
229
+ }
230
+ .scout-insight-card .type-btn:hover {
231
+ color: var(--text-primary);
232
+ background: var(--bg-primary);
233
+ }
234
+ .scout-insight-card .type-btn.active {
235
+ background: var(--accent-cyan);
236
+ color: #000;
237
+ }
238
+ .scout-insight-card .type-btn.type-recommendation.active {
239
+ background: var(--accent-purple, #A371F7);
240
+ }
241
+ .scout-insight-card .type-btn.type-warning.active {
242
+ background: var(--accent-yellow, #FFE66D);
243
+ color: #000;
244
+ }
245
+ .scout-insight-card .type-btn.type-tip.active {
246
+ background: var(--accent-green);
247
+ color: #000;
248
+ }
249
+ .scout-insight-card .type-btn .count {
250
+ padding: 0 4px;
251
+ background: rgba(0,0,0,0.2);
252
+ border-radius: 8px;
253
+ font-size: 10px;
254
+ }
255
+ .scout-insight-card .insight-items {
256
+ display: flex;
257
+ flex-direction: column;
258
+ gap: 8px;
259
+ max-height: 350px;
260
+ overflow-y: auto;
261
+ }
262
+ .scout-insight-card .empty-state {
263
+ text-align: center;
264
+ padding: 32px;
265
+ color: var(--text-secondary);
266
+ font-size: 13px;
267
+ }
268
+ .scout-insight-card .insight-item {
269
+ display: flex;
270
+ align-items: flex-start;
271
+ gap: 12px;
272
+ padding: 12px;
273
+ background: var(--bg-tertiary);
274
+ border: 1px solid var(--border-color);
275
+ border-radius: 8px;
276
+ cursor: pointer;
277
+ transition: all 0.2s;
278
+ }
279
+ .scout-insight-card .insight-item:hover {
280
+ border-color: var(--accent-cyan);
281
+ }
282
+ .scout-insight-card .insight-item.type-recommendation {
283
+ border-left: 3px solid var(--accent-purple, #A371F7);
284
+ }
285
+ .scout-insight-card .insight-item.type-warning {
286
+ border-left: 3px solid var(--accent-yellow, #FFE66D);
287
+ }
288
+ .scout-insight-card .insight-item.type-tip {
289
+ border-left: 3px solid var(--accent-green);
290
+ }
291
+ .scout-insight-card .insight-item.impact-high {
292
+ background: rgba(255, 107, 107, 0.05);
293
+ }
294
+ .scout-insight-card .insight-icon {
295
+ font-size: 18px;
296
+ flex-shrink: 0;
297
+ padding-top: 2px;
298
+ }
299
+ .scout-insight-card .insight-content {
300
+ flex: 1;
301
+ min-width: 0;
302
+ }
303
+ .scout-insight-card .insight-title {
304
+ font-size: 13px;
305
+ font-weight: 500;
306
+ color: var(--text-primary);
307
+ margin-bottom: 4px;
308
+ }
309
+ .scout-insight-card .insight-description {
310
+ font-size: 12px;
311
+ color: var(--text-secondary);
312
+ line-height: 1.4;
313
+ margin-bottom: 6px;
314
+ }
315
+ .scout-insight-card .insight-meta {
316
+ display: flex;
317
+ gap: 12px;
318
+ font-size: 10px;
319
+ color: var(--text-muted);
320
+ }
321
+ .scout-insight-card .insight-plugin {
322
+ color: var(--text-secondary);
323
+ }
324
+ .scout-insight-card .insight-impact {
325
+ padding: 1px 6px;
326
+ border-radius: 4px;
327
+ font-weight: 500;
328
+ }
329
+ .scout-insight-card .impact-badge-high {
330
+ background: rgba(255, 107, 107, 0.2);
331
+ color: var(--accent-red, #FF6B6B);
332
+ }
333
+ .scout-insight-card .impact-badge-medium {
334
+ background: rgba(255, 230, 109, 0.2);
335
+ color: var(--accent-yellow, #FFE66D);
336
+ }
337
+ .scout-insight-card .impact-badge-low {
338
+ background: rgba(50, 205, 50, 0.2);
339
+ color: var(--accent-green);
340
+ }
341
+ .scout-insight-card .insight-actions {
342
+ display: flex;
343
+ gap: 4px;
344
+ opacity: 0;
345
+ transition: opacity 0.2s;
346
+ }
347
+ .scout-insight-card .insight-item:hover .insight-actions {
348
+ opacity: 1;
349
+ }
350
+ .scout-insight-card .action-btn {
351
+ background: none;
352
+ border: none;
353
+ cursor: pointer;
354
+ font-size: 12px;
355
+ padding: 4px 6px;
356
+ border-radius: 4px;
357
+ transition: all 0.2s;
358
+ }
359
+ .scout-insight-card .action-btn:hover {
360
+ background: var(--bg-primary);
361
+ }
362
+ `;
363
+ document.head.appendChild(style);
364
+
365
+ export default ScoutInsightCard;