agentgui 1.0.317 → 1.0.319

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 (3) hide show
  1. package/.prd +267 -0
  2. package/package.json +2 -1
  3. package/static/index.html +749 -565
package/static/index.html CHANGED
@@ -1,25 +1,26 @@
1
- <!DOCTYPE html>
2
- <html lang="en" class="light">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
6
- <meta name="description" content="AgentGUI - Real-time Claude Code Execution Visualization">
7
- <title>AgentGUI</title>
8
- <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' rx='20' fill='%233b82f6'/%3E%3Ctext x='50' y='68' font-size='50' font-family='sans-serif' font-weight='bold' fill='white' text-anchor='middle'%3EG%3C/text%3E%3C/svg%3E">
9
-
10
- <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
11
- <link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
12
- <link href="https://cdn.jsdelivr.net/npm/rippleui@1.12.1/dist/css/styles.css" rel="stylesheet">
13
- <link rel="preload" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-dark.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
14
- <noscript><link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-dark.css" rel="stylesheet"></noscript>
15
- <link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github-dark.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
16
- <noscript><link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github-dark.min.css" rel="stylesheet"></noscript>
17
- <script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
18
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/css/xterm.min.css">
19
- <script defer src="https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/lib/xterm.min.js"></script>
20
- <script defer src="https://cdn.jsdelivr.net/npm/@xterm/addon-fit@0.10.0/lib/addon-fit.min.js"></script>
21
-
22
- <style> *, *::before, *::after { box-sizing: border-box; }
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="light">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
6
+ <meta name="description" content="AgentGUI - Real-time Claude Code Execution Visualization">
7
+ <title>AgentGUI</title>
8
+ <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' rx='20' fill='%233b82f6'/%3E%3Ctext x='50' y='68' font-size='50' font-family='sans-serif' font-weight='bold' fill='white' text-anchor='middle'%3EG%3C/text%3E%3C/svg%3E">
9
+
10
+ <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
11
+ <link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
12
+ <link href="https://cdn.jsdelivr.net/npm/rippleui@1.12.1/dist/css/styles.css" rel="stylesheet">
13
+ <link rel="preload" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-dark.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
14
+ <noscript><link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-dark.css" rel="stylesheet"></noscript>
15
+ <link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github-dark.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
16
+ <noscript><link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github-dark.min.css" rel="stylesheet"></noscript>
17
+ <script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
18
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/css/xterm.min.css">
19
+ <script defer src="https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/lib/xterm.min.js"></script>
20
+ <script defer src="https://cdn.jsdelivr.net/npm/@xterm/addon-fit@0.10.0/lib/addon-fit.min.js"></script>
21
+
22
+ <style>
23
+ *, *::before, *::after { box-sizing: border-box; }
23
24
 
24
25
  :root {
25
26
  --color-primary: #F59E0B;
@@ -32,14 +33,13 @@
32
33
  --color-text-secondary: #737373;
33
34
  --color-text-tertiary: #A3A3A3;
34
35
  --color-border: #E5E7EB;
35
- --color-border-light: #F3F4F6;
36
+ --color-border-light: #F0F0EF;
36
37
  --color-success: #10b981;
37
38
  --color-error: #ef4444;
38
39
  --color-warning: #f59e0b;
39
40
  --color-info: #0891b2;
40
41
  --sidebar-width: 300px;
41
42
  --header-height: 52px;
42
- --msg-max-width: 100%;
43
43
  }
44
44
 
45
45
  html.dark {
@@ -54,9 +54,7 @@
54
54
  }
55
55
 
56
56
  html, body {
57
- margin: 0;
58
- padding: 0;
59
- height: 100%;
57
+ margin: 0; padding: 0; height: 100%;
60
58
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
61
59
  background-color: var(--color-bg-primary);
62
60
  color: var(--color-text-primary);
@@ -65,11 +63,10 @@
65
63
  letter-spacing: -0.011em;
66
64
  }
67
65
 
68
- /* ===== ROOT LAYOUT ===== */
66
+ /* ROOT LAYOUT */
69
67
  .app-shell {
70
68
  display: flex;
71
- height: 100dvh;
72
- height: 100vh;
69
+ height: 100dvh; height: 100vh;
73
70
  overflow: hidden;
74
71
  padding-top: env(safe-area-inset-top);
75
72
  padding-bottom: env(safe-area-inset-bottom);
@@ -77,23 +74,25 @@
77
74
  padding-right: env(safe-area-inset-right);
78
75
  }
79
76
 
80
- /* ===== SIDEBAR ===== */
77
+ /* SIDEBAR */
78
+ .sidebar-overlay {
79
+ display: none;
80
+ position: fixed; inset: 0; z-index: 99;
81
+ background: rgba(0,0,0,0.4);
82
+ }
83
+
81
84
  .sidebar {
82
85
  width: var(--sidebar-width);
83
86
  flex-shrink: 0;
84
87
  display: flex;
85
88
  flex-direction: column;
86
89
  background-color: var(--color-bg-secondary);
87
- overflow: hidden;
88
- transition: width 0.25s ease;
89
90
  border-right: 1px solid var(--color-border-light);
91
+ overflow: hidden;
92
+ transition: width 0.25s ease, min-width 0.25s ease;
90
93
  }
91
94
 
92
- .sidebar.collapsed {
93
- width: 0;
94
- min-width: 0;
95
- border-right: none;
96
- }
95
+ .sidebar.collapsed { width: 0; min-width: 0; border-right: none; }
97
96
 
98
97
  .sidebar-header {
99
98
  padding: 0.75rem 1rem;
@@ -112,671 +111,856 @@
112
111
  text-transform: uppercase;
113
112
  letter-spacing: 0.05em;
114
113
  color: var(--color-text-secondary);
114
+ white-space: nowrap;
115
+ }
116
+
117
+ .sidebar-header-actions {
118
+ display: flex; gap: 0.375rem; align-items: center; flex-shrink: 0;
119
+ }
120
+
121
+ .sidebar-clone-btn {
122
+ padding: 0.375rem 0.5rem;
123
+ font-size: 0.75rem;
124
+ background-color: transparent;
125
+ color: var(--color-text-secondary);
126
+ border: 1px solid var(--color-border-light);
127
+ border-radius: 4px;
128
+ cursor: pointer;
129
+ transition: all 0.15s;
130
+ }
131
+
132
+ .sidebar-clone-btn:hover {
133
+ background-color: var(--color-bg-tertiary);
134
+ color: var(--color-text-primary);
135
+ border-color: var(--color-border);
115
136
  }
116
137
 
117
138
  .sidebar-new-btn {
118
- padding: 0.375rem 0.75rem;
139
+ padding: 0.375rem 0.625rem;
119
140
  font-size: 0.75rem;
120
141
  background-color: var(--color-primary);
121
142
  color: white;
122
143
  border: none;
123
144
  border-radius: 6px;
124
145
  cursor: pointer;
125
- transition: background-color 0.2s;
146
+ transition: background-color 0.15s;
126
147
  font-weight: 500;
148
+ white-space: nowrap;
127
149
  }
128
150
 
129
- .sidebar-new-btn:hover {
130
- background-color: var(--color-primary-dark);
151
+ .sidebar-new-btn:hover { background-color: var(--color-primary-dark); }
152
+
153
+ .clone-input-bar {
154
+ display: flex; align-items: center; gap: 0.375rem;
155
+ padding: 0.375rem 0.75rem;
156
+ background: var(--color-bg-primary);
157
+ border-bottom: 1px solid var(--color-border-light);
158
+ flex-shrink: 0;
131
159
  }
132
160
 
133
- /* ===== MESSAGES CONTAINER ===== */
134
- .messages-wrapper {
135
- max-width: 768px;
136
- margin: 0 auto;
137
- width: 100%;
138
- padding: 1rem 1.5rem;
139
- display: flex;
140
- flex-direction: column;
141
- gap: 0;
161
+ .clone-input {
162
+ flex: 1; min-width: 0;
163
+ padding: 0.375rem 0.5rem;
164
+ font-size: 0.8rem;
165
+ font-family: 'Monaco','Menlo','Ubuntu Mono', monospace;
166
+ border: 1px solid var(--color-border);
167
+ border-radius: 4px;
168
+ background: var(--color-bg-secondary);
169
+ color: var(--color-text-primary);
170
+ outline: none;
142
171
  }
143
172
 
144
- .message {
145
- margin-bottom: 1.5rem;
146
- padding: 1rem 1.5rem;
147
- border-radius: 8px;
148
- max-width: 100%;
149
- word-break: break-word;
150
- transition: background-color 0.15s ease;
173
+ .clone-input:focus { border-color: var(--color-primary); }
174
+
175
+ .clone-go-btn {
176
+ padding: 0.375rem 0.625rem;
177
+ font-size: 0.75rem; font-weight: 600;
178
+ background: var(--color-primary); color: white;
179
+ border: none; border-radius: 4px; cursor: pointer;
180
+ transition: background-color 0.15s;
181
+ }
182
+
183
+ .clone-go-btn:hover { background-color: var(--color-primary-dark); }
184
+ .clone-go-btn:disabled { opacity: 0.5; cursor: not-allowed; }
185
+
186
+ .clone-cancel-btn {
187
+ padding: 0.25rem 0.5rem; font-size: 1rem;
188
+ background: none; border: none; cursor: pointer;
189
+ color: var(--color-text-secondary); line-height: 1;
190
+ }
191
+
192
+ .clone-cancel-btn:hover { color: var(--color-text-primary); }
193
+
194
+ .sidebar-list {
195
+ flex: 1; overflow-y: auto; overflow-x: hidden;
196
+ list-style: none; margin: 0; padding: 0.5rem;
197
+ -webkit-overflow-scrolling: touch;
198
+ }
199
+
200
+ .sidebar-empty {
201
+ padding: 2rem 1rem; text-align: center;
202
+ color: var(--color-text-secondary); font-size: 0.875rem;
203
+ }
204
+
205
+ .conversation-item {
206
+ padding: 0.625rem 0.75rem;
207
+ margin-bottom: 0.125rem;
208
+ background-color: transparent;
209
+ border: 1px solid transparent;
210
+ border-radius: 6px;
211
+ cursor: pointer;
212
+ transition: all 0.15s;
213
+ color: var(--color-text-primary);
214
+ font-size: 0.875rem;
215
+ display: flex;
216
+ align-items: center;
217
+ gap: 0.5rem;
218
+ user-select: none;
151
219
  }
152
220
 
153
- .message:hover {
221
+ .conversation-item:hover {
154
222
  background-color: var(--color-bg-tertiary);
155
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
223
+ border-color: var(--color-border-light);
156
224
  }
157
225
 
158
- .message-user {
226
+ .conversation-item.active {
159
227
  background-color: var(--color-bg-tertiary);
160
- color: var(--color-text-primary);
228
+ border-color: var(--color-primary);
229
+ font-weight: 500;
161
230
  }
162
231
 
163
- .message-user:hover {
164
- background-color: #E5E7EB;
232
+ .conversation-item-content {
233
+ flex: 1; min-width: 0; overflow: hidden;
165
234
  }
166
235
 
167
- html.dark .message-user:hover {
168
- background-color: #333333;
236
+ .conversation-item-title {
237
+ font-weight: 500; font-size: 0.875rem; margin: 0;
238
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
169
239
  }
170
240
 
171
- .message-assistant {
172
- background-color: transparent;
173
- color: var(--color-text-primary);
241
+ .conversation-item-meta {
242
+ font-size: 0.75rem; color: var(--color-text-secondary);
243
+ margin-top: 0.125rem; white-space: nowrap;
244
+ overflow: hidden; text-overflow: ellipsis;
174
245
  }
175
246
 
176
- .message-assistant + .message-assistant {
177
- margin-top: 0;
178
- padding-top: 0.5rem;
247
+ .conversation-item-delete {
248
+ flex-shrink: 0; width: 24px; height: 24px; padding: 0;
249
+ display: flex; align-items: center; justify-content: center;
250
+ background: transparent; border: none; border-radius: 4px;
251
+ cursor: pointer; color: var(--color-text-secondary);
252
+ opacity: 0; transition: all 0.15s;
179
253
  }
180
254
 
181
- .message-role {
182
- font-weight: 600;
183
- font-size: 0.7rem;
184
- text-transform: uppercase;
185
- letter-spacing: 0.04em;
186
- margin-bottom: 0.5rem;
187
- opacity: 0.6;
188
- color: var(--color-text-secondary);
255
+ .conversation-item:hover .conversation-item-delete { opacity: 1; }
256
+ .conversation-item-delete:hover { background-color: var(--color-error); color: white; }
257
+
258
+ .conversation-streaming-badge {
259
+ display: inline-flex; align-items: center;
260
+ margin-right: 0.25rem; vertical-align: middle;
189
261
  }
190
262
 
191
- .message-content {
192
- font-size: 15px;
193
- line-height: 1.65;
194
- white-space: pre-wrap;
195
- word-break: break-word;
263
+ .streaming-dot {
264
+ display: inline-block; width: 0.5rem; height: 0.5rem;
265
+ border-radius: 50%; background-color: var(--color-success);
266
+ animation: pulse 1.5s ease-in-out infinite;
196
267
  }
197
268
 
198
- .message-timestamp {
199
- font-size: 0.75rem;
200
- color: var(--color-text-tertiary);
201
- margin-top: 0.5rem;
202
- opacity: 0.6;
269
+ @keyframes pulse { 0%,100% { opacity:1; } 50% { opacity:0.4; } }
270
+
271
+ /* MAIN PANEL */
272
+ .main-panel {
273
+ flex: 1; display: flex; flex-direction: column;
274
+ overflow: hidden; min-width: 0;
275
+ background-color: var(--color-bg-primary);
203
276
  }
204
277
 
205
- /* ===== CODE BLOCKS ===== */
206
- code, pre {
207
- font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
208
- font-size: 14px;
209
- line-height: 1.5;
278
+ /* HEADER */
279
+ .main-header {
280
+ display: flex; align-items: center; gap: 0.75rem;
281
+ padding: 0 1rem;
282
+ height: var(--header-height); min-height: var(--header-height);
283
+ flex-shrink: 0;
284
+ background-color: var(--color-bg-secondary);
285
+ border-bottom: 1px solid var(--color-border-light);
210
286
  }
211
287
 
212
- pre {
213
- background-color: var(--color-bg-code);
214
- color: #E5E7EB;
215
- padding: 1rem;
216
- border-radius: 8px;
217
- overflow-x: auto;
218
- margin: 0.5rem 0;
219
- border: 1px solid var(--color-border);
288
+ .sidebar-toggle-btn {
289
+ display: flex; align-items: center; justify-content: center;
290
+ width: 36px; height: 36px;
291
+ background: none; border: none; border-radius: 6px;
292
+ cursor: pointer; color: var(--color-text-secondary);
293
+ flex-shrink: 0; transition: background-color 0.15s, color 0.15s;
220
294
  }
221
295
 
222
- code {
296
+ .sidebar-toggle-btn:hover {
223
297
  background-color: var(--color-bg-tertiary);
224
298
  color: var(--color-text-primary);
225
- padding: 0.2em 0.4em;
226
- border-radius: 4px;
227
- font-size: 0.9em;
228
299
  }
229
300
 
230
- pre code {
231
- background-color: transparent;
232
- color: inherit;
233
- padding: 0;
301
+ .sidebar-toggle-btn svg { width: 18px; height: 18px; }
302
+
303
+ .header-title {
304
+ font-size: 0.95rem; font-weight: 600; margin: 0;
305
+ flex: 1; min-width: 0;
306
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
307
+ color: var(--color-text-primary);
234
308
  }
235
309
 
236
- /* ===== BUTTONS & INPUTS ===== */
237
- button {
238
- background-color: var(--color-primary);
239
- color: white;
240
- border: none;
241
- padding: 0.5rem 1rem;
242
- border-radius: 6px;
243
- cursor: pointer;
244
- font-size: 0.875rem;
245
- transition: background-color 0.2s;
246
- font-weight: 500;
310
+ .header-controls {
311
+ display: flex; gap: 0.375rem; align-items: center; flex-shrink: 0;
247
312
  }
248
313
 
249
- button:hover {
250
- background-color: var(--color-primary-dark);
314
+ .header-icon-btn {
315
+ display: flex; align-items: center; justify-content: center;
316
+ width: 36px; height: 36px;
317
+ background: none; border: none; border-radius: 6px;
318
+ cursor: pointer; color: var(--color-text-secondary);
319
+ transition: background-color 0.15s, color 0.15s;
251
320
  }
252
321
 
253
- input, textarea {
254
- background-color: var(--color-bg-secondary);
322
+ .header-icon-btn:hover {
323
+ background-color: var(--color-bg-tertiary);
255
324
  color: var(--color-text-primary);
325
+ }
326
+
327
+ .header-icon-btn svg { width: 18px; height: 18px; }
328
+
329
+ #scriptStartBtn { color: var(--color-success); }
330
+ #scriptStartBtn:hover { background-color: rgba(16,185,129,0.1); color: var(--color-success); }
331
+ .script-dev-btn { color: var(--color-info); }
332
+ .script-dev-btn:hover { background-color: rgba(8,145,178,0.1); color: var(--color-info); }
333
+ .script-stop-btn { color: var(--color-error); }
334
+ .script-stop-btn:hover { background-color: rgba(239,68,68,0.1); color: var(--color-error); }
335
+
336
+ .script-buttons { display: flex; gap: 0.25rem; align-items: center; }
337
+
338
+ .agent-auth-btn { color: var(--color-text-secondary); position: relative; }
339
+ .agent-auth-btn.auth-ok { color: var(--color-success); }
340
+ .agent-auth-btn.auth-warn { color: var(--color-warning); }
341
+
342
+ .agent-auth-dropdown {
343
+ position: absolute; top: 100%; right: 0; z-index: 100;
344
+ min-width: 260px; padding: 0.25rem 0;
345
+ background: var(--color-bg-secondary);
256
346
  border: 1px solid var(--color-border);
257
- border-radius: 6px;
258
- padding: 0.5rem 0.75rem;
259
- font-size: 0.875rem;
347
+ border-radius: 8px;
348
+ box-shadow: 0 4px 16px rgba(0,0,0,0.12);
349
+ display: none;
260
350
  }
261
351
 
262
- input:focus, textarea:focus {
263
- outline: none;
264
- border-color: var(--color-primary);
265
- box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.1);
352
+ .agent-auth-dropdown.open { display: block; }
353
+
354
+ .agent-auth-item {
355
+ display: flex; align-items: center; gap: 0.5rem;
356
+ padding: 0.5rem 0.75rem; cursor: pointer; font-size: 0.8125rem;
357
+ color: var(--color-text-primary); border: none; background: none;
358
+ width: 100%; text-align: left; transition: background 0.1s;
266
359
  }
267
360
 
268
- /* ===== SIDEBAR ITEMS ===== */
269
- .sidebar-header-actions {
270
- display: flex;
271
- gap: 0.375rem;
272
- align-items: center;
273
- flex-shrink: 0;
361
+ .agent-auth-item:hover { background: var(--color-bg-tertiary); }
362
+
363
+ .agent-auth-dot {
364
+ width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
274
365
  }
275
366
 
276
- .sidebar-clone-btn, .sidebar-settings-btn, .sidebar-collapse-btn {
277
- padding: 0.375rem 0.5rem;
278
- font-size: 0.75rem;
279
- background-color: transparent;
367
+ .agent-auth-dot.ok { background: var(--color-success); }
368
+ .agent-auth-dot.missing { background: var(--color-warning); }
369
+ .agent-auth-dot.unknown { background: var(--color-text-secondary); }
370
+
371
+ .agent-auth-section-header {
372
+ padding: 0.375rem 0.75rem; font-size: 0.6875rem; font-weight: 600;
373
+ text-transform: uppercase; letter-spacing: 0.05em;
374
+ color: var(--color-text-secondary); user-select: none;
375
+ }
376
+
377
+ .status-badge {
378
+ display: inline-flex; align-items: center; gap: 0.375rem;
379
+ padding: 0.25rem 0.625rem;
380
+ border-radius: 1rem; font-size: 0.75rem; font-weight: 500;
381
+ background-color: var(--color-bg-tertiary);
280
382
  color: var(--color-text-secondary);
281
383
  border: 1px solid var(--color-border-light);
282
- border-radius: 4px;
283
- cursor: pointer;
284
- transition: all 0.2s;
285
384
  }
286
385
 
287
- .sidebar-clone-btn:hover, .sidebar-settings-btn:hover, .sidebar-collapse-btn:hover {
386
+ .status-indicator {
387
+ width: 0.5rem; height: 0.5rem; border-radius: 50%;
388
+ background-color: var(--color-error);
389
+ animation: pulse 2s infinite;
390
+ }
391
+
392
+ .status-indicator[data-status="connected"] { background-color: var(--color-success); }
393
+ .status-indicator[data-status="reconnecting"],
394
+ .status-indicator[data-status="connecting"] { background-color: var(--color-warning); animation: pulse 1s infinite; }
395
+
396
+ .theme-toggle-btn {
397
+ display: flex; align-items: center; justify-content: center;
398
+ width: 36px; height: 36px;
399
+ background: none; border: none; border-radius: 6px;
400
+ cursor: pointer; color: var(--color-text-secondary);
401
+ transition: background-color 0.15s, color 0.15s;
402
+ }
403
+
404
+ .theme-toggle-btn:hover {
288
405
  background-color: var(--color-bg-tertiary);
289
406
  color: var(--color-text-primary);
290
- border-color: var(--color-border);
291
407
  }
292
408
 
293
- .sidebar-list {
294
- flex: 1;
295
- overflow-y: auto;
296
- overflow-x: hidden;
297
- padding: 0.5rem;
409
+ .theme-toggle-btn svg { width: 18px; height: 18px; }
410
+
411
+ /* VIEW TOGGLE BAR */
412
+ .view-toggle-bar {
413
+ display: flex; gap: 0;
414
+ background: var(--color-bg-secondary);
415
+ border-bottom: 1px solid var(--color-border-light);
416
+ flex-shrink: 0; padding: 0 1rem;
298
417
  }
299
418
 
300
- .conversation-item {
301
- padding: 0.75rem;
302
- margin-bottom: 0.5rem;
303
- background-color: transparent;
304
- border: 1px solid transparent;
305
- border-radius: 6px;
306
- cursor: pointer;
307
- transition: all 0.2s;
308
- color: var(--color-text-primary);
309
- font-size: 0.875rem;
310
- display: flex;
311
- align-items: center;
312
- gap: 0.5rem;
419
+ .view-toggle-btn {
420
+ padding: 0.5rem 1rem;
421
+ border: none; background: none; cursor: pointer;
422
+ font-size: 0.875rem; font-weight: 500;
423
+ color: var(--color-text-secondary);
424
+ border-bottom: 2px solid transparent;
425
+ transition: color 0.15s, border-color 0.15s;
426
+ margin-bottom: -1px;
313
427
  }
314
428
 
315
- .conversation-item:hover {
316
- background-color: var(--color-bg-tertiary);
317
- border-color: var(--color-border-light);
429
+ .view-toggle-btn:hover { color: var(--color-text-primary); }
430
+
431
+ .view-toggle-btn.active {
432
+ color: var(--color-primary);
433
+ border-bottom-color: var(--color-primary);
318
434
  }
319
435
 
320
- .conversation-item.active {
321
- background-color: var(--color-bg-tertiary);
322
- border-color: var(--color-primary);
323
- font-weight: 500;
436
+ /* OUTPUT SCROLL */
437
+ #output-scroll {
438
+ flex: 1; overflow-y: auto; overflow-x: hidden;
439
+ background-color: var(--color-bg-primary);
440
+ position: relative;
324
441
  }
325
442
 
326
- .conversation-item-content {
327
- flex: 1;
328
- min-width: 0;
329
- overflow: hidden;
330
- text-overflow: ellipsis;
331
- white-space: nowrap;
443
+ .messages-wrapper {
444
+ max-width: 768px; margin: 0 auto; width: 100%;
445
+ padding: 1rem 1.5rem;
332
446
  }
333
447
 
334
- .conversation-item-time {
335
- font-size: 0.75rem;
336
- color: var(--color-text-tertiary);
337
- flex-shrink: 0;
448
+ #output { width: 100%; }
449
+
450
+ /* DROP ZONE */
451
+ .drop-zone-overlay {
452
+ display: none;
453
+ position: absolute; inset: 0; z-index: 50;
454
+ background: rgba(245,158,11,0.08);
455
+ border: 2px dashed var(--color-primary);
456
+ border-radius: 8px;
457
+ align-items: center; justify-content: center;
338
458
  }
339
459
 
340
- /* ===== MAIN CONTENT ===== */
341
- .main-content {
342
- flex: 1;
343
- display: flex;
344
- flex-direction: column;
345
- overflow: hidden;
460
+ .drop-zone-overlay.active { display: flex; }
461
+
462
+ .drop-zone-content {
463
+ text-align: center; pointer-events: none;
346
464
  }
347
465
 
348
- .header {
349
- flex-shrink: 0;
350
- padding: 0 1.5rem;
351
- height: var(--header-height);
352
- display: flex;
353
- align-items: center;
354
- justify-content: space-between;
355
- background-color: var(--color-bg-secondary);
356
- border-bottom: 1px solid var(--color-border-light);
466
+ .drop-zone-icon {
467
+ font-size: 3rem; color: var(--color-primary); line-height: 1;
357
468
  }
358
469
 
359
- .header-title {
360
- font-size: 0.95rem;
361
- font-weight: 600;
470
+ .drop-zone-text {
471
+ font-size: 1rem; font-weight: 500; color: var(--color-primary);
472
+ margin-top: 0.5rem;
473
+ }
474
+
475
+ /* FILE BROWSER */
476
+ .file-browser-container {
477
+ flex: 1; display: flex; flex-direction: column; overflow: hidden;
478
+ }
479
+
480
+ .file-browser-iframe { flex: 1; border: none; width: 100%; height: 100%; }
481
+
482
+ /* TERMINAL */
483
+ .terminal-container {
484
+ flex: 1; display: flex; flex-direction: column; overflow: hidden;
485
+ background: #1e1e1e;
486
+ }
487
+
488
+ .terminal-output { flex: 1; overflow: hidden; }
489
+
490
+ /* VOICE */
491
+ .voice-container {
492
+ flex: 1; display: flex; flex-direction: column; overflow: hidden;
493
+ }
494
+
495
+ .voice-scroll {
496
+ flex: 1; overflow-y: auto; padding: 1rem 1.5rem;
497
+ }
498
+
499
+ .voice-messages { display: flex; flex-direction: column; gap: 1rem; }
500
+
501
+ .voice-input-section {
502
+ flex-shrink: 0; padding: 0.75rem 1rem;
503
+ background: var(--color-bg-secondary);
504
+ border-top: 1px solid var(--color-border-light);
505
+ }
506
+
507
+ .voice-input-wrapper {
508
+ display: flex; align-items: center; gap: 0.5rem;
509
+ margin-bottom: 0.5rem;
510
+ }
511
+
512
+ .voice-transcript {
513
+ flex: 1; min-height: 2.5rem;
514
+ padding: 0.5rem 0.75rem;
515
+ border: 1px solid var(--color-border);
516
+ border-radius: 6px;
517
+ background: var(--color-bg-primary);
362
518
  color: var(--color-text-primary);
363
- margin: 0;
519
+ font-size: 0.875rem;
364
520
  }
365
521
 
366
- .header-actions {
367
- display: flex;
368
- gap: 0.5rem;
369
- align-items: center;
522
+ .voice-mic-btn, .voice-send-btn, .voice-stop-btn {
523
+ display: flex; align-items: center; justify-content: center;
524
+ width: 40px; height: 40px; padding: 0;
525
+ border-radius: 50%; border: none; cursor: pointer;
526
+ transition: all 0.15s; flex-shrink: 0;
370
527
  }
371
528
 
372
- .theme-toggle, .settings-btn {
373
- background-color: transparent;
374
- color: var(--color-text-secondary);
529
+ .voice-mic-btn { background: var(--color-bg-tertiary); color: var(--color-text-primary); }
530
+ .voice-mic-btn:hover { background: var(--color-border); }
531
+ .voice-mic-btn.recording { background: var(--color-error); color: white; }
532
+
533
+ .voice-send-btn { background: var(--color-primary); color: white; }
534
+ .voice-send-btn:hover { background: var(--color-primary-dark); }
535
+
536
+ .voice-stop-btn {
537
+ padding: 0.375rem 0.75rem; width: auto; height: auto;
538
+ border-radius: 6px; font-size: 0.8rem;
539
+ background: var(--color-bg-tertiary); color: var(--color-text-secondary);
375
540
  border: 1px solid var(--color-border-light);
376
- padding: 0.375rem 0.625rem;
377
- font-size: 0.75rem;
378
- border-radius: 4px;
379
- cursor: pointer;
380
- transition: all 0.2s;
381
541
  }
382
542
 
383
- .theme-toggle:hover, .settings-btn:hover {
384
- background-color: var(--color-bg-tertiary);
385
- color: var(--color-text-primary);
386
- border-color: var(--color-border);
543
+ .voice-stop-btn:hover { background: var(--color-error); color: white; border-color: var(--color-error); }
544
+
545
+ .voice-tts-controls {
546
+ display: flex; align-items: center; gap: 0.75rem;
547
+ font-size: 0.8125rem; color: var(--color-text-secondary);
387
548
  }
388
549
 
389
- /* ===== OUTPUT SCROLL AREA ===== */
390
- #output-scroll {
391
- flex: 1;
392
- overflow-y: auto;
393
- overflow-x: hidden;
394
- background-color: var(--color-bg-primary);
550
+ .voice-toggle-label {
551
+ display: flex; align-items: center; gap: 0.375rem; cursor: pointer;
395
552
  }
396
553
 
397
- #output {
398
- width: 100%;
399
- padding: 1rem 0;
554
+ .voice-selector-wrapper { display: flex; align-items: center; }
555
+
556
+ .voice-selector, .agent-selector, .model-selector {
557
+ padding: 0.375rem 0.5rem;
558
+ font-size: 0.8125rem;
559
+ background: var(--color-bg-secondary);
560
+ color: var(--color-text-primary);
561
+ border: 1px solid var(--color-border);
562
+ border-radius: 6px; cursor: pointer;
563
+ transition: border-color 0.15s;
400
564
  }
401
565
 
402
- /* ===== INPUT AREA ===== */
403
- .input-area {
566
+ .voice-selector:focus, .agent-selector:focus, .model-selector:focus {
567
+ outline: none; border-color: var(--color-primary);
568
+ }
569
+
570
+ .voice-agent-selector { font-size: 0.8125rem; }
571
+
572
+ /* INPUT SECTION */
573
+ .input-section {
404
574
  flex-shrink: 0;
405
- padding: 1rem 1.5rem;
575
+ padding: 0.75rem 1rem;
406
576
  background-color: var(--color-bg-secondary);
407
577
  border-top: 1px solid var(--color-border-light);
408
- display: flex;
409
- gap: 0.75rem;
410
- align-items: flex-end;
411
- }
412
-
413
- .input-group {
414
- flex: 1;
415
- display: flex;
416
- flex-direction: column;
417
- gap: 0.5rem;
418
578
  }
419
579
 
420
- .input-group label {
421
- font-size: 0.75rem;
422
- font-weight: 600;
423
- color: var(--color-text-secondary);
424
- text-transform: uppercase;
425
- letter-spacing: 0.05em;
580
+ .input-wrapper {
581
+ display: flex; align-items: flex-end; gap: 0.5rem;
582
+ max-width: 768px; margin: 0 auto;
426
583
  }
427
584
 
428
- .input-group textarea {
429
- min-height: 3rem;
430
- max-height: 8rem;
431
- resize: vertical;
432
- background-color: var(--color-bg-secondary);
585
+ .message-textarea {
586
+ flex: 1;
587
+ min-height: 2.5rem; max-height: 12rem;
588
+ resize: none;
589
+ background-color: var(--color-bg-primary);
433
590
  color: var(--color-text-primary);
434
591
  border: 1px solid var(--color-border);
435
- border-radius: 6px;
436
- padding: 0.75rem;
437
- font-family: inherit;
438
- font-size: 0.875rem;
592
+ border-radius: 8px;
593
+ padding: 0.625rem 0.75rem;
594
+ font-family: inherit; font-size: 0.9375rem;
595
+ line-height: 1.5;
596
+ transition: border-color 0.15s, box-shadow 0.15s;
597
+ outline: none;
439
598
  }
440
599
 
441
- .input-group textarea:focus {
442
- outline: none;
600
+ .message-textarea:focus {
443
601
  border-color: var(--color-primary);
444
- box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.1);
602
+ box-shadow: 0 0 0 2px rgba(245,158,11,0.1);
445
603
  }
446
604
 
447
- .send-btn {
448
- padding: 0.625rem 1rem;
449
- background-color: var(--color-primary);
450
- color: white;
451
- border: none;
452
- border-radius: 6px;
453
- cursor: pointer;
454
- font-weight: 500;
455
- transition: background-color 0.2s;
456
- white-space: nowrap;
605
+ .send-btn, .stop-btn, .inject-btn {
606
+ display: flex; align-items: center; justify-content: center;
607
+ width: 36px; height: 36px; padding: 0;
608
+ border: none; border-radius: 6px; cursor: pointer;
609
+ flex-shrink: 0; transition: all 0.15s;
457
610
  }
458
611
 
459
- .send-btn:hover {
460
- background-color: var(--color-primary-dark);
461
- }
612
+ .send-btn { background-color: var(--color-primary); color: white; }
613
+ .send-btn:hover { background-color: var(--color-primary-dark); }
614
+ .send-btn:disabled { opacity: 0.4; cursor: not-allowed; }
462
615
 
463
- .send-btn:disabled {
464
- opacity: 0.5;
465
- cursor: not-allowed;
466
- }
616
+ .stop-btn { background-color: var(--color-error); color: white; }
617
+ .stop-btn:hover { background-color: #dc2626; }
467
618
 
468
- /* ===== MODALS & DIALOGS ===== */
469
- .modal-overlay {
470
- position: fixed;
471
- top: 0;
472
- left: 0;
473
- right: 0;
474
- bottom: 0;
475
- background-color: rgba(0, 0, 0, 0.5);
476
- display: flex;
477
- align-items: center;
478
- justify-content: center;
479
- z-index: 1000;
619
+ .inject-btn { background-color: var(--color-bg-tertiary); color: var(--color-text-secondary); border: 1px solid var(--color-border-light); }
620
+ .inject-btn:hover { background-color: var(--color-border); color: var(--color-text-primary); }
621
+
622
+ /* FOLDER MODAL */
623
+ .folder-modal-overlay {
624
+ display: none;
625
+ position: fixed; inset: 0; z-index: 200;
626
+ background: rgba(0,0,0,0.5);
627
+ align-items: center; justify-content: center;
480
628
  }
481
629
 
482
- .modal {
483
- background-color: var(--color-bg-secondary);
630
+ .folder-modal-overlay.open { display: flex; }
631
+
632
+ .folder-modal {
633
+ background: var(--color-bg-secondary);
484
634
  border-radius: 8px;
485
- box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
486
- max-width: 90%;
487
- max-height: 90vh;
488
- overflow: auto;
489
- padding: 1.5rem;
635
+ box-shadow: 0 8px 32px rgba(0,0,0,0.15);
636
+ width: 480px; max-width: 90vw; max-height: 70vh;
637
+ display: flex; flex-direction: column; overflow: hidden;
490
638
  }
491
639
 
492
- .modal-header {
493
- font-size: 1.125rem;
494
- font-weight: 600;
640
+ .folder-modal-header {
641
+ display: flex; align-items: center; justify-content: space-between;
642
+ padding: 1rem 1.25rem;
643
+ border-bottom: 1px solid var(--color-border-light);
644
+ }
645
+
646
+ .folder-modal-header h3 {
647
+ margin: 0; font-size: 1rem; font-weight: 600;
495
648
  color: var(--color-text-primary);
496
- margin-bottom: 1rem;
497
649
  }
498
650
 
499
- .modal-content {
500
- color: var(--color-text-secondary);
501
- margin-bottom: 1rem;
651
+ .folder-modal-close {
652
+ display: flex; align-items: center; justify-content: center;
653
+ width: 28px; height: 28px; padding: 0;
654
+ background: none; border: none; border-radius: 4px;
655
+ cursor: pointer; color: var(--color-text-secondary); font-size: 1.25rem;
656
+ transition: all 0.15s;
502
657
  }
503
658
 
504
- .modal-actions {
505
- display: flex;
506
- gap: 0.75rem;
507
- justify-content: flex-end;
659
+ .folder-modal-close:hover { background: var(--color-bg-tertiary); color: var(--color-text-primary); }
660
+
661
+ .folder-breadcrumb {
662
+ padding: 0.5rem 1.25rem;
663
+ font-size: 0.8rem; color: var(--color-text-secondary);
664
+ border-bottom: 1px solid var(--color-border-light);
665
+ background: var(--color-bg-tertiary);
508
666
  }
509
667
 
510
- /* ===== SCROLLBARS ===== */
511
- ::-webkit-scrollbar {
512
- width: 8px;
513
- height: 8px;
668
+ .folder-list {
669
+ flex: 1; overflow-y: auto;
670
+ list-style: none; margin: 0; padding: 0.5rem;
514
671
  }
515
672
 
516
- ::-webkit-scrollbar-track {
517
- background-color: transparent;
673
+ .folder-list-loading {
674
+ padding: 1rem; text-align: center;
675
+ color: var(--color-text-secondary); font-size: 0.875rem;
518
676
  }
519
677
 
520
- ::-webkit-scrollbar-thumb {
521
- background-color: var(--color-border);
522
- border-radius: 4px;
678
+ .folder-modal-footer {
679
+ padding: 0.75rem 1.25rem;
680
+ border-top: 1px solid var(--color-border-light);
681
+ display: flex; justify-content: flex-end; gap: 0.5rem;
523
682
  }
524
683
 
525
- ::-webkit-scrollbar-thumb:hover {
526
- background-color: var(--color-text-secondary);
684
+ .btn {
685
+ padding: 0.5rem 1rem;
686
+ font-size: 0.875rem; font-weight: 500;
687
+ border-radius: 6px; cursor: pointer; border: none;
688
+ transition: all 0.15s;
527
689
  }
528
690
 
529
- /* ===== RESPONSIVE ===== */
530
- @media (max-width: 768px) {
531
- .sidebar {
532
- position: absolute;
533
- left: 0;
534
- top: 0;
535
- bottom: 0;
536
- z-index: 100;
537
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
538
- }
691
+ .btn-primary { background: var(--color-primary); color: white; }
692
+ .btn-primary:hover { background: var(--color-primary-dark); }
539
693
 
540
- .sidebar.collapsed {
541
- display: none;
542
- }
694
+ .btn-secondary {
695
+ background: var(--color-bg-tertiary); color: var(--color-text-primary);
696
+ border: 1px solid var(--color-border);
697
+ }
543
698
 
544
- .main-content {
545
- width: 100%;
546
- }
699
+ .btn-secondary:hover { background: var(--color-border); }
547
700
 
548
- .messages-wrapper {
549
- padding: 0.75rem 1rem;
550
- }
701
+ /* CODE BLOCKS */
702
+ code, pre {
703
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
704
+ font-size: 13px; line-height: 1.5;
705
+ }
551
706
 
552
- .message {
553
- padding: 0.75rem 1rem;
554
- margin-bottom: 1rem;
555
- }
707
+ pre {
708
+ background-color: var(--color-bg-code);
709
+ color: #E5E7EB;
710
+ padding: 1rem; border-radius: 8px;
711
+ overflow-x: auto; margin: 0.5rem 0;
712
+ border: 1px solid rgba(255,255,255,0.05);
713
+ }
714
+
715
+ code {
716
+ background-color: var(--color-bg-tertiary);
717
+ color: var(--color-text-primary);
718
+ padding: 0.2em 0.4em;
719
+ border-radius: 4px; font-size: 0.9em;
556
720
  }
557
- </style>
558
- </head>
559
- <body>
560
- <!-- Sidebar overlay (mobile) -->
561
- <div class="sidebar-overlay" data-sidebar-overlay></div>
562
-
563
- <div class="app-shell">
564
- <!-- ===== SIDEBAR ===== -->
565
- <aside class="sidebar" data-sidebar>
566
- <div class="sidebar-header">
567
- <h2>History</h2>
568
- <div class="sidebar-header-actions">
569
- <button id="cloneRepoBtn" class="sidebar-clone-btn" data-clone-repo title="Clone a GitHub repo">Clone</button>
570
- <button id="newConversationBtn" class="sidebar-new-btn" data-new-conversation title="Start new conversation">+ New</button>
571
- </div>
572
- </div>
573
- <div class="clone-input-bar" id="cloneInputBar" style="display:none;">
574
- <input type="text" class="clone-input" id="cloneRepoInput" placeholder="org/repo" autocomplete="off" spellcheck="false">
575
- <button class="clone-go-btn" id="cloneGoBtn" title="Clone">Go</button>
576
- <button class="clone-cancel-btn" id="cloneCancelBtn" title="Cancel">&times;</button>
577
- </div>
578
- <ul class="sidebar-list" data-conversation-list>
579
- <li class="sidebar-empty" data-conversation-empty>No conversations yet</li>
580
- </ul>
581
- </aside>
582
-
583
- <!-- ===== MAIN PANEL ===== -->
584
- <main id="app" class="main-panel">
585
- <!-- Header bar -->
586
- <div class="main-header">
587
- <button class="sidebar-toggle-btn" data-sidebar-toggle title="Toggle sidebar (Ctrl+B)" aria-label="Toggle sidebar">
588
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
589
- <line x1="3" y1="6" x2="21" y2="6"></line>
590
- <line x1="3" y1="12" x2="21" y2="12"></line>
591
- <line x1="3" y1="18" x2="21" y2="18"></line>
592
- </svg>
593
- </button>
594
-
595
- <h1 class="header-title">AgentGUI</h1>
596
-
597
- <div class="header-controls">
598
- <div class="script-buttons" id="scriptButtons" style="display:none;">
599
- <button class="header-icon-btn" id="scriptStartBtn" title="Run start script" aria-label="Run start script" style="display:none;">
600
- <svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><polygon points="6,3 20,12 6,21"></polygon></svg>
601
- </button>
602
- <button class="header-icon-btn script-dev-btn" id="scriptDevBtn" title="Run dev script" aria-label="Run dev script" style="display:none;">
603
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>
604
- </button>
605
- <button class="header-icon-btn script-stop-btn" id="scriptStopBtn" title="Stop running script" aria-label="Stop running script" style="display:none;">
606
- <svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><rect x="5" y="5" width="14" height="14" rx="1"></rect></svg>
607
- </button>
608
- </div>
609
- <button class="header-icon-btn agent-auth-btn" id="agentAuthBtn" title="Agent authentication" aria-label="Agent authentication" style="display:none;">
610
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg>
611
- <div class="agent-auth-dropdown" id="agentAuthDropdown"></div>
612
- </button>
613
- <div class="status-badge">
614
- <div class="status-indicator" data-status="disconnected"></div>
615
- <span id="connectionStatus" data-status-indicator>Disconnected</span>
616
- </div>
617
- <button class="theme-toggle-btn" data-theme-toggle title="Toggle dark mode" aria-label="Toggle dark mode">
618
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
619
- <circle cx="12" cy="12" r="5"></circle>
620
- <line x1="12" y1="1" x2="12" y2="3"></line>
621
- <line x1="12" y1="21" x2="12" y2="23"></line>
622
- <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
623
- <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
624
- <line x1="1" y1="12" x2="3" y2="12"></line>
625
- <line x1="21" y1="12" x2="23" y2="12"></line>
626
- <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
627
- <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
628
- </svg>
629
- </button>
630
- </div>
631
- </div>
632
-
633
- <!-- View toggle bar (hidden by default) -->
634
- <div class="view-toggle-bar" id="viewToggleBar" style="display:none;">
635
- <button class="view-toggle-btn active" data-view="chat">Chat</button>
636
- <button class="view-toggle-btn" data-view="files">Files</button>
637
- <button class="view-toggle-btn" data-view="voice" style="display:none;">Voice</button>
638
- <button class="view-toggle-btn" data-view="terminal" id="terminalTabBtn" style="display:none;">Terminal</button>
639
- </div>
640
-
641
- <!-- Messages scroll area -->
642
- <div id="output-scroll" role="region" aria-label="Chat messages" aria-live="polite" data-drop-zone>
643
- <div class="messages-wrapper">
644
- <div id="output"></div>
645
- </div>
646
- <div class="drop-zone-overlay" id="dropZoneOverlay">
647
- <div class="drop-zone-content">
648
- <div class="drop-zone-icon">+</div>
649
- <div class="drop-zone-text">Drop files here to copy to working directory</div>
650
- </div>
651
- </div>
652
- </div>
653
-
654
- <!-- File browser (hidden by default) -->
655
- <div id="fileBrowserContainer" class="file-browser-container" style="display:none;">
656
- <iframe id="fileBrowserIframe" class="file-browser-iframe"></iframe>
657
- </div>
658
-
659
- <!-- Terminal output view -->
660
- <div id="terminalContainer" class="terminal-container" style="display:none;">
661
- <div id="terminalOutput" class="terminal-output"></div>
662
- </div>
663
-
664
- <!-- Voice STT/TTS view -->
665
- <div id="voiceContainer" class="voice-container" style="display:none;">
666
- <div id="voiceScroll" class="voice-scroll">
667
- <div class="voice-messages" id="voiceMessages"></div>
668
- </div>
669
- <div class="voice-input-section">
670
- <div class="voice-input-wrapper">
671
- <select class="agent-selector voice-agent-selector" data-voice-agent-selector title="Select agent"></select>
672
- <div class="voice-transcript" id="voiceTranscript" data-placeholder="Tap mic and speak..."></div>
673
- <button class="voice-mic-btn" id="voiceMicBtn" title="Toggle recording" aria-label="Voice input">
674
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
675
- <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
676
- <path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
677
- <line x1="12" y1="19" x2="12" y2="23"/>
678
- <line x1="8" y1="23" x2="16" y2="23"/>
679
- </svg>
680
- </button>
681
- <button class="send-btn voice-send-btn" id="voiceSendBtn" title="Send message" aria-label="Send message">
682
- <svg viewBox="0 0 24 24" fill="currentColor">
683
- <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
684
- </svg>
685
- </button>
686
- </div>
687
- <div class="voice-tts-controls">
688
- <label class="voice-toggle-label">
689
- <input type="checkbox" id="voiceTTSToggle" checked>
690
- <span>Auto-speak responses</span>
691
- </label>
692
- <div class="voice-selector-wrapper">
693
- <select class="voice-selector" id="voiceSelector" title="Select voice">
694
- <option value="default">Default</option>
695
- </select>
696
- </div>
697
- <button class="voice-stop-btn" id="voiceStopSpeaking" title="Stop speaking">Stop</button>
698
- </div>
699
- </div>
700
- </div>
701
-
702
- <!-- Input area: fixed at bottom -->
703
- <div class="input-section">
704
- <div class="input-wrapper">
705
- <select class="agent-selector" data-agent-selector title="Select agent"></select>
706
- <select class="model-selector" data-model-selector title="Select model" data-empty="true"></select>
707
- <textarea
708
- class="message-textarea"
709
- data-message-input
710
- placeholder="Message AgentGUI... (Ctrl+Enter to send)"
711
- aria-label="Message input"
712
- rows="1"
713
- ></textarea>
714
- <button class="inject-btn" id="injectBtn" title="Inject instructions into running agent" aria-label="Inject instructions">
715
- <svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
716
- <path d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"/>
717
- </svg>
718
- </button>
719
- <button class="stop-btn" id="stopBtn" title="Stop running agent (emergency)" aria-label="Stop agent">
720
- <svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
721
- <path d="M6 6h12v12H6z"/>
722
- </svg>
723
- </button>
724
- <button class="send-btn" data-send-button title="Send message (Ctrl+Enter)" aria-label="Send message">
725
- <svg viewBox="0 0 24 24" fill="currentColor">
726
- <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
727
- </svg>
728
- </button>
729
- </div>
730
- </div>
731
- </main>
732
- </div>
733
-
734
- <!-- Folder Browser Modal -->
735
- <div id="folderBrowserModal" class="folder-modal-overlay">
736
- <div class="folder-modal">
737
- <div class="folder-modal-header">
738
- <h3>Select Working Directory</h3>
739
- <button class="folder-modal-close" data-folder-close>&times;</button>
740
- </div>
741
- <div id="folderBreadcrumb" class="folder-breadcrumb"></div>
742
- <ul id="folderList" class="folder-list">
743
- <li class="folder-list-loading">Loading...</li>
744
- </ul>
745
- <div class="folder-modal-footer">
746
- <button class="btn btn-secondary" data-folder-cancel>Cancel</button>
747
- <button class="btn btn-primary" data-folder-select>Select This Folder</button>
748
- </div>
749
- </div>
750
- </div>
751
-
752
- <script>
753
- var _escHtmlMap = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };
754
- var _escHtmlRe = /[&<>"']/g;
755
- window._escHtml = function(t) { return t.replace(_escHtmlRe, function(c) { return _escHtmlMap[c]; }); };
756
- </script>
757
- <script defer src="/gm/js/event-processor.js"></script>
758
- <script defer src="/gm/js/streaming-renderer.js"></script>
759
- <script defer src="/gm/js/kalman-filter.js"></script>
760
- <script defer src="/gm/js/event-consolidator.js"></script>
761
- <script defer src="/gm/js/websocket-manager.js"></script>
762
- <script defer src="/gm/js/event-filter.js"></script>
763
- <script defer src="/gm/js/syntax-highlighter.js"></script>
764
- <script defer src="/gm/js/dialogs.js"></script>
765
- <script defer src="/gm/js/ui-components.js"></script>
766
- <script defer src="/gm/js/progress-dialog.js"></script>
767
- <script defer src="/gm/js/conversations.js"></script>
768
- <script defer src="/gm/js/client.js"></script>
769
- <script type="module" src="/gm/js/voice.js"></script>
770
- <script defer src="/gm/js/features.js"></script>
771
- <script defer src="/gm/js/script-runner.js"></script>
772
- <script defer src="/gm/js/agent-auth.js"></script>
773
-
774
- <script>
775
- const savedTheme = localStorage.getItem('theme') || 'light';
776
- if (savedTheme === 'dark') document.documentElement.classList.add('dark');
777
-
778
- window.addEventListener('error', (event) => console.error('Uncaught error:', event.error));
779
- window.addEventListener('unhandledrejection', (event) => console.error('Unhandled rejection:', event.reason));
780
- </script>
781
- </body>
782
- </html>
721
+
722
+ pre code { background-color: transparent; color: inherit; padding: 0; }
723
+
724
+ /* SCROLLBARS */
725
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
726
+ ::-webkit-scrollbar-track { background-color: transparent; }
727
+ ::-webkit-scrollbar-thumb { background-color: var(--color-border); border-radius: 3px; }
728
+ ::-webkit-scrollbar-thumb:hover { background-color: var(--color-text-tertiary); }
729
+
730
+ /* RESPONSIVE */
731
+ @media (max-width: 768px) {
732
+ .sidebar {
733
+ position: absolute; left: 0; top: 0; bottom: 0; z-index: 100;
734
+ box-shadow: 2px 0 16px rgba(0,0,0,0.1);
735
+ }
736
+
737
+ .sidebar.collapsed { display: none; }
738
+
739
+ .messages-wrapper, .input-wrapper { padding-left: 1rem; padding-right: 1rem; }
740
+ }
741
+ </style>
742
+ </head>
743
+ <body>
744
+ <!-- Sidebar overlay (mobile) -->
745
+ <div class="sidebar-overlay" data-sidebar-overlay></div>
746
+
747
+ <div class="app-shell">
748
+ <!-- ===== SIDEBAR ===== -->
749
+ <aside class="sidebar" data-sidebar>
750
+ <div class="sidebar-header">
751
+ <h2>History</h2>
752
+ <div class="sidebar-header-actions">
753
+ <button id="cloneRepoBtn" class="sidebar-clone-btn" data-clone-repo title="Clone a GitHub repo">Clone</button>
754
+ <button id="newConversationBtn" class="sidebar-new-btn" data-new-conversation title="Start new conversation">+ New</button>
755
+ </div>
756
+ </div>
757
+ <div class="clone-input-bar" id="cloneInputBar" style="display:none;">
758
+ <input type="text" class="clone-input" id="cloneRepoInput" placeholder="org/repo" autocomplete="off" spellcheck="false">
759
+ <button class="clone-go-btn" id="cloneGoBtn" title="Clone">Go</button>
760
+ <button class="clone-cancel-btn" id="cloneCancelBtn" title="Cancel">&times;</button>
761
+ </div>
762
+ <ul class="sidebar-list" data-conversation-list>
763
+ <li class="sidebar-empty" data-conversation-empty>No conversations yet</li>
764
+ </ul>
765
+ </aside>
766
+
767
+ <!-- ===== MAIN PANEL ===== -->
768
+ <main id="app" class="main-panel">
769
+ <!-- Header bar -->
770
+ <div class="main-header">
771
+ <button class="sidebar-toggle-btn" data-sidebar-toggle title="Toggle sidebar (Ctrl+B)" aria-label="Toggle sidebar">
772
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
773
+ <line x1="3" y1="6" x2="21" y2="6"></line>
774
+ <line x1="3" y1="12" x2="21" y2="12"></line>
775
+ <line x1="3" y1="18" x2="21" y2="18"></line>
776
+ </svg>
777
+ </button>
778
+
779
+ <h1 class="header-title">AgentGUI</h1>
780
+
781
+ <div class="header-controls">
782
+ <div class="script-buttons" id="scriptButtons" style="display:none;">
783
+ <button class="header-icon-btn" id="scriptStartBtn" title="Run start script" aria-label="Run start script" style="display:none;">
784
+ <svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><polygon points="6,3 20,12 6,21"></polygon></svg>
785
+ </button>
786
+ <button class="header-icon-btn script-dev-btn" id="scriptDevBtn" title="Run dev script" aria-label="Run dev script" style="display:none;">
787
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>
788
+ </button>
789
+ <button class="header-icon-btn script-stop-btn" id="scriptStopBtn" title="Stop running script" aria-label="Stop running script" style="display:none;">
790
+ <svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><rect x="5" y="5" width="14" height="14" rx="1"></rect></svg>
791
+ </button>
792
+ </div>
793
+ <button class="header-icon-btn agent-auth-btn" id="agentAuthBtn" title="Agent authentication" aria-label="Agent authentication" style="display:none;">
794
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg>
795
+ <div class="agent-auth-dropdown" id="agentAuthDropdown"></div>
796
+ </button>
797
+ <div class="status-badge">
798
+ <div class="status-indicator" data-status="disconnected"></div>
799
+ <span id="connectionStatus" data-status-indicator>Disconnected</span>
800
+ </div>
801
+ <button class="theme-toggle-btn" data-theme-toggle title="Toggle dark mode" aria-label="Toggle dark mode">
802
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
803
+ <circle cx="12" cy="12" r="5"></circle>
804
+ <line x1="12" y1="1" x2="12" y2="3"></line>
805
+ <line x1="12" y1="21" x2="12" y2="23"></line>
806
+ <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
807
+ <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
808
+ <line x1="1" y1="12" x2="3" y2="12"></line>
809
+ <line x1="21" y1="12" x2="23" y2="12"></line>
810
+ <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
811
+ <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
812
+ </svg>
813
+ </button>
814
+ </div>
815
+ </div>
816
+
817
+ <!-- View toggle bar (hidden by default) -->
818
+ <div class="view-toggle-bar" id="viewToggleBar" style="display:none;">
819
+ <button class="view-toggle-btn active" data-view="chat">Chat</button>
820
+ <button class="view-toggle-btn" data-view="files">Files</button>
821
+ <button class="view-toggle-btn" data-view="voice" style="display:none;">Voice</button>
822
+ <button class="view-toggle-btn" data-view="terminal" id="terminalTabBtn" style="display:none;">Terminal</button>
823
+ </div>
824
+
825
+ <!-- Messages scroll area -->
826
+ <div id="output-scroll" role="region" aria-label="Chat messages" aria-live="polite" data-drop-zone>
827
+ <div class="messages-wrapper">
828
+ <div id="output"></div>
829
+ </div>
830
+ <div class="drop-zone-overlay" id="dropZoneOverlay">
831
+ <div class="drop-zone-content">
832
+ <div class="drop-zone-icon">+</div>
833
+ <div class="drop-zone-text">Drop files here to copy to working directory</div>
834
+ </div>
835
+ </div>
836
+ </div>
837
+
838
+ <!-- File browser (hidden by default) -->
839
+ <div id="fileBrowserContainer" class="file-browser-container" style="display:none;">
840
+ <iframe id="fileBrowserIframe" class="file-browser-iframe"></iframe>
841
+ </div>
842
+
843
+ <!-- Terminal output view -->
844
+ <div id="terminalContainer" class="terminal-container" style="display:none;">
845
+ <div id="terminalOutput" class="terminal-output"></div>
846
+ </div>
847
+
848
+ <!-- Voice STT/TTS view -->
849
+ <div id="voiceContainer" class="voice-container" style="display:none;">
850
+ <div id="voiceScroll" class="voice-scroll">
851
+ <div class="voice-messages" id="voiceMessages"></div>
852
+ </div>
853
+ <div class="voice-input-section">
854
+ <div class="voice-input-wrapper">
855
+ <select class="agent-selector voice-agent-selector" data-voice-agent-selector title="Select agent"></select>
856
+ <div class="voice-transcript" id="voiceTranscript" data-placeholder="Tap mic and speak..."></div>
857
+ <button class="voice-mic-btn" id="voiceMicBtn" title="Toggle recording" aria-label="Voice input">
858
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
859
+ <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
860
+ <path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
861
+ <line x1="12" y1="19" x2="12" y2="23"/>
862
+ <line x1="8" y1="23" x2="16" y2="23"/>
863
+ </svg>
864
+ </button>
865
+ <button class="send-btn voice-send-btn" id="voiceSendBtn" title="Send message" aria-label="Send message">
866
+ <svg viewBox="0 0 24 24" fill="currentColor">
867
+ <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
868
+ </svg>
869
+ </button>
870
+ </div>
871
+ <div class="voice-tts-controls">
872
+ <label class="voice-toggle-label">
873
+ <input type="checkbox" id="voiceTTSToggle" checked>
874
+ <span>Auto-speak responses</span>
875
+ </label>
876
+ <div class="voice-selector-wrapper">
877
+ <select class="voice-selector" id="voiceSelector" title="Select voice">
878
+ <option value="default">Default</option>
879
+ </select>
880
+ </div>
881
+ <button class="voice-stop-btn" id="voiceStopSpeaking" title="Stop speaking">Stop</button>
882
+ </div>
883
+ </div>
884
+ </div>
885
+
886
+ <!-- Input area: fixed at bottom -->
887
+ <div class="input-section">
888
+ <div class="input-wrapper">
889
+ <select class="agent-selector" data-agent-selector title="Select agent"></select>
890
+ <select class="model-selector" data-model-selector title="Select model" data-empty="true"></select>
891
+ <textarea
892
+ class="message-textarea"
893
+ data-message-input
894
+ placeholder="Message AgentGUI... (Ctrl+Enter to send)"
895
+ aria-label="Message input"
896
+ rows="1"
897
+ ></textarea>
898
+ <button class="inject-btn" id="injectBtn" title="Inject instructions into running agent" aria-label="Inject instructions">
899
+ <svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
900
+ <path d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"/>
901
+ </svg>
902
+ </button>
903
+ <button class="stop-btn" id="stopBtn" title="Stop running agent (emergency)" aria-label="Stop agent">
904
+ <svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
905
+ <path d="M6 6h12v12H6z"/>
906
+ </svg>
907
+ </button>
908
+ <button class="send-btn" data-send-button title="Send message (Ctrl+Enter)" aria-label="Send message">
909
+ <svg viewBox="0 0 24 24" fill="currentColor">
910
+ <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
911
+ </svg>
912
+ </button>
913
+ </div>
914
+ </div>
915
+ </main>
916
+ </div>
917
+
918
+ <!-- Folder Browser Modal -->
919
+ <div id="folderBrowserModal" class="folder-modal-overlay">
920
+ <div class="folder-modal">
921
+ <div class="folder-modal-header">
922
+ <h3>Select Working Directory</h3>
923
+ <button class="folder-modal-close" data-folder-close>&times;</button>
924
+ </div>
925
+ <div id="folderBreadcrumb" class="folder-breadcrumb"></div>
926
+ <ul id="folderList" class="folder-list">
927
+ <li class="folder-list-loading">Loading...</li>
928
+ </ul>
929
+ <div class="folder-modal-footer">
930
+ <button class="btn btn-secondary" data-folder-cancel>Cancel</button>
931
+ <button class="btn btn-primary" data-folder-select>Select This Folder</button>
932
+ </div>
933
+ </div>
934
+ </div>
935
+
936
+ <script>
937
+ var _escHtmlMap = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };
938
+ var _escHtmlRe = /[&<>"']/g;
939
+ window._escHtml = function(t) { return t.replace(_escHtmlRe, function(c) { return _escHtmlMap[c]; }); };
940
+ </script>
941
+ <script defer src="/gm/js/event-processor.js"></script>
942
+ <script defer src="/gm/js/streaming-renderer.js"></script>
943
+ <script defer src="/gm/js/kalman-filter.js"></script>
944
+ <script defer src="/gm/js/event-consolidator.js"></script>
945
+ <script defer src="/gm/js/websocket-manager.js"></script>
946
+ <script defer src="/gm/js/event-filter.js"></script>
947
+ <script defer src="/gm/js/syntax-highlighter.js"></script>
948
+ <script defer src="/gm/js/dialogs.js"></script>
949
+ <script defer src="/gm/js/ui-components.js"></script>
950
+ <script defer src="/gm/js/progress-dialog.js"></script>
951
+ <script defer src="/gm/js/conversations.js"></script>
952
+ <script defer src="/gm/js/client.js"></script>
953
+ <script type="module" src="/gm/js/voice.js"></script>
954
+ <script defer src="/gm/js/features.js"></script>
955
+ <script defer src="/gm/js/script-runner.js"></script>
956
+ <script defer src="/gm/js/agent-auth.js"></script>
957
+
958
+ <script>
959
+ const savedTheme = localStorage.getItem('theme') || 'light';
960
+ if (savedTheme === 'dark') document.documentElement.classList.add('dark');
961
+
962
+ window.addEventListener('error', (event) => console.error('Uncaught error:', event.error));
963
+ window.addEventListener('unhandledrejection', (event) => console.error('Unhandled rejection:', event.reason));
964
+ </script>
965
+ </body>
966
+ </html>