agentgui 1.0.67 → 1.0.68
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/.prd +214 -0
- package/.prd-browser +607 -0
- package/CLAUDE.md +1532 -125
- package/browser-test-harness.js +371 -0
- package/browser-test.js +409 -0
- package/execute-tests.js +164 -0
- package/lib/claude-runner.js +41 -12
- package/lib/database-service.ts +252 -0
- package/lib/sync-service.ts +275 -0
- package/lib/types.ts +168 -0
- package/package.json +1 -1
- package/readme.md +586 -0
- package/run-e2e-test.sh +88 -0
- package/server.js +274 -8
- package/static/index.html +487 -180
- package/static/js/client.js +558 -0
- package/static/js/event-filter.js +311 -0
- package/static/js/event-processor.js +454 -0
- package/static/js/streaming-renderer.js +813 -0
- package/static/js/syntax-highlighter.js +271 -0
- package/static/js/ui-components.js +433 -0
- package/static/js/websocket-manager.js +482 -0
- package/static/templates/INDEX.html +465 -0
- package/static/templates/README.md +190 -0
- package/static/templates/agent-capabilities.html +56 -0
- package/static/templates/agent-metadata-panel.html +44 -0
- package/static/templates/agent-status-badge.html +30 -0
- package/static/templates/code-annotation-panel.html +155 -0
- package/static/templates/code-suggestion-panel.html +184 -0
- package/static/templates/command-header.html +77 -0
- package/static/templates/command-output-scrollable.html +118 -0
- package/static/templates/elapsed-time.html +54 -0
- package/static/templates/error-alert.html +106 -0
- package/static/templates/error-history-timeline.html +160 -0
- package/static/templates/error-recovery-options.html +109 -0
- package/static/templates/error-stack-trace.html +95 -0
- package/static/templates/error-summary.html +80 -0
- package/static/templates/event-counter.html +48 -0
- package/static/templates/execution-actions.html +97 -0
- package/static/templates/execution-progress-bar.html +80 -0
- package/static/templates/execution-stepper.html +120 -0
- package/static/templates/file-breadcrumb.html +118 -0
- package/static/templates/file-diff-viewer.html +121 -0
- package/static/templates/file-metadata.html +133 -0
- package/static/templates/file-read-panel.html +66 -0
- package/static/templates/file-write-panel.html +120 -0
- package/static/templates/git-branch-remote.html +107 -0
- package/static/templates/git-diff-list.html +101 -0
- package/static/templates/git-log-visualization.html +153 -0
- package/static/templates/git-status-panel.html +115 -0
- package/static/templates/quality-metrics-display.html +170 -0
- package/static/templates/terminal-output-panel.html +87 -0
- package/static/templates/test-results-display.html +144 -0
- package/test-browser.js +457 -0
- package/test-runner.js +182 -0
package/static/index.html
CHANGED
|
@@ -1,211 +1,518 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
2
|
+
<html lang="en" class="light">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<
|
|
7
|
-
<
|
|
8
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/rippleui@1.12.1/dist/css/styles.css" />
|
|
9
|
-
<link rel="stylesheet" href="styles.css">
|
|
10
|
-
</head>
|
|
11
|
-
<body>
|
|
12
|
-
<div id="app" class="app">
|
|
13
|
-
<!-- Left Sidebar -->
|
|
14
|
-
<aside class="sidebar" id="sidebar">
|
|
15
|
-
<div class="sidebar-header">
|
|
16
|
-
<button class="sidebar-toggle" onclick="toggleSidebar()" title="Toggle sidebar">
|
|
17
|
-
<span class="toggle-icon">×</span>
|
|
18
|
-
</button>
|
|
19
|
-
</div>
|
|
6
|
+
<meta name="description" content="AgentGUI - Real-time Claude Code Execution Visualization">
|
|
7
|
+
<title>AgentGUI - Agent Execution Visualizer</title>
|
|
20
8
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
</button>
|
|
9
|
+
<!-- RippleUI CSS -->
|
|
10
|
+
<link href="https://unpkg.com/rippleui@0.14.0/dist/ripple.css" rel="stylesheet">
|
|
24
11
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<div class="chat-list" id="chatList"></div>
|
|
28
|
-
</div>
|
|
12
|
+
<!-- Syntax Highlighting -->
|
|
13
|
+
<link href="https://unpkg.com/prism@1.29.0/themes/prism-dark.css" rel="stylesheet">
|
|
29
14
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
</aside>
|
|
15
|
+
<!-- Custom Styles -->
|
|
16
|
+
<style>
|
|
17
|
+
* {
|
|
18
|
+
box-sizing: border-box;
|
|
19
|
+
}
|
|
36
20
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
21
|
+
:root {
|
|
22
|
+
--color-primary: #3b82f6;
|
|
23
|
+
--color-primary-dark: #1e40af;
|
|
24
|
+
--color-bg-primary: #ffffff;
|
|
25
|
+
--color-bg-secondary: #f9fafb;
|
|
26
|
+
--color-bg-code: #1f2937;
|
|
27
|
+
--color-text-primary: #111827;
|
|
28
|
+
--color-text-secondary: #6b7280;
|
|
29
|
+
--color-border: #e5e7eb;
|
|
30
|
+
--color-success: #10b981;
|
|
31
|
+
--color-error: #ef4444;
|
|
32
|
+
--color-warning: #f59e0b;
|
|
33
|
+
}
|
|
44
34
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
35
|
+
html.dark {
|
|
36
|
+
--color-bg-primary: #111827;
|
|
37
|
+
--color-bg-secondary: #1f2937;
|
|
38
|
+
--color-text-primary: #f9fafb;
|
|
39
|
+
--color-text-secondary: #d1d5db;
|
|
40
|
+
--color-border: #374151;
|
|
41
|
+
}
|
|
55
42
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
></textarea>
|
|
65
|
-
<div class="input-actions">
|
|
66
|
-
<button class="action-btn" onclick="triggerFileUpload()" title="Upload files">
|
|
67
|
-
<span class="icon">📎</span>
|
|
68
|
-
</button>
|
|
69
|
-
<button class="action-btn send-btn" id="sendBtn" onclick="sendMessage()" title="Send message">
|
|
70
|
-
<span class="icon">→</span>
|
|
71
|
-
</button>
|
|
72
|
-
<input type="file" id="fileInput" style="display: none;" onchange="handleFileUpload()" multiple />
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
</div>
|
|
76
|
-
</div>
|
|
43
|
+
body {
|
|
44
|
+
margin: 0;
|
|
45
|
+
padding: 0;
|
|
46
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
47
|
+
background-color: var(--color-bg-primary);
|
|
48
|
+
color: var(--color-text-primary);
|
|
49
|
+
transition: background-color 0.3s, color 0.3s;
|
|
50
|
+
}
|
|
77
51
|
|
|
78
|
-
|
|
52
|
+
/* Layout */
|
|
53
|
+
.app-container {
|
|
54
|
+
display: grid;
|
|
55
|
+
grid-template-columns: 1fr;
|
|
56
|
+
grid-template-rows: auto 1fr;
|
|
57
|
+
min-height: 100vh;
|
|
58
|
+
gap: 0;
|
|
59
|
+
}
|
|
79
60
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
61
|
+
header {
|
|
62
|
+
background-color: var(--color-bg-secondary);
|
|
63
|
+
border-bottom: 1px solid var(--color-border);
|
|
64
|
+
padding: 1rem;
|
|
65
|
+
display: flex;
|
|
66
|
+
justify-content: space-between;
|
|
67
|
+
align-items: center;
|
|
68
|
+
gap: 1rem;
|
|
69
|
+
}
|
|
87
70
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
71
|
+
.header-title {
|
|
72
|
+
font-size: 1.5rem;
|
|
73
|
+
font-weight: bold;
|
|
74
|
+
margin: 0;
|
|
75
|
+
flex: 1;
|
|
76
|
+
}
|
|
94
77
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
78
|
+
.header-controls {
|
|
79
|
+
display: flex;
|
|
80
|
+
gap: 1rem;
|
|
81
|
+
align-items: center;
|
|
82
|
+
}
|
|
99
83
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
84
|
+
.status-badge {
|
|
85
|
+
display: inline-flex;
|
|
86
|
+
align-items: center;
|
|
87
|
+
gap: 0.5rem;
|
|
88
|
+
padding: 0.5rem 1rem;
|
|
89
|
+
border-radius: 0.25rem;
|
|
90
|
+
font-size: 0.875rem;
|
|
91
|
+
font-weight: 500;
|
|
92
|
+
background-color: var(--color-bg-primary);
|
|
93
|
+
border: 1px solid var(--color-border);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.status-indicator {
|
|
97
|
+
width: 0.75rem;
|
|
98
|
+
height: 0.75rem;
|
|
99
|
+
border-radius: 50%;
|
|
100
|
+
background-color: var(--color-error);
|
|
101
|
+
animation: pulse 2s infinite;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.status-indicator[data-status="connected"] {
|
|
105
|
+
background-color: var(--color-success);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.status-indicator[data-status="reconnecting"],
|
|
109
|
+
.status-indicator[data-status="connecting"] {
|
|
110
|
+
background-color: var(--color-warning);
|
|
111
|
+
animation: pulse 1s infinite;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@keyframes pulse {
|
|
115
|
+
0%, 100% {
|
|
116
|
+
opacity: 1;
|
|
117
|
+
}
|
|
118
|
+
50% {
|
|
119
|
+
opacity: 0.5;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Main content */
|
|
124
|
+
main {
|
|
125
|
+
display: grid;
|
|
126
|
+
grid-template-columns: 1fr;
|
|
127
|
+
grid-template-rows: auto 1fr;
|
|
128
|
+
gap: 0;
|
|
129
|
+
min-height: 0;
|
|
130
|
+
overflow: hidden;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.execution-panel {
|
|
134
|
+
background-color: var(--color-bg-secondary);
|
|
135
|
+
border-bottom: 1px solid var(--color-border);
|
|
136
|
+
padding: 1.5rem;
|
|
137
|
+
display: grid;
|
|
138
|
+
grid-template-columns: 1fr auto;
|
|
139
|
+
gap: 1rem;
|
|
140
|
+
align-items: end;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.execution-input-group {
|
|
144
|
+
display: grid;
|
|
145
|
+
grid-template-columns: 1fr auto;
|
|
146
|
+
gap: 0.5rem;
|
|
147
|
+
align-items: end;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.execution-input-group > * {
|
|
151
|
+
min-width: 0;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.execution-textarea {
|
|
155
|
+
width: 100%;
|
|
156
|
+
padding: 0.75rem;
|
|
157
|
+
border: 1px solid var(--color-border);
|
|
158
|
+
border-radius: 0.375rem;
|
|
159
|
+
background-color: var(--color-bg-primary);
|
|
160
|
+
color: var(--color-text-primary);
|
|
161
|
+
font-family: inherit;
|
|
162
|
+
resize: none;
|
|
163
|
+
min-height: 3rem;
|
|
164
|
+
max-height: 8rem;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.btn {
|
|
168
|
+
padding: 0.75rem 1.5rem;
|
|
169
|
+
border: none;
|
|
170
|
+
border-radius: 0.375rem;
|
|
171
|
+
font-weight: 500;
|
|
172
|
+
cursor: pointer;
|
|
173
|
+
transition: all 0.2s;
|
|
174
|
+
font-size: 0.875rem;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.btn-primary {
|
|
178
|
+
background-color: var(--color-primary);
|
|
179
|
+
color: white;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.btn-primary:hover:not(:disabled) {
|
|
183
|
+
background-color: var(--color-primary-dark);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.btn:disabled {
|
|
187
|
+
opacity: 0.5;
|
|
188
|
+
cursor: not-allowed;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.agent-selector {
|
|
192
|
+
padding: 0.5rem;
|
|
193
|
+
border: 1px solid var(--color-border);
|
|
194
|
+
border-radius: 0.375rem;
|
|
195
|
+
background-color: var(--color-bg-primary);
|
|
196
|
+
color: var(--color-text-primary);
|
|
197
|
+
font-size: 0.875rem;
|
|
198
|
+
cursor: pointer;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* Output area */
|
|
202
|
+
#output-scroll {
|
|
203
|
+
overflow-y: auto;
|
|
204
|
+
overflow-x: hidden;
|
|
205
|
+
display: flex;
|
|
206
|
+
flex-direction: column;
|
|
207
|
+
min-height: 0;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
#output {
|
|
211
|
+
flex: 1;
|
|
212
|
+
padding: 1rem;
|
|
213
|
+
display: flex;
|
|
214
|
+
flex-direction: column;
|
|
215
|
+
gap: 0.5rem;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* Event cards */
|
|
219
|
+
.card {
|
|
220
|
+
background-color: var(--color-bg-primary);
|
|
221
|
+
border: 1px solid var(--color-border);
|
|
222
|
+
border-radius: 0.375rem;
|
|
223
|
+
padding: 1rem;
|
|
224
|
+
margin-bottom: 0.5rem;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.card-header {
|
|
228
|
+
font-weight: 600;
|
|
229
|
+
margin-bottom: 0.5rem;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.badge {
|
|
233
|
+
display: inline-block;
|
|
234
|
+
padding: 0.25rem 0.75rem;
|
|
235
|
+
border-radius: 0.25rem;
|
|
236
|
+
font-size: 0.75rem;
|
|
237
|
+
font-weight: 600;
|
|
238
|
+
background-color: var(--color-bg-secondary);
|
|
239
|
+
color: var(--color-text-secondary);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.badge-sm {
|
|
243
|
+
padding: 0.125rem 0.5rem;
|
|
244
|
+
font-size: 0.7rem;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* Responsive */
|
|
248
|
+
@media (max-width: 768px) {
|
|
249
|
+
.execution-panel {
|
|
250
|
+
grid-template-columns: 1fr;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.header-controls {
|
|
254
|
+
flex-wrap: wrap;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.execution-input-group {
|
|
258
|
+
grid-template-columns: 1fr;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/* Utilities */
|
|
263
|
+
.flex {
|
|
264
|
+
display: flex;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.items-center {
|
|
268
|
+
align-items: center;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.justify-between {
|
|
272
|
+
justify-content: space-between;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.gap-2 {
|
|
276
|
+
gap: 0.5rem;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.gap-3 {
|
|
280
|
+
gap: 0.75rem;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.text-xs {
|
|
284
|
+
font-size: 0.75rem;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.text-sm {
|
|
288
|
+
font-size: 0.875rem;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.text-secondary {
|
|
292
|
+
color: var(--color-text-secondary);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.font-mono {
|
|
296
|
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.truncate {
|
|
300
|
+
overflow: hidden;
|
|
301
|
+
text-overflow: ellipsis;
|
|
302
|
+
white-space: nowrap;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.mb-2 {
|
|
306
|
+
margin-bottom: 0.5rem;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.mb-3 {
|
|
310
|
+
margin-bottom: 0.75rem;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.mt-2 {
|
|
314
|
+
margin-top: 0.5rem;
|
|
315
|
+
}
|
|
107
316
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
317
|
+
.mt-3 {
|
|
318
|
+
margin-top: 0.75rem;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.p-2 {
|
|
322
|
+
padding: 0.5rem;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.p-3 {
|
|
326
|
+
padding: 0.75rem;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.p-4 {
|
|
330
|
+
padding: 1rem;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.rounded {
|
|
334
|
+
border-radius: 0.375rem;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
.bg-gray-50 {
|
|
338
|
+
background-color: #f9fafb;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.bg-gray-900 {
|
|
342
|
+
background-color: #111827;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.dark .bg-gray-50 {
|
|
346
|
+
background-color: #1f2937;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.dark .bg-gray-900 {
|
|
350
|
+
background-color: #111827;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.text-green-400 {
|
|
354
|
+
color: #4ade80;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/* Loading animation */
|
|
358
|
+
.animate-spin {
|
|
359
|
+
animation: spin 1s linear infinite;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
@keyframes spin {
|
|
363
|
+
from {
|
|
364
|
+
transform: rotate(0deg);
|
|
365
|
+
}
|
|
366
|
+
to {
|
|
367
|
+
transform: rotate(360deg);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/* Syntax highlighting adjustments */
|
|
372
|
+
pre {
|
|
373
|
+
margin: 0;
|
|
374
|
+
overflow-x: auto;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
code {
|
|
378
|
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
379
|
+
font-size: 0.875rem;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/* Details/summary styling */
|
|
383
|
+
details {
|
|
384
|
+
margin: 0.5rem 0;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
summary {
|
|
388
|
+
cursor: pointer;
|
|
389
|
+
user-select: none;
|
|
390
|
+
padding: 0.5rem;
|
|
391
|
+
border-radius: 0.25rem;
|
|
392
|
+
transition: background-color 0.2s;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
summary:hover {
|
|
396
|
+
background-color: var(--color-bg-secondary);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/* Grid helpers */
|
|
400
|
+
.grid {
|
|
401
|
+
display: grid;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.grid-cols-2 {
|
|
405
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.gap-1 {
|
|
409
|
+
gap: 0.25rem;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.min-w-0 {
|
|
413
|
+
min-width: 0;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.flex-1 {
|
|
417
|
+
flex: 1;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
.flex-shrink-0 {
|
|
421
|
+
flex-shrink: 0;
|
|
422
|
+
}
|
|
423
|
+
</style>
|
|
424
|
+
</head>
|
|
425
|
+
<body>
|
|
426
|
+
<div class="app-container">
|
|
427
|
+
<!-- Header -->
|
|
428
|
+
<header>
|
|
429
|
+
<h1 class="header-title">AgentGUI</h1>
|
|
430
|
+
|
|
431
|
+
<div class="header-controls">
|
|
432
|
+
<div class="status-badge">
|
|
433
|
+
<div class="status-indicator" data-status="disconnected"></div>
|
|
434
|
+
<span data-status-indicator>Disconnected</span>
|
|
115
435
|
</div>
|
|
116
|
-
</div>
|
|
117
|
-
</div>
|
|
118
|
-
</div>
|
|
119
436
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
<div class="gm-modal-content" style="max-width: 400px;">
|
|
123
|
-
<div class="gm-modal-header">
|
|
124
|
-
<h3>New Chat</h3>
|
|
125
|
-
<button onclick="closeNewChatModal()" class="gm-btn-close">×</button>
|
|
126
|
-
</div>
|
|
127
|
-
<div class="gm-modal-body" style="gap: 1rem; flex-direction: column; padding: 2rem;">
|
|
128
|
-
<button class="chat-option-btn" onclick="createChatInWorkspace()">
|
|
129
|
-
<span class="chat-option-icon">💬</span>
|
|
130
|
-
<div class="chat-option-content">
|
|
131
|
-
<div class="chat-option-title">Chat in this workspace</div>
|
|
132
|
-
<div class="chat-option-desc">Default chat mode</div>
|
|
133
|
-
</div>
|
|
134
|
-
</button>
|
|
135
|
-
<button class="chat-option-btn" onclick="createChatInFolder()">
|
|
136
|
-
<span class="chat-option-icon">📁</span>
|
|
137
|
-
<div class="chat-option-content">
|
|
138
|
-
<div class="chat-option-title">Chat in folder</div>
|
|
139
|
-
<div class="chat-option-desc">Contextualize chat to a specific folder</div>
|
|
140
|
-
</div>
|
|
437
|
+
<button class="btn btn-primary" data-theme-toggle title="Toggle dark mode">
|
|
438
|
+
🌓 Theme
|
|
141
439
|
</button>
|
|
142
440
|
</div>
|
|
143
|
-
</
|
|
144
|
-
</div>
|
|
441
|
+
</header>
|
|
145
442
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
<div class="
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
<
|
|
443
|
+
<!-- Main Content -->
|
|
444
|
+
<main>
|
|
445
|
+
<!-- Execution Panel -->
|
|
446
|
+
<div class="execution-panel">
|
|
447
|
+
<div class="execution-input-group">
|
|
448
|
+
<select class="agent-selector" data-agent-selector title="Select agent">
|
|
449
|
+
<option value="claude-code">Claude Code</option>
|
|
450
|
+
<option value="opencode">OpenCode</option>
|
|
451
|
+
</select>
|
|
452
|
+
|
|
453
|
+
<textarea
|
|
454
|
+
class="execution-textarea"
|
|
455
|
+
data-message-input
|
|
456
|
+
placeholder="Enter command or prompt... (Ctrl+Enter to submit)"
|
|
457
|
+
aria-label="Execution prompt input"
|
|
458
|
+
></textarea>
|
|
157
459
|
</div>
|
|
158
|
-
<div id="folderBrowserList" style="flex: 1; overflow-y: auto; padding: 0; border: none;"></div>
|
|
159
|
-
</div>
|
|
160
|
-
<div class="gm-modal-footer">
|
|
161
|
-
<button onclick="confirmFolderSelection()" class="gm-btn gm-btn-primary">Select</button>
|
|
162
|
-
<button onclick="closeFolderBrowser()" class="gm-btn gm-btn-secondary">Cancel</button>
|
|
163
|
-
</div>
|
|
164
|
-
</div>
|
|
165
|
-
</div>
|
|
166
460
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
<div class="gm-modal-header">
|
|
171
|
-
<h3>Delete Chat</h3>
|
|
172
|
-
<button class="gm-btn-close" onclick="app.closeDeleteConfirmDialog()">×</button>
|
|
173
|
-
</div>
|
|
174
|
-
<div class="gm-modal-body" style="flex-direction: column; gap: 1rem; text-align: center;">
|
|
175
|
-
<p style="margin: 0; color: var(--text-primary);">Are you sure you want to delete this chat?</p>
|
|
176
|
-
<p style="margin: 0; font-size: 0.875rem; color: var(--text-tertiary);">This action cannot be undone.</p>
|
|
177
|
-
</div>
|
|
178
|
-
<div class="gm-modal-footer">
|
|
179
|
-
<button class="gm-btn-confirm gm-btn gm-btn-danger">Delete</button>
|
|
180
|
-
<button class="gm-btn-cancel gm-btn gm-btn-secondary">Cancel</button>
|
|
461
|
+
<button class="btn btn-primary" data-send-button title="Start execution (Ctrl+Enter)">
|
|
462
|
+
Execute
|
|
463
|
+
</button>
|
|
181
464
|
</div>
|
|
182
|
-
</div>
|
|
183
|
-
</div>
|
|
184
465
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
<div class="gm-modal-header">
|
|
189
|
-
<h3>Screenshot Captured</h3>
|
|
190
|
-
<button onclick="closeScreenshotModal()" class="gm-btn-close">×</button>
|
|
466
|
+
<!-- Output Container -->
|
|
467
|
+
<div id="output-scroll" role="region" aria-label="Execution output" aria-live="polite" aria-atomic="false">
|
|
468
|
+
<div id="output" class="output"></div>
|
|
191
469
|
</div>
|
|
192
|
-
|
|
193
|
-
<img id="screenshotImage" src="" alt="Screenshot" style="max-width: 100%; max-height: 60vh; border-radius: 0.5rem;" />
|
|
194
|
-
</div>
|
|
195
|
-
<div class="gm-modal-footer">
|
|
196
|
-
<button onclick="sendScreenshot()" class="gm-btn gm-btn-success">Send to Agent</button>
|
|
197
|
-
<button onclick="downloadScreenshot()" class="gm-btn gm-btn-secondary">Download</button>
|
|
198
|
-
<button onclick="closeScreenshotModal()" class="gm-btn gm-btn-secondary">Close</button>
|
|
199
|
-
</div>
|
|
200
|
-
</div>
|
|
470
|
+
</main>
|
|
201
471
|
</div>
|
|
202
472
|
|
|
203
|
-
<!--
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
473
|
+
<!-- Scripts - Order matters! -->
|
|
474
|
+
<!-- 1. Event Processor (no dependencies) -->
|
|
475
|
+
<script src="/gm/js/event-processor.js"></script>
|
|
476
|
+
|
|
477
|
+
<!-- 2. Streaming Renderer (no dependencies) -->
|
|
478
|
+
<script src="/gm/js/streaming-renderer.js"></script>
|
|
479
|
+
|
|
480
|
+
<!-- 3. WebSocket Manager (no dependencies) -->
|
|
481
|
+
<script src="/gm/js/websocket-manager.js"></script>
|
|
482
|
+
|
|
483
|
+
<!-- 4. Event Filter (depends on Streaming Renderer) -->
|
|
484
|
+
<script src="/gm/js/event-filter.js"></script>
|
|
485
|
+
|
|
486
|
+
<!-- 5. Syntax Highlighter (no dependencies) -->
|
|
487
|
+
<script src="/gm/js/syntax-highlighter.js"></script>
|
|
488
|
+
|
|
489
|
+
<!-- 6. UI Components (no dependencies) -->
|
|
490
|
+
<script src="/gm/js/ui-components.js"></script>
|
|
491
|
+
|
|
492
|
+
<!-- 7. Main Client (depends on all above) -->
|
|
493
|
+
<script src="/gm/js/client.js"></script>
|
|
494
|
+
|
|
495
|
+
<!-- Inline initialization -->
|
|
496
|
+
<script>
|
|
497
|
+
// Set initial theme based on preference
|
|
498
|
+
const savedTheme = localStorage.getItem('theme') || 'light';
|
|
499
|
+
if (savedTheme === 'dark') {
|
|
500
|
+
document.documentElement.classList.add('dark');
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Fallback error handler
|
|
504
|
+
window.addEventListener('error', (event) => {
|
|
505
|
+
console.error('Uncaught error:', event.error);
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
window.addEventListener('unhandledrejection', (event) => {
|
|
509
|
+
console.error('Unhandled rejection:', event.reason);
|
|
510
|
+
});
|
|
207
511
|
|
|
208
|
-
|
|
209
|
-
|
|
512
|
+
// Log client readiness
|
|
513
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
514
|
+
console.log('DOM loaded, waiting for client initialization');
|
|
515
|
+
});
|
|
516
|
+
</script>
|
|
210
517
|
</body>
|
|
211
518
|
</html>
|