agentgui 1.0.453 → 1.0.454

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.
@@ -0,0 +1,323 @@
1
+ const ToolStatusComponent = {
2
+ state: {
3
+ tools: [],
4
+ expandedTool: null,
5
+ refreshing: false
6
+ },
7
+
8
+ init() {
9
+ this.loadTools();
10
+ if (window.wsManager) {
11
+ window.wsManager.on('tool_install_started', (data) => this.handleInstallStarted(data));
12
+ window.wsManager.on('tool_install_progress', (data) => this.handleProgress(data));
13
+ window.wsManager.on('tool_install_complete', (data) => this.handleInstallComplete(data));
14
+ window.wsManager.on('tool_install_failed', (data) => this.handleInstallFailed(data));
15
+ window.wsManager.on('tool_update_complete', (data) => this.handleUpdateComplete(data));
16
+ window.wsManager.on('tool_update_failed', (data) => this.handleUpdateFailed(data));
17
+ window.wsManager.on('tools_refresh_complete', (data) => this.handleRefreshComplete(data));
18
+ }
19
+ },
20
+
21
+ async loadTools() {
22
+ try {
23
+ const res = await fetch('/gm/api/tools');
24
+ const data = await res.json();
25
+ this.state.tools = data.tools || [];
26
+ this.render();
27
+ } catch (e) {
28
+ console.error('[TOOL-STATUS] Load failed:', e.message);
29
+ }
30
+ },
31
+
32
+ async installTool(toolId) {
33
+ try {
34
+ const res = await fetch(`/gm/api/tools/${toolId}/install`, { method: 'POST' });
35
+ const data = await res.json();
36
+ if (data.success) {
37
+ const tool = this.state.tools.find(t => t.id === toolId);
38
+ if (tool) tool.status = 'installing';
39
+ this.render();
40
+ } else {
41
+ alert('Install failed: ' + (data.error || 'Unknown error'));
42
+ }
43
+ } catch (e) {
44
+ alert('Install failed: ' + e.message);
45
+ }
46
+ },
47
+
48
+ async updateTool(toolId) {
49
+ try {
50
+ const res = await fetch(`/gm/api/tools/${toolId}/update`, { method: 'POST', body: JSON.stringify({}) });
51
+ const data = await res.json();
52
+ if (data.success) {
53
+ const tool = this.state.tools.find(t => t.id === toolId);
54
+ if (tool) tool.status = 'updating';
55
+ this.render();
56
+ } else {
57
+ alert('Update failed: ' + (data.error || 'Unknown error'));
58
+ }
59
+ } catch (e) {
60
+ alert('Update failed: ' + e.message);
61
+ }
62
+ },
63
+
64
+ async refreshTools() {
65
+ this.state.refreshing = true;
66
+ this.render();
67
+ try {
68
+ await fetch('/gm/api/tools/refresh-all', { method: 'POST' });
69
+ } catch (e) {
70
+ console.error('[TOOL-STATUS] Refresh failed:', e.message);
71
+ }
72
+ },
73
+
74
+ handleInstallStarted(data) {
75
+ const tool = this.state.tools.find(t => t.id === data.toolId);
76
+ if (tool) {
77
+ tool.status = 'installing';
78
+ tool.progress = 0;
79
+ this.render();
80
+ }
81
+ },
82
+
83
+ handleProgress(data) {
84
+ const tool = this.state.tools.find(t => t.id === data.toolId);
85
+ if (tool) {
86
+ tool.progress = Math.min((tool.progress || 0) + 5, 90);
87
+ this.render();
88
+ }
89
+ },
90
+
91
+ handleInstallComplete(data) {
92
+ const tool = this.state.tools.find(t => t.id === data.toolId);
93
+ if (tool) {
94
+ tool.status = 'installed';
95
+ tool.version = data.data.version;
96
+ tool.progress = 100;
97
+ this.render();
98
+ setTimeout(() => this.loadTools(), 1000);
99
+ }
100
+ },
101
+
102
+ handleInstallFailed(data) {
103
+ const tool = this.state.tools.find(t => t.id === data.toolId);
104
+ if (tool) {
105
+ tool.status = 'failed';
106
+ tool.error_message = data.data.error;
107
+ tool.progress = 0;
108
+ this.render();
109
+ }
110
+ },
111
+
112
+ handleUpdateComplete(data) {
113
+ const tool = this.state.tools.find(t => t.id === data.toolId);
114
+ if (tool) {
115
+ tool.status = 'installed';
116
+ tool.version = data.data.version;
117
+ tool.hasUpdate = false;
118
+ tool.progress = 100;
119
+ this.render();
120
+ setTimeout(() => this.loadTools(), 1000);
121
+ }
122
+ },
123
+
124
+ handleUpdateFailed(data) {
125
+ const tool = this.state.tools.find(t => t.id === data.toolId);
126
+ if (tool) {
127
+ tool.status = 'failed';
128
+ tool.error_message = data.data.error;
129
+ this.render();
130
+ }
131
+ },
132
+
133
+ handleRefreshComplete(data) {
134
+ this.state.refreshing = false;
135
+ this.loadTools();
136
+ },
137
+
138
+ getStatusColor(tool) {
139
+ if (tool.status === 'installed' && !tool.hasUpdate) return '#4CAF50';
140
+ if (tool.status === 'installed' && tool.hasUpdate) return '#FFC107';
141
+ if (tool.status === 'installing' || tool.status === 'updating') return '#2196F3';
142
+ if (tool.status === 'failed') return '#F44336';
143
+ return '#9E9E9E';
144
+ },
145
+
146
+ getStatusText(tool) {
147
+ if (tool.status === 'installed') {
148
+ if (tool.hasUpdate) return `Update available (v${tool.latestVersion})`;
149
+ return `Installed v${tool.version || '?'}`;
150
+ }
151
+ if (tool.status === 'installing') return 'Installing...';
152
+ if (tool.status === 'updating') return 'Updating...';
153
+ if (tool.status === 'failed') return 'Failed';
154
+ return 'Not installed';
155
+ },
156
+
157
+ render() {
158
+ const container = document.getElementById('tool-status-container');
159
+ if (!container) return;
160
+
161
+ const html = `
162
+ <div class="tool-status-header">
163
+ <h3>Tools</h3>
164
+ <button onclick="window.toolStatus.refreshTools()" ${this.state.refreshing ? 'disabled' : ''} class="tool-refresh-btn">
165
+ ${this.state.refreshing ? 'Refreshing...' : 'Refresh'}
166
+ </button>
167
+ </div>
168
+ <div class="tool-grid">
169
+ ${this.state.tools.map(tool => `
170
+ <div class="tool-card" style="border-left: 4px solid ${this.getStatusColor(tool)}">
171
+ <div class="tool-name">${tool.name || tool.id}</div>
172
+ <div class="tool-status">${this.getStatusText(tool)}</div>
173
+ ${tool.progress !== undefined && (tool.status === 'installing' || tool.status === 'updating') ? `
174
+ <div class="tool-progress">
175
+ <div class="progress-bar" style="width: ${tool.progress}%"></div>
176
+ </div>
177
+ ` : ''}
178
+ <div class="tool-actions">
179
+ ${!tool.installed ? `
180
+ <button onclick="window.toolStatus.installTool('${tool.id}')" class="tool-btn tool-btn-primary">Install</button>
181
+ ` : tool.hasUpdate ? `
182
+ <button onclick="window.toolStatus.updateTool('${tool.id}')" class="tool-btn tool-btn-primary">Update</button>
183
+ ` : `
184
+ <button onclick="window.toolStatus.refreshTools()" class="tool-btn tool-btn-secondary">Check Updates</button>
185
+ `}
186
+ ${tool.status === 'failed' ? `
187
+ <button onclick="window.toolStatus.installTool('${tool.id}')" class="tool-btn tool-btn-warning">Retry</button>
188
+ ` : ''}
189
+ ${tool.error_message ? `
190
+ <div class="tool-error" title="${tool.error_message}">
191
+ Error: ${tool.error_message.substring(0, 30)}...
192
+ <a href="#" onclick="alert('${tool.error_message.replace(/"/g, '\\"')}'); return false;">Details</a>
193
+ </div>
194
+ ` : ''}
195
+ </div>
196
+ </div>
197
+ `).join('')}
198
+ </div>
199
+ <style>
200
+ #tool-status-container {
201
+ padding: 16px;
202
+ border: 1px solid #e0e0e0;
203
+ border-radius: 4px;
204
+ margin-bottom: 16px;
205
+ }
206
+ .tool-status-header {
207
+ display: flex;
208
+ justify-content: space-between;
209
+ align-items: center;
210
+ margin-bottom: 16px;
211
+ }
212
+ .tool-status-header h3 {
213
+ margin: 0;
214
+ font-size: 18px;
215
+ }
216
+ .tool-refresh-btn {
217
+ padding: 6px 12px;
218
+ background: #2196F3;
219
+ color: white;
220
+ border: none;
221
+ border-radius: 4px;
222
+ cursor: pointer;
223
+ font-size: 12px;
224
+ }
225
+ .tool-refresh-btn:disabled {
226
+ opacity: 0.6;
227
+ cursor: not-allowed;
228
+ }
229
+ .tool-grid {
230
+ display: grid;
231
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
232
+ gap: 12px;
233
+ }
234
+ .tool-card {
235
+ padding: 12px;
236
+ border: 1px solid #ddd;
237
+ border-radius: 4px;
238
+ background: #f9f9f9;
239
+ }
240
+ .tool-name {
241
+ font-weight: bold;
242
+ margin-bottom: 4px;
243
+ font-size: 14px;
244
+ }
245
+ .tool-status {
246
+ font-size: 12px;
247
+ color: #666;
248
+ margin-bottom: 8px;
249
+ }
250
+ .tool-progress {
251
+ width: 100%;
252
+ height: 6px;
253
+ background: #e0e0e0;
254
+ border-radius: 3px;
255
+ overflow: hidden;
256
+ margin-bottom: 8px;
257
+ }
258
+ .progress-bar {
259
+ height: 100%;
260
+ background: #4CAF50;
261
+ transition: width 0.3s;
262
+ }
263
+ .tool-actions {
264
+ display: flex;
265
+ flex-direction: column;
266
+ gap: 6px;
267
+ }
268
+ .tool-btn {
269
+ padding: 6px;
270
+ border: none;
271
+ border-radius: 3px;
272
+ cursor: pointer;
273
+ font-size: 12px;
274
+ white-space: nowrap;
275
+ }
276
+ .tool-btn-primary {
277
+ background: #2196F3;
278
+ color: white;
279
+ }
280
+ .tool-btn-primary:hover {
281
+ background: #1976D2;
282
+ }
283
+ .tool-btn-secondary {
284
+ background: #f0f0f0;
285
+ color: #333;
286
+ border: 1px solid #ddd;
287
+ }
288
+ .tool-btn-secondary:hover {
289
+ background: #e0e0e0;
290
+ }
291
+ .tool-btn-warning {
292
+ background: #FF9800;
293
+ color: white;
294
+ }
295
+ .tool-btn-warning:hover {
296
+ background: #F57C00;
297
+ }
298
+ .tool-error {
299
+ font-size: 11px;
300
+ color: #F44336;
301
+ padding: 6px;
302
+ background: #ffebee;
303
+ border-radius: 2px;
304
+ margin-top: 4px;
305
+ }
306
+ .tool-error a {
307
+ color: #C62828;
308
+ text-decoration: underline;
309
+ cursor: pointer;
310
+ }
311
+ </style>
312
+ `;
313
+
314
+ container.innerHTML = html;
315
+ window.toolStatus = this;
316
+ }
317
+ };
318
+
319
+ if (document.readyState === 'loading') {
320
+ document.addEventListener('DOMContentLoaded', () => ToolStatusComponent.init());
321
+ } else {
322
+ ToolStatusComponent.init();
323
+ }