agentgui 1.0.524 → 1.0.526
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/lib/tool-manager.js +4 -4
- package/package.json +1 -1
- package/static/css/tools-popup.css +133 -33
- package/static/index.html +13 -2
- package/static/js/tools-manager.js +86 -12
- package/static/tools-ui-test.html +551 -0
package/lib/tool-manager.js
CHANGED
|
@@ -5,10 +5,10 @@ import path from 'path';
|
|
|
5
5
|
|
|
6
6
|
const isWindows = os.platform() === 'win32';
|
|
7
7
|
const TOOLS = [
|
|
8
|
-
{ id: 'gm-
|
|
9
|
-
{ id: 'gm-
|
|
10
|
-
{ id: 'gm-
|
|
11
|
-
{ id: 'gm-
|
|
8
|
+
{ id: 'gm-cc', name: 'gm-cc', pkg: '@anthropic-ai/claude-code', pluginId: 'gm-cc' },
|
|
9
|
+
{ id: 'gm-oc', name: 'gm-oc', pkg: 'opencode-ai', pluginId: 'gm-oc' },
|
|
10
|
+
{ id: 'gm-gc', name: 'gm-gc', pkg: '@google/gemini-cli', pluginId: 'gm' },
|
|
11
|
+
{ id: 'gm-kilo', name: 'gm-kilo', pkg: '@kilocode/cli', pluginId: 'gm-kilo' },
|
|
12
12
|
];
|
|
13
13
|
|
|
14
14
|
const statusCache = new Map();
|
package/package.json
CHANGED
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
background: var(--color-bg-secondary);
|
|
41
41
|
border-radius: 1rem;
|
|
42
42
|
width: 90%;
|
|
43
|
-
max-width:
|
|
43
|
+
max-width: 600px;
|
|
44
44
|
max-height: 80vh;
|
|
45
45
|
display: flex;
|
|
46
46
|
flex-direction: column;
|
|
@@ -49,21 +49,91 @@
|
|
|
49
49
|
font-family: system-ui, -apple-system, sans-serif;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
@media (max-width: 768px) {
|
|
53
|
+
.tools-popup-content {
|
|
54
|
+
max-width: 90vw;
|
|
55
|
+
width: 100%;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@media (max-width: 480px) {
|
|
60
|
+
.tools-popup-content {
|
|
61
|
+
max-width: 95vw;
|
|
62
|
+
width: 100%;
|
|
63
|
+
max-height: 85vh;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.tools-popup-header {
|
|
67
|
+
flex-direction: column;
|
|
68
|
+
align-items: flex-start;
|
|
69
|
+
gap: 0.5rem;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.tools-popup-header-controls {
|
|
73
|
+
width: 100%;
|
|
74
|
+
flex-wrap: wrap;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
52
78
|
.tools-popup-header {
|
|
53
79
|
display: flex;
|
|
54
80
|
justify-content: space-between;
|
|
55
81
|
align-items: center;
|
|
56
|
-
padding:
|
|
82
|
+
padding: 0.875rem 1.25rem;
|
|
57
83
|
flex-shrink: 0;
|
|
58
84
|
border-bottom: 1px solid var(--color-border);
|
|
85
|
+
gap: 0.75rem;
|
|
59
86
|
}
|
|
60
87
|
|
|
61
88
|
.tools-popup-header h2 {
|
|
62
89
|
margin: 0;
|
|
63
|
-
font-size:
|
|
90
|
+
font-size: 1rem;
|
|
64
91
|
font-weight: 700;
|
|
65
92
|
}
|
|
66
93
|
|
|
94
|
+
.tools-popup-header-controls {
|
|
95
|
+
display: flex;
|
|
96
|
+
align-items: center;
|
|
97
|
+
gap: 0.75rem;
|
|
98
|
+
flex-shrink: 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.tools-voice-toggle {
|
|
102
|
+
display: flex;
|
|
103
|
+
align-items: center;
|
|
104
|
+
gap: 0.5rem;
|
|
105
|
+
font-size: 0.8rem;
|
|
106
|
+
cursor: pointer;
|
|
107
|
+
user-select: none;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.tools-voice-toggle input {
|
|
111
|
+
width: 0.875rem;
|
|
112
|
+
height: 0.875rem;
|
|
113
|
+
cursor: pointer;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.tools-voice-selector {
|
|
117
|
+
padding: 0.35rem 0.5rem;
|
|
118
|
+
font-size: 0.75rem;
|
|
119
|
+
border-radius: 0.3rem;
|
|
120
|
+
border: 1px solid var(--color-border);
|
|
121
|
+
background: var(--color-bg-primary);
|
|
122
|
+
color: var(--color-text-primary);
|
|
123
|
+
cursor: pointer;
|
|
124
|
+
transition: border-color 0.2s;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.tools-voice-selector:hover {
|
|
128
|
+
border-color: var(--color-primary);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.tools-voice-selector:focus {
|
|
132
|
+
outline: none;
|
|
133
|
+
border-color: var(--color-primary);
|
|
134
|
+
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
|
|
135
|
+
}
|
|
136
|
+
|
|
67
137
|
.tools-popup-close {
|
|
68
138
|
background: none;
|
|
69
139
|
border: none;
|
|
@@ -83,9 +153,21 @@
|
|
|
83
153
|
flex: 1;
|
|
84
154
|
overflow-y: auto;
|
|
85
155
|
padding: 1rem;
|
|
86
|
-
display:
|
|
87
|
-
|
|
88
|
-
gap:
|
|
156
|
+
display: grid;
|
|
157
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
158
|
+
gap: 1rem;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@media (max-width: 768px) {
|
|
162
|
+
.tools-popup-scroll {
|
|
163
|
+
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@media (max-width: 480px) {
|
|
168
|
+
.tools-popup-scroll {
|
|
169
|
+
grid-template-columns: 1fr;
|
|
170
|
+
}
|
|
89
171
|
}
|
|
90
172
|
|
|
91
173
|
.tools-popup-scroll::-webkit-scrollbar {
|
|
@@ -106,43 +188,50 @@
|
|
|
106
188
|
}
|
|
107
189
|
|
|
108
190
|
.tool-item {
|
|
109
|
-
padding:
|
|
191
|
+
padding: 0.75rem;
|
|
110
192
|
border: 1px solid var(--color-border);
|
|
111
193
|
border-radius: 0.5rem;
|
|
112
194
|
background: var(--color-bg-primary);
|
|
113
195
|
display: flex;
|
|
114
196
|
flex-direction: column;
|
|
115
|
-
gap: 0.
|
|
197
|
+
gap: 0.375rem;
|
|
116
198
|
transition: border-color 0.2s, background-color 0.2s;
|
|
199
|
+
min-height: 120px;
|
|
200
|
+
justify-content: space-between;
|
|
117
201
|
}
|
|
118
202
|
|
|
119
203
|
.tool-item:hover {
|
|
120
204
|
border-color: var(--color-primary);
|
|
121
205
|
background: var(--color-bg-secondary);
|
|
206
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
122
207
|
}
|
|
123
208
|
|
|
124
209
|
.tool-header {
|
|
125
210
|
display: flex;
|
|
126
|
-
align-items:
|
|
127
|
-
gap: 0.
|
|
211
|
+
align-items: flex-start;
|
|
212
|
+
gap: 0.5rem;
|
|
128
213
|
justify-content: space-between;
|
|
214
|
+
flex-wrap: wrap;
|
|
129
215
|
}
|
|
130
216
|
|
|
131
217
|
.tool-name {
|
|
132
218
|
font-weight: 600;
|
|
133
|
-
font-size: 0.
|
|
219
|
+
font-size: 0.9rem;
|
|
134
220
|
flex: 1;
|
|
221
|
+
word-break: break-word;
|
|
135
222
|
}
|
|
136
223
|
|
|
137
224
|
.tool-status-indicator {
|
|
138
225
|
display: inline-flex;
|
|
139
226
|
align-items: center;
|
|
140
|
-
gap: 0.
|
|
141
|
-
font-size: 0.
|
|
142
|
-
padding: 0.
|
|
227
|
+
gap: 0.25rem;
|
|
228
|
+
font-size: 0.7rem;
|
|
229
|
+
padding: 0.2rem 0.4rem;
|
|
143
230
|
border-radius: 0.25rem;
|
|
144
231
|
background: var(--color-bg-tertiary);
|
|
145
232
|
color: var(--color-text-secondary);
|
|
233
|
+
white-space: nowrap;
|
|
234
|
+
flex-shrink: 0;
|
|
146
235
|
}
|
|
147
236
|
|
|
148
237
|
.tool-status-indicator.installed {
|
|
@@ -179,24 +268,28 @@
|
|
|
179
268
|
}
|
|
180
269
|
|
|
181
270
|
.tool-details {
|
|
182
|
-
font-size: 0.
|
|
271
|
+
font-size: 0.7rem;
|
|
183
272
|
color: var(--color-text-secondary);
|
|
184
|
-
display:
|
|
273
|
+
display: none;
|
|
185
274
|
align-items: center;
|
|
186
275
|
gap: 0.5rem;
|
|
276
|
+
line-height: 1.3;
|
|
277
|
+
max-height: 2.6em;
|
|
278
|
+
overflow: hidden;
|
|
187
279
|
}
|
|
188
280
|
|
|
189
281
|
.tool-progress-container {
|
|
190
282
|
display: flex;
|
|
191
283
|
flex-direction: column;
|
|
192
|
-
gap: 0.
|
|
284
|
+
gap: 0.15rem;
|
|
285
|
+
margin-top: 0.25rem;
|
|
193
286
|
}
|
|
194
287
|
|
|
195
288
|
.tool-progress-bar {
|
|
196
289
|
width: 100%;
|
|
197
|
-
height: 0.
|
|
290
|
+
height: 0.25rem;
|
|
198
291
|
background: var(--color-bg-tertiary);
|
|
199
|
-
border-radius: 0.
|
|
292
|
+
border-radius: 0.125rem;
|
|
200
293
|
overflow: hidden;
|
|
201
294
|
}
|
|
202
295
|
|
|
@@ -205,30 +298,31 @@
|
|
|
205
298
|
background: linear-gradient(90deg, #3b82f6, #2563eb);
|
|
206
299
|
width: 0%;
|
|
207
300
|
transition: width 0.3s ease;
|
|
208
|
-
border-radius: 0.
|
|
301
|
+
border-radius: 0.125rem;
|
|
209
302
|
}
|
|
210
303
|
|
|
211
304
|
.tool-progress-text {
|
|
212
|
-
font-size: 0.
|
|
305
|
+
font-size: 0.65rem;
|
|
213
306
|
color: var(--color-text-secondary);
|
|
214
307
|
}
|
|
215
308
|
|
|
216
309
|
.tool-actions {
|
|
217
310
|
display: flex;
|
|
218
|
-
gap: 0.
|
|
311
|
+
gap: 0.4rem;
|
|
219
312
|
flex-wrap: wrap;
|
|
313
|
+
margin-top: 0.25rem;
|
|
220
314
|
}
|
|
221
315
|
|
|
222
316
|
.tool-btn {
|
|
223
|
-
padding: 0.
|
|
317
|
+
padding: 0.35rem 0.65rem;
|
|
224
318
|
border: none;
|
|
225
|
-
border-radius: 0.
|
|
319
|
+
border-radius: 0.3rem;
|
|
226
320
|
cursor: pointer;
|
|
227
|
-
font-size: 0.
|
|
321
|
+
font-size: 0.7rem;
|
|
228
322
|
font-weight: 600;
|
|
229
323
|
transition: all 0.2s;
|
|
230
324
|
flex: 1;
|
|
231
|
-
min-width:
|
|
325
|
+
min-width: 60px;
|
|
232
326
|
white-space: nowrap;
|
|
233
327
|
}
|
|
234
328
|
|
|
@@ -259,12 +353,15 @@
|
|
|
259
353
|
}
|
|
260
354
|
|
|
261
355
|
.tool-error-message {
|
|
262
|
-
font-size: 0.
|
|
356
|
+
font-size: 0.65rem;
|
|
263
357
|
color: #ef4444;
|
|
264
358
|
background: rgba(239, 68, 68, 0.1);
|
|
265
|
-
padding: 0.
|
|
359
|
+
padding: 0.375rem;
|
|
266
360
|
border-radius: 0.25rem;
|
|
267
361
|
border-left: 2px solid #ef4444;
|
|
362
|
+
overflow: hidden;
|
|
363
|
+
text-overflow: ellipsis;
|
|
364
|
+
max-height: 1.5em;
|
|
268
365
|
}
|
|
269
366
|
|
|
270
367
|
.tools-popup-footer {
|
|
@@ -318,18 +415,21 @@
|
|
|
318
415
|
.tool-versions {
|
|
319
416
|
display: flex;
|
|
320
417
|
flex-direction: column;
|
|
321
|
-
gap: 0.
|
|
322
|
-
font-size: 0.
|
|
418
|
+
gap: 0.15rem;
|
|
419
|
+
font-size: 0.65rem;
|
|
323
420
|
color: var(--color-text-secondary);
|
|
324
|
-
background:
|
|
325
|
-
padding: 0
|
|
421
|
+
background: transparent;
|
|
422
|
+
padding: 0;
|
|
326
423
|
border-radius: 0.25rem;
|
|
424
|
+
line-height: 1.3;
|
|
327
425
|
}
|
|
328
426
|
|
|
329
427
|
.tool-version-item {
|
|
330
428
|
display: flex;
|
|
331
429
|
align-items: center;
|
|
332
|
-
gap: 0.
|
|
430
|
+
gap: 0.25rem;
|
|
431
|
+
overflow: hidden;
|
|
432
|
+
text-overflow: ellipsis;
|
|
333
433
|
}
|
|
334
434
|
|
|
335
435
|
.tool-version-item strong {
|
package/static/index.html
CHANGED
|
@@ -3125,8 +3125,19 @@
|
|
|
3125
3125
|
<div class="tools-popup" id="toolsPopup">
|
|
3126
3126
|
<div class="tools-popup-content" onclick="event.stopPropagation()">
|
|
3127
3127
|
<div class="tools-popup-header">
|
|
3128
|
-
<
|
|
3129
|
-
|
|
3128
|
+
<div style="display: flex; align-items: center; gap: 0.75rem; flex: 1;">
|
|
3129
|
+
<h2 style="margin: 0; font-size: 1rem;">Tools & Extensions</h2>
|
|
3130
|
+
</div>
|
|
3131
|
+
<div class="tools-popup-header-controls" style="display: flex; align-items: center; gap: 0.75rem; flex-shrink: 0;">
|
|
3132
|
+
<label class="tools-voice-toggle" style="display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; cursor: pointer; user-select: none;">
|
|
3133
|
+
<input type="checkbox" id="toolsAutoSpeakToggle" style="width: 1rem; height: 1rem; cursor: pointer;">
|
|
3134
|
+
<span>Auto-speak</span>
|
|
3135
|
+
</label>
|
|
3136
|
+
<select class="tools-voice-selector" id="toolsVoiceSelector" style="padding: 0.4rem 0.6rem; font-size: 0.8rem; border-radius: 0.3rem; border: 1px solid var(--color-border); background: var(--color-bg-primary); color: var(--color-text-primary); cursor: pointer;">
|
|
3137
|
+
<option value="default">Voice</option>
|
|
3138
|
+
</select>
|
|
3139
|
+
<button class="tools-popup-close" onclick="document.getElementById('toolsPopup').classList.remove('open')" style="background: none; border: none; color: var(--color-text-secondary); font-size: 1.5rem; cursor: pointer; padding: 0; line-height: 1; transition: color 0.2s;">×</button>
|
|
3140
|
+
</div>
|
|
3130
3141
|
</div>
|
|
3131
3142
|
<div class="tools-popup-scroll"></div>
|
|
3132
3143
|
<div class="tools-popup-footer">
|
|
@@ -13,9 +13,62 @@
|
|
|
13
13
|
if (!btn.contains(e.target) && !popup.contains(e.target)) closePopup();
|
|
14
14
|
});
|
|
15
15
|
window.addEventListener('ws-message', onWsMessage);
|
|
16
|
+
|
|
17
|
+
// Initialize voice controls
|
|
18
|
+
initVoiceControls();
|
|
16
19
|
refresh();
|
|
17
20
|
}
|
|
18
21
|
|
|
22
|
+
function initVoiceControls() {
|
|
23
|
+
var autoSpeakToggle = document.getElementById('toolsAutoSpeakToggle');
|
|
24
|
+
var voiceSelector = document.getElementById('toolsVoiceSelector');
|
|
25
|
+
|
|
26
|
+
if (!autoSpeakToggle || !voiceSelector) return;
|
|
27
|
+
|
|
28
|
+
// Load saved preferences
|
|
29
|
+
var savedAutoSpeak = localStorage.getItem('toolsAutoSpeak') === 'true';
|
|
30
|
+
var savedVoice = localStorage.getItem('toolsVoice') || 'default';
|
|
31
|
+
|
|
32
|
+
autoSpeakToggle.checked = savedAutoSpeak;
|
|
33
|
+
voiceSelector.value = savedVoice;
|
|
34
|
+
|
|
35
|
+
// Listen for voice list updates
|
|
36
|
+
window.addEventListener('ws-message', function(e) {
|
|
37
|
+
var data = e.detail;
|
|
38
|
+
if (data && data.type === 'voice_list') {
|
|
39
|
+
updateVoiceSelector(data.voices);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Save preferences on change
|
|
44
|
+
autoSpeakToggle.addEventListener('change', function() {
|
|
45
|
+
localStorage.setItem('toolsAutoSpeak', this.checked);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
voiceSelector.addEventListener('change', function() {
|
|
49
|
+
localStorage.setItem('toolsVoice', this.value);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function updateVoiceSelector(voices) {
|
|
54
|
+
var voiceSelector = document.getElementById('toolsVoiceSelector');
|
|
55
|
+
if (!voiceSelector || !voices || !Array.isArray(voices)) return;
|
|
56
|
+
|
|
57
|
+
var currentValue = voiceSelector.value;
|
|
58
|
+
voiceSelector.innerHTML = '<option value="default">Voice</option>';
|
|
59
|
+
|
|
60
|
+
voices.forEach(function(voice) {
|
|
61
|
+
var option = document.createElement('option');
|
|
62
|
+
option.value = voice;
|
|
63
|
+
option.textContent = voice;
|
|
64
|
+
voiceSelector.appendChild(option);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
if (voices.includes(currentValue)) {
|
|
68
|
+
voiceSelector.value = currentValue;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
19
72
|
function refresh() {
|
|
20
73
|
fetchTools();
|
|
21
74
|
}
|
|
@@ -200,42 +253,41 @@
|
|
|
200
253
|
if (!scroll) return;
|
|
201
254
|
|
|
202
255
|
if (tools.length === 0) {
|
|
203
|
-
scroll.innerHTML = '<div class="tool-empty-state"><div class="tool-empty-state-icon">⚙️</div><div class="tool-empty-state-text">No tools available</div></div>';
|
|
256
|
+
scroll.innerHTML = '<div class="tool-empty-state" style="grid-column: 1 / -1;"><div class="tool-empty-state-icon">⚙️</div><div class="tool-empty-state-text">No tools available</div></div>';
|
|
204
257
|
return;
|
|
205
258
|
}
|
|
206
259
|
|
|
207
260
|
scroll.innerHTML = tools.map(function(tool) {
|
|
208
261
|
var statusClass = getStatusClass(tool);
|
|
209
262
|
var isInstalling = tool.status === 'installing' || tool.status === 'updating';
|
|
210
|
-
var hasAction = !tool.installed || tool.hasUpdate || tool.status === 'failed';
|
|
211
263
|
var versionInfo = '';
|
|
212
264
|
if (tool.installedVersion || tool.publishedVersion) {
|
|
213
265
|
versionInfo = '<div class="tool-versions">';
|
|
214
266
|
if (tool.installedVersion) {
|
|
215
|
-
versionInfo += '<span class="tool-version-item">
|
|
267
|
+
versionInfo += '<span class="tool-version-item">v' + esc(tool.installedVersion) + '</span>';
|
|
216
268
|
}
|
|
217
|
-
if (tool.publishedVersion) {
|
|
218
|
-
versionInfo += '<span class="tool-version-item">
|
|
269
|
+
if (tool.publishedVersion && tool.installedVersion !== tool.publishedVersion) {
|
|
270
|
+
versionInfo += '<span class="tool-version-item">(v' + esc(tool.publishedVersion) + ' available)</span>';
|
|
219
271
|
}
|
|
220
272
|
versionInfo += '</div>';
|
|
221
273
|
}
|
|
222
274
|
|
|
223
275
|
return '<div class="tool-item">' +
|
|
276
|
+
'<div style="display: flex; flex-direction: column; gap: 0.3rem;">' +
|
|
224
277
|
'<div class="tool-header">' +
|
|
225
278
|
'<span class="tool-name">' + esc(tool.id) + '</span>' +
|
|
226
|
-
'
|
|
279
|
+
'</div>' +
|
|
280
|
+
'<div class="tool-status-indicator ' + statusClass + '">' +
|
|
227
281
|
'<span class="tool-status-dot"></span>' +
|
|
228
282
|
'<span>' + getStatusText(tool) + '</span>' +
|
|
229
|
-
'</span>' +
|
|
230
283
|
'</div>' +
|
|
231
284
|
versionInfo +
|
|
232
|
-
(tool.description ? '<div class="tool-details">' + esc(tool.description) + '</div>' : '') +
|
|
233
285
|
(isInstalling && tool.progress !== undefined ?
|
|
234
286
|
'<div class="tool-progress-container">' +
|
|
235
287
|
'<div class="tool-progress-bar"><div class="tool-progress-fill" style="width:' + Math.min(tool.progress, 100) + '%"></div></div>' +
|
|
236
|
-
'<div class="tool-progress-text">' + Math.floor(tool.progress) + '%</div>' +
|
|
237
288
|
'</div>' : '') +
|
|
238
|
-
(tool.error_message ? '<div class="tool-error-message">Error: ' + esc(tool.error_message.substring(0,
|
|
289
|
+
(tool.error_message ? '<div class="tool-error-message">Error: ' + esc(tool.error_message.substring(0, 40)) + '</div>' : '') +
|
|
290
|
+
'</div>' +
|
|
239
291
|
'<div class="tool-actions">' +
|
|
240
292
|
(tool.status === 'not_installed' ?
|
|
241
293
|
'<button class="tool-btn tool-btn-primary" onclick="window.toolsManager.install(\'' + tool.id + '\')" ' + (operationInProgress.has(tool.id) ? 'disabled' : '') + '>Install</button>' :
|
|
@@ -243,7 +295,7 @@
|
|
|
243
295
|
'<button class="tool-btn tool-btn-primary" onclick="window.toolsManager.update(\'' + tool.id + '\')" ' + (operationInProgress.has(tool.id) ? 'disabled' : '') + '>Update</button>' :
|
|
244
296
|
tool.status === 'failed' ?
|
|
245
297
|
'<button class="tool-btn tool-btn-primary" onclick="window.toolsManager.install(\'' + tool.id + '\')" ' + (operationInProgress.has(tool.id) ? 'disabled' : '') + '>Retry</button>' :
|
|
246
|
-
'<button class="tool-btn tool-btn-secondary" onclick="window.toolsManager.refresh()" ' + (isRefreshing ? 'disabled' : '') + '
|
|
298
|
+
'<button class="tool-btn tool-btn-secondary" onclick="window.toolsManager.refresh()" ' + (isRefreshing ? 'disabled' : '') + '>✓</button>'
|
|
247
299
|
) +
|
|
248
300
|
'</div>' +
|
|
249
301
|
'</div>';
|
|
@@ -306,6 +358,28 @@
|
|
|
306
358
|
},
|
|
307
359
|
install: function(toolId) { install(toolId); },
|
|
308
360
|
update: function(toolId) { update(toolId); },
|
|
309
|
-
updateAll: function() { updateAll(); }
|
|
361
|
+
updateAll: function() { updateAll(); },
|
|
362
|
+
getAutoSpeak: function() {
|
|
363
|
+
var toggle = document.getElementById('toolsAutoSpeakToggle');
|
|
364
|
+
return toggle ? toggle.checked : false;
|
|
365
|
+
},
|
|
366
|
+
getVoice: function() {
|
|
367
|
+
var selector = document.getElementById('toolsVoiceSelector');
|
|
368
|
+
return selector ? selector.value : 'default';
|
|
369
|
+
},
|
|
370
|
+
setAutoSpeak: function(value) {
|
|
371
|
+
var toggle = document.getElementById('toolsAutoSpeakToggle');
|
|
372
|
+
if (toggle) {
|
|
373
|
+
toggle.checked = value;
|
|
374
|
+
localStorage.setItem('toolsAutoSpeak', value);
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
setVoice: function(value) {
|
|
378
|
+
var selector = document.getElementById('toolsVoiceSelector');
|
|
379
|
+
if (selector && Array.from(selector.options).some(opt => opt.value === value)) {
|
|
380
|
+
selector.value = value;
|
|
381
|
+
localStorage.setItem('toolsVoice', value);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
310
384
|
};
|
|
311
385
|
})();
|
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
|
|
2
|
+
<!DOCTYPE html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Tools UI Redesign Test - Compact Grid Layout</title>
|
|
8
|
+
<style>
|
|
9
|
+
* { box-sizing: border-box; }
|
|
10
|
+
|
|
11
|
+
:root {
|
|
12
|
+
--color-primary: #3b82f6;
|
|
13
|
+
--color-primary-dark: #1e40af;
|
|
14
|
+
--color-bg-primary: #ffffff;
|
|
15
|
+
--color-bg-secondary: #f9fafb;
|
|
16
|
+
--color-bg-tertiary: #f3f4f6;
|
|
17
|
+
--color-text-primary: #111827;
|
|
18
|
+
--color-text-secondary: #6b7280;
|
|
19
|
+
--color-border: #e5e7eb;
|
|
20
|
+
--color-success: #10b981;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
html.dark {
|
|
24
|
+
--color-bg-primary: #111827;
|
|
25
|
+
--color-bg-secondary: #1f2937;
|
|
26
|
+
--color-bg-tertiary: #374151;
|
|
27
|
+
--color-text-primary: #f9fafb;
|
|
28
|
+
--color-text-secondary: #d1d5db;
|
|
29
|
+
--color-border: #374151;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
body {
|
|
33
|
+
margin: 0;
|
|
34
|
+
padding: 20px;
|
|
35
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
36
|
+
background: var(--color-bg-secondary);
|
|
37
|
+
color: var(--color-text-primary);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.test-container {
|
|
41
|
+
max-width: 1000px;
|
|
42
|
+
margin: 0 auto;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
h1 {
|
|
46
|
+
font-size: 2rem;
|
|
47
|
+
margin-bottom: 10px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.description {
|
|
51
|
+
color: var(--color-text-secondary);
|
|
52
|
+
margin-bottom: 30px;
|
|
53
|
+
font-size: 0.95rem;
|
|
54
|
+
line-height: 1.5;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.demo-section {
|
|
58
|
+
margin-bottom: 40px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.section-title {
|
|
62
|
+
font-size: 1.25rem;
|
|
63
|
+
font-weight: 600;
|
|
64
|
+
margin-bottom: 15px;
|
|
65
|
+
border-bottom: 2px solid var(--color-primary);
|
|
66
|
+
padding-bottom: 8px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* Tools popup styles */
|
|
70
|
+
.tools-popup-content {
|
|
71
|
+
background: var(--color-bg-secondary);
|
|
72
|
+
border-radius: 1rem;
|
|
73
|
+
width: 100%;
|
|
74
|
+
max-width: 600px;
|
|
75
|
+
display: flex;
|
|
76
|
+
flex-direction: column;
|
|
77
|
+
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.1);
|
|
78
|
+
color: var(--color-text-primary);
|
|
79
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
80
|
+
overflow: hidden;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.tools-popup-header {
|
|
84
|
+
display: flex;
|
|
85
|
+
justify-content: space-between;
|
|
86
|
+
align-items: center;
|
|
87
|
+
padding: 0.875rem 1.25rem;
|
|
88
|
+
flex-shrink: 0;
|
|
89
|
+
border-bottom: 1px solid var(--color-border);
|
|
90
|
+
gap: 0.75rem;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.tools-popup-header h2 {
|
|
94
|
+
margin: 0;
|
|
95
|
+
font-size: 1rem;
|
|
96
|
+
font-weight: 700;
|
|
97
|
+
flex: 1;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.tools-popup-header-controls {
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
gap: 0.75rem;
|
|
104
|
+
flex-shrink: 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.tools-voice-toggle {
|
|
108
|
+
display: flex;
|
|
109
|
+
align-items: center;
|
|
110
|
+
gap: 0.5rem;
|
|
111
|
+
font-size: 0.8rem;
|
|
112
|
+
cursor: pointer;
|
|
113
|
+
user-select: none;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.tools-voice-toggle input {
|
|
117
|
+
width: 0.875rem;
|
|
118
|
+
height: 0.875rem;
|
|
119
|
+
cursor: pointer;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.tools-voice-selector {
|
|
123
|
+
padding: 0.35rem 0.5rem;
|
|
124
|
+
font-size: 0.75rem;
|
|
125
|
+
border-radius: 0.3rem;
|
|
126
|
+
border: 1px solid var(--color-border);
|
|
127
|
+
background: var(--color-bg-primary);
|
|
128
|
+
color: var(--color-text-primary);
|
|
129
|
+
cursor: pointer;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.tools-popup-scroll {
|
|
133
|
+
flex: 1;
|
|
134
|
+
overflow-y: auto;
|
|
135
|
+
padding: 1rem;
|
|
136
|
+
display: grid;
|
|
137
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
138
|
+
gap: 1rem;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@media (max-width: 768px) {
|
|
142
|
+
.tools-popup-scroll {
|
|
143
|
+
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@media (max-width: 480px) {
|
|
148
|
+
.tools-popup-scroll {
|
|
149
|
+
grid-template-columns: 1fr;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.tools-popup-header {
|
|
153
|
+
flex-direction: column;
|
|
154
|
+
align-items: flex-start;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.tools-popup-header-controls {
|
|
158
|
+
width: 100%;
|
|
159
|
+
flex-wrap: wrap;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.tool-item {
|
|
164
|
+
padding: 0.75rem;
|
|
165
|
+
border: 1px solid var(--color-border);
|
|
166
|
+
border-radius: 0.5rem;
|
|
167
|
+
background: var(--color-bg-primary);
|
|
168
|
+
display: flex;
|
|
169
|
+
flex-direction: column;
|
|
170
|
+
gap: 0.375rem;
|
|
171
|
+
transition: border-color 0.2s, background-color 0.2s;
|
|
172
|
+
min-height: 120px;
|
|
173
|
+
justify-content: space-between;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.tool-item:hover {
|
|
177
|
+
border-color: var(--color-primary);
|
|
178
|
+
background: var(--color-bg-secondary);
|
|
179
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.tool-header {
|
|
183
|
+
display: flex;
|
|
184
|
+
align-items: flex-start;
|
|
185
|
+
gap: 0.5rem;
|
|
186
|
+
justify-content: space-between;
|
|
187
|
+
flex-wrap: wrap;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.tool-name {
|
|
191
|
+
font-weight: 600;
|
|
192
|
+
font-size: 0.9rem;
|
|
193
|
+
flex: 1;
|
|
194
|
+
word-break: break-word;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.tool-status-indicator {
|
|
198
|
+
display: inline-flex;
|
|
199
|
+
align-items: center;
|
|
200
|
+
gap: 0.25rem;
|
|
201
|
+
font-size: 0.7rem;
|
|
202
|
+
padding: 0.2rem 0.4rem;
|
|
203
|
+
border-radius: 0.25rem;
|
|
204
|
+
background: var(--color-bg-tertiary);
|
|
205
|
+
color: var(--color-text-secondary);
|
|
206
|
+
white-space: nowrap;
|
|
207
|
+
flex-shrink: 0;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.tool-status-indicator.installed {
|
|
211
|
+
background: rgba(16, 185, 129, 0.15);
|
|
212
|
+
color: #10b981;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.tool-status-indicator.needs_update {
|
|
216
|
+
background: rgba(245, 158, 11, 0.15);
|
|
217
|
+
color: #f59e0b;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.tool-status-indicator.not_installed {
|
|
221
|
+
background: rgba(107, 114, 128, 0.15);
|
|
222
|
+
color: #9ca3af;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.tool-status-dot {
|
|
226
|
+
width: 0.375rem;
|
|
227
|
+
height: 0.375rem;
|
|
228
|
+
border-radius: 50%;
|
|
229
|
+
background: currentColor;
|
|
230
|
+
display: inline-block;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.tool-versions {
|
|
234
|
+
display: flex;
|
|
235
|
+
flex-direction: column;
|
|
236
|
+
gap: 0.15rem;
|
|
237
|
+
font-size: 0.65rem;
|
|
238
|
+
color: var(--color-text-secondary);
|
|
239
|
+
line-height: 1.3;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.tool-version-item {
|
|
243
|
+
display: flex;
|
|
244
|
+
align-items: center;
|
|
245
|
+
gap: 0.25rem;
|
|
246
|
+
overflow: hidden;
|
|
247
|
+
text-overflow: ellipsis;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.tool-actions {
|
|
251
|
+
display: flex;
|
|
252
|
+
gap: 0.4rem;
|
|
253
|
+
flex-wrap: wrap;
|
|
254
|
+
margin-top: 0.25rem;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.tool-btn {
|
|
258
|
+
padding: 0.35rem 0.65rem;
|
|
259
|
+
border: none;
|
|
260
|
+
border-radius: 0.3rem;
|
|
261
|
+
cursor: pointer;
|
|
262
|
+
font-size: 0.7rem;
|
|
263
|
+
font-weight: 600;
|
|
264
|
+
transition: all 0.2s;
|
|
265
|
+
flex: 1;
|
|
266
|
+
min-width: 60px;
|
|
267
|
+
white-space: nowrap;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.tool-btn-primary {
|
|
271
|
+
background: var(--color-primary);
|
|
272
|
+
color: white;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.tool-btn-primary:hover {
|
|
276
|
+
background: var(--color-primary-dark);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.tool-progress-bar {
|
|
280
|
+
width: 100%;
|
|
281
|
+
height: 0.25rem;
|
|
282
|
+
background: var(--color-bg-tertiary);
|
|
283
|
+
border-radius: 0.125rem;
|
|
284
|
+
overflow: hidden;
|
|
285
|
+
margin-top: 0.25rem;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.tool-progress-fill {
|
|
289
|
+
height: 100%;
|
|
290
|
+
background: linear-gradient(90deg, #3b82f6, #2563eb);
|
|
291
|
+
width: 60%;
|
|
292
|
+
border-radius: 0.125rem;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.feature-list {
|
|
296
|
+
display: grid;
|
|
297
|
+
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
298
|
+
gap: 15px;
|
|
299
|
+
margin: 20px 0;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.feature-item {
|
|
303
|
+
padding: 12px;
|
|
304
|
+
background: var(--color-bg-primary);
|
|
305
|
+
border-radius: 0.5rem;
|
|
306
|
+
border-left: 3px solid var(--color-primary);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.feature-item strong {
|
|
310
|
+
color: var(--color-primary);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.size-demo {
|
|
314
|
+
display: flex;
|
|
315
|
+
gap: 10px;
|
|
316
|
+
margin: 20px 0;
|
|
317
|
+
flex-wrap: wrap;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.size-demo-item {
|
|
321
|
+
text-align: center;
|
|
322
|
+
padding: 10px;
|
|
323
|
+
background: var(--color-bg-primary);
|
|
324
|
+
border-radius: 0.5rem;
|
|
325
|
+
border: 1px solid var(--color-border);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.size-label {
|
|
329
|
+
font-size: 0.8rem;
|
|
330
|
+
color: var(--color-text-secondary);
|
|
331
|
+
margin-bottom: 5px;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.toggle-dark {
|
|
335
|
+
position: fixed;
|
|
336
|
+
top: 20px;
|
|
337
|
+
right: 20px;
|
|
338
|
+
padding: 0.5rem 1rem;
|
|
339
|
+
background: var(--color-primary);
|
|
340
|
+
color: white;
|
|
341
|
+
border: none;
|
|
342
|
+
border-radius: 0.5rem;
|
|
343
|
+
cursor: pointer;
|
|
344
|
+
font-weight: 600;
|
|
345
|
+
}
|
|
346
|
+
</style>
|
|
347
|
+
</head>
|
|
348
|
+
<body>
|
|
349
|
+
<button class="toggle-dark" onclick="document.documentElement.classList.toggle('dark')">Toggle Dark</button>
|
|
350
|
+
|
|
351
|
+
<div class="test-container">
|
|
352
|
+
<h1>Tools UI Redesign - Compact Grid Layout</h1>
|
|
353
|
+
<div class="description">
|
|
354
|
+
This test page demonstrates the new compact single-card tools UI with integrated voice controls.
|
|
355
|
+
The tools are arranged in a responsive 2x2 grid that adapts to smaller screens.
|
|
356
|
+
</div>
|
|
357
|
+
|
|
358
|
+
<div class="demo-section">
|
|
359
|
+
<div class="section-title">New Features</div>
|
|
360
|
+
<div class="feature-list">
|
|
361
|
+
<div class="feature-item">
|
|
362
|
+
<strong>Compact Grid</strong><br>
|
|
363
|
+
All 4 tools fit in a 2x2 grid that's responsive
|
|
364
|
+
</div>
|
|
365
|
+
<div class="feature-item">
|
|
366
|
+
<strong>Integrated Voice</strong><br>
|
|
367
|
+
Auto-speak toggle and voice selector in header
|
|
368
|
+
</div>
|
|
369
|
+
<div class="feature-item">
|
|
370
|
+
<strong>Efficient Sizing</strong><br>
|
|
371
|
+
Tool cards ~120px height, optimized buttons
|
|
372
|
+
</div>
|
|
373
|
+
<div class="feature-item">
|
|
374
|
+
<strong>Responsive Design</strong><br>
|
|
375
|
+
Adapts from 2 columns to 1 on mobile
|
|
376
|
+
</div>
|
|
377
|
+
</div>
|
|
378
|
+
</div>
|
|
379
|
+
|
|
380
|
+
<div class="demo-section">
|
|
381
|
+
<div class="section-title">Live Preview</div>
|
|
382
|
+
<div style="display: flex; gap: 20px; margin-bottom: 30px; flex-wrap: wrap;">
|
|
383
|
+
<div>
|
|
384
|
+
<div class="size-label">Desktop (600px)</div>
|
|
385
|
+
<div class="tools-popup-content">
|
|
386
|
+
<div class="tools-popup-header">
|
|
387
|
+
<div style="display: flex; align-items: center; gap: 0.75rem; flex: 1;">
|
|
388
|
+
<h2 style="margin: 0; font-size: 1rem;">Tools & Extensions</h2>
|
|
389
|
+
</div>
|
|
390
|
+
<div class="tools-popup-header-controls">
|
|
391
|
+
<label class="tools-voice-toggle">
|
|
392
|
+
<input type="checkbox" checked>
|
|
393
|
+
<span>Auto-speak</span>
|
|
394
|
+
</label>
|
|
395
|
+
<select class="tools-voice-selector">
|
|
396
|
+
<option>Voice</option>
|
|
397
|
+
<option>en-US</option>
|
|
398
|
+
</select>
|
|
399
|
+
<button style="background: none; border: none; color: var(--color-text-secondary); font-size: 1.5rem; cursor: pointer; padding: 0; line-height: 1;">×</button>
|
|
400
|
+
</div>
|
|
401
|
+
</div>
|
|
402
|
+
<div class="tools-popup-scroll">
|
|
403
|
+
<div class="tool-item">
|
|
404
|
+
<div style="display: flex; flex-direction: column; gap: 0.3rem;">
|
|
405
|
+
<div class="tool-header">
|
|
406
|
+
<span class="tool-name">gm-cc</span>
|
|
407
|
+
</div>
|
|
408
|
+
<div class="tool-status-indicator installed">
|
|
409
|
+
<span class="tool-status-dot"></span>
|
|
410
|
+
<span>Up-to-date</span>
|
|
411
|
+
</div>
|
|
412
|
+
<div class="tool-versions">
|
|
413
|
+
<span class="tool-version-item">v1.2.5</span>
|
|
414
|
+
</div>
|
|
415
|
+
</div>
|
|
416
|
+
<div class="tool-actions">
|
|
417
|
+
<button class="tool-btn tool-btn-primary">✓</button>
|
|
418
|
+
</div>
|
|
419
|
+
</div>
|
|
420
|
+
|
|
421
|
+
<div class="tool-item">
|
|
422
|
+
<div style="display: flex; flex-direction: column; gap: 0.3rem;">
|
|
423
|
+
<div class="tool-header">
|
|
424
|
+
<span class="tool-name">gm-oc</span>
|
|
425
|
+
</div>
|
|
426
|
+
<div class="tool-status-indicator needs_update">
|
|
427
|
+
<span class="tool-status-dot"></span>
|
|
428
|
+
<span>Update avail</span>
|
|
429
|
+
</div>
|
|
430
|
+
<div class="tool-versions">
|
|
431
|
+
<span class="tool-version-item">v1.0.2</span>
|
|
432
|
+
<span class="tool-version-item">(v1.0.3 available)</span>
|
|
433
|
+
</div>
|
|
434
|
+
</div>
|
|
435
|
+
<div class="tool-actions">
|
|
436
|
+
<button class="tool-btn tool-btn-primary">Update</button>
|
|
437
|
+
</div>
|
|
438
|
+
</div>
|
|
439
|
+
|
|
440
|
+
<div class="tool-item">
|
|
441
|
+
<div style="display: flex; flex-direction: column; gap: 0.3rem;">
|
|
442
|
+
<div class="tool-header">
|
|
443
|
+
<span class="tool-name">gm-gc</span>
|
|
444
|
+
</div>
|
|
445
|
+
<div class="tool-status-indicator installed">
|
|
446
|
+
<span class="tool-status-dot"></span>
|
|
447
|
+
<span>Up-to-date</span>
|
|
448
|
+
</div>
|
|
449
|
+
<div class="tool-versions">
|
|
450
|
+
<span class="tool-version-item">v2.1.0</span>
|
|
451
|
+
</div>
|
|
452
|
+
</div>
|
|
453
|
+
<div class="tool-actions">
|
|
454
|
+
<button class="tool-btn tool-btn-primary">✓</button>
|
|
455
|
+
</div>
|
|
456
|
+
</div>
|
|
457
|
+
|
|
458
|
+
<div class="tool-item">
|
|
459
|
+
<div style="display: flex; flex-direction: column; gap: 0.3rem;">
|
|
460
|
+
<div class="tool-header">
|
|
461
|
+
<span class="tool-name">gm-kilo</span>
|
|
462
|
+
</div>
|
|
463
|
+
<div class="tool-status-indicator not_installed">
|
|
464
|
+
<span class="tool-status-dot"></span>
|
|
465
|
+
<span>Not instal</span>
|
|
466
|
+
</div>
|
|
467
|
+
<div class="tool-versions">
|
|
468
|
+
</div>
|
|
469
|
+
</div>
|
|
470
|
+
<div class="tool-actions">
|
|
471
|
+
<button class="tool-btn tool-btn-primary">Install</button>
|
|
472
|
+
</div>
|
|
473
|
+
</div>
|
|
474
|
+
</div>
|
|
475
|
+
</div>
|
|
476
|
+
</div>
|
|
477
|
+
|
|
478
|
+
<div>
|
|
479
|
+
<div class="size-label">Installing State</div>
|
|
480
|
+
<div class="tools-popup-content" style="max-width: 300px;">
|
|
481
|
+
<div class="tools-popup-header">
|
|
482
|
+
<h2 style="margin: 0; font-size: 1rem;">Tools & Extensions</h2>
|
|
483
|
+
<button style="background: none; border: none; color: var(--color-text-secondary); font-size: 1.5rem; cursor: pointer; padding: 0; line-height: 1;">×</button>
|
|
484
|
+
</div>
|
|
485
|
+
<div class="tools-popup-scroll">
|
|
486
|
+
<div class="tool-item">
|
|
487
|
+
<div style="display: flex; flex-direction: column; gap: 0.3rem;">
|
|
488
|
+
<div class="tool-header">
|
|
489
|
+
<span class="tool-name">gm-kilo</span>
|
|
490
|
+
</div>
|
|
491
|
+
<div class="tool-status-indicator" style="background: rgba(59, 130, 246, 0.15); color: #3b82f6;">
|
|
492
|
+
<span class="tool-status-dot"></span>
|
|
493
|
+
<span>Installing</span>
|
|
494
|
+
</div>
|
|
495
|
+
</div>
|
|
496
|
+
<div class="tool-actions">
|
|
497
|
+
<button class="tool-btn tool-btn-primary" disabled>Installing</button>
|
|
498
|
+
</div>
|
|
499
|
+
</div>
|
|
500
|
+
</div>
|
|
501
|
+
</div>
|
|
502
|
+
</div>
|
|
503
|
+
</div>
|
|
504
|
+
</div>
|
|
505
|
+
|
|
506
|
+
<div class="demo-section">
|
|
507
|
+
<div class="section-title">Size Comparison</div>
|
|
508
|
+
<div class="size-demo">
|
|
509
|
+
<div class="size-demo-item">
|
|
510
|
+
<div class="size-label">Tool Card Height</div>
|
|
511
|
+
<div style="font-size: 0.9rem; font-weight: 600; color: var(--color-primary);">120px min</div>
|
|
512
|
+
</div>
|
|
513
|
+
<div class="size-demo-item">
|
|
514
|
+
<div class="size-label">Tool Item Padding</div>
|
|
515
|
+
<div style="font-size: 0.9rem; font-weight: 600; color: var(--color-primary);">0.75rem</div>
|
|
516
|
+
</div>
|
|
517
|
+
<div class="size-demo-item">
|
|
518
|
+
<div class="size-label">Button Height</div>
|
|
519
|
+
<div style="font-size: 0.9rem; font-weight: 600; color: var(--color-primary);">28px</div>
|
|
520
|
+
</div>
|
|
521
|
+
<div class="size-demo-item">
|
|
522
|
+
<div class="size-label">Grid Gap</div>
|
|
523
|
+
<div style="font-size: 0.9rem; font-weight: 600; color: var(--color-primary);">1rem</div>
|
|
524
|
+
</div>
|
|
525
|
+
</div>
|
|
526
|
+
</div>
|
|
527
|
+
|
|
528
|
+
<div class="demo-section">
|
|
529
|
+
<div class="section-title">Responsive Behavior</div>
|
|
530
|
+
<div class="feature-list">
|
|
531
|
+
<div class="feature-item">
|
|
532
|
+
<strong>Desktop (>768px)</strong><br>
|
|
533
|
+
2x2 grid with 200px min-width per column
|
|
534
|
+
</div>
|
|
535
|
+
<div class="feature-item">
|
|
536
|
+
<strong>Tablet (481-768px)</strong><br>
|
|
537
|
+
Auto-fit with 150px min-width columns
|
|
538
|
+
</div>
|
|
539
|
+
<div class="feature-item">
|
|
540
|
+
<strong>Mobile (<480px)</strong><br>
|
|
541
|
+
Single column layout, full width
|
|
542
|
+
</div>
|
|
543
|
+
<div class="feature-item">
|
|
544
|
+
<strong>Header on Mobile</strong><br>
|
|
545
|
+
Flex-direction column for better spacing
|
|
546
|
+
</div>
|
|
547
|
+
</div>
|
|
548
|
+
</div>
|
|
549
|
+
</div>
|
|
550
|
+
</body>
|
|
551
|
+
</html>
|