agent-relay 1.0.9 → 1.0.12

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 (94) hide show
  1. package/README.md +27 -56
  2. package/bin/.gitkeep +0 -0
  3. package/bin/tmux +0 -0
  4. package/dist/bridge/config.d.ts.map +1 -1
  5. package/dist/bridge/multi-project-client.d.ts.map +1 -1
  6. package/dist/bridge/multi-project-client.js +1 -1
  7. package/dist/bridge/multi-project-client.js.map +1 -1
  8. package/dist/bridge/spawner.d.ts +47 -9
  9. package/dist/bridge/spawner.d.ts.map +1 -1
  10. package/dist/bridge/spawner.js +177 -73
  11. package/dist/bridge/spawner.js.map +1 -1
  12. package/dist/bridge/types.d.ts +4 -2
  13. package/dist/bridge/types.d.ts.map +1 -1
  14. package/dist/cli/index.js +192 -295
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/daemon/router.d.ts.map +1 -1
  17. package/dist/daemon/router.js.map +1 -1
  18. package/dist/dashboard-server/metrics.d.ts.map +1 -0
  19. package/dist/dashboard-server/metrics.js.map +1 -0
  20. package/dist/dashboard-server/needs-attention.d.ts.map +1 -0
  21. package/dist/dashboard-server/needs-attention.js.map +1 -0
  22. package/dist/dashboard-server/server.d.ts.map +1 -0
  23. package/dist/{dashboard → dashboard-server}/server.js +20 -14
  24. package/dist/dashboard-server/server.js.map +1 -0
  25. package/dist/dashboard-server/start.d.ts.map +1 -0
  26. package/dist/dashboard-server/start.js.map +1 -0
  27. package/dist/utils/tmux-resolver.d.ts +55 -0
  28. package/dist/utils/tmux-resolver.d.ts.map +1 -0
  29. package/dist/utils/tmux-resolver.js +175 -0
  30. package/dist/utils/tmux-resolver.js.map +1 -0
  31. package/dist/utils/update-checker.d.ts +26 -0
  32. package/dist/utils/update-checker.d.ts.map +1 -0
  33. package/dist/utils/update-checker.js +174 -0
  34. package/dist/utils/update-checker.js.map +1 -0
  35. package/dist/wrapper/pty-wrapper.d.ts +129 -0
  36. package/dist/wrapper/pty-wrapper.d.ts.map +1 -0
  37. package/dist/wrapper/pty-wrapper.js +442 -0
  38. package/dist/wrapper/pty-wrapper.js.map +1 -0
  39. package/dist/wrapper/tmux-wrapper.d.ts +2 -1
  40. package/dist/wrapper/tmux-wrapper.d.ts.map +1 -1
  41. package/dist/wrapper/tmux-wrapper.js +23 -19
  42. package/dist/wrapper/tmux-wrapper.js.map +1 -1
  43. package/docs/AGENTS.md +43 -30
  44. package/docs/INTEGRATION-GUIDE.md +1 -1
  45. package/docs/PROTOCOL.md +16 -10
  46. package/docs/agent-relay-snippet.md +21 -17
  47. package/package.json +10 -6
  48. package/scripts/dev/PUBLIC_RELEASE_PLAN.md +88 -0
  49. package/scripts/dev/dev-team-setup.sh +431 -0
  50. package/scripts/e2e-test.sh +119 -0
  51. package/scripts/games/game-protocol.md +79 -0
  52. package/scripts/games/hearts-setup.sh +264 -0
  53. package/scripts/postinstall.js +254 -0
  54. package/scripts/tictactoe-setup.sh +181 -0
  55. package/dist/dashboard/metrics.d.ts.map +0 -1
  56. package/dist/dashboard/metrics.js.map +0 -1
  57. package/dist/dashboard/needs-attention.d.ts.map +0 -1
  58. package/dist/dashboard/needs-attention.js.map +0 -1
  59. package/dist/dashboard/public/bridge.html +0 -1272
  60. package/dist/dashboard/public/index.html +0 -2262
  61. package/dist/dashboard/public/js/app.js +0 -184
  62. package/dist/dashboard/public/js/app.js.map +0 -7
  63. package/dist/dashboard/public/metrics.html +0 -999
  64. package/dist/dashboard/server.d.ts.map +0 -1
  65. package/dist/dashboard/server.js.map +0 -1
  66. package/dist/dashboard/start.d.ts.map +0 -1
  67. package/dist/dashboard/start.js.map +0 -1
  68. package/dist/dashboard-v2/index.d.ts +0 -10
  69. package/dist/dashboard-v2/index.d.ts.map +0 -1
  70. package/dist/dashboard-v2/index.js +0 -54
  71. package/dist/dashboard-v2/index.js.map +0 -1
  72. package/dist/dashboard-v2/lib/api.d.ts +0 -95
  73. package/dist/dashboard-v2/lib/api.d.ts.map +0 -1
  74. package/dist/dashboard-v2/lib/api.js +0 -270
  75. package/dist/dashboard-v2/lib/api.js.map +0 -1
  76. package/dist/dashboard-v2/lib/colors.d.ts +0 -61
  77. package/dist/dashboard-v2/lib/colors.d.ts.map +0 -1
  78. package/dist/dashboard-v2/lib/colors.js +0 -198
  79. package/dist/dashboard-v2/lib/colors.js.map +0 -1
  80. package/dist/dashboard-v2/lib/hierarchy.d.ts +0 -74
  81. package/dist/dashboard-v2/lib/hierarchy.d.ts.map +0 -1
  82. package/dist/dashboard-v2/lib/hierarchy.js +0 -196
  83. package/dist/dashboard-v2/lib/hierarchy.js.map +0 -1
  84. package/dist/dashboard-v2/types/index.d.ts +0 -154
  85. package/dist/dashboard-v2/types/index.d.ts.map +0 -1
  86. package/dist/dashboard-v2/types/index.js +0 -6
  87. package/dist/dashboard-v2/types/index.js.map +0 -1
  88. /package/dist/{dashboard → dashboard-server}/metrics.d.ts +0 -0
  89. /package/dist/{dashboard → dashboard-server}/metrics.js +0 -0
  90. /package/dist/{dashboard → dashboard-server}/needs-attention.d.ts +0 -0
  91. /package/dist/{dashboard → dashboard-server}/needs-attention.js +0 -0
  92. /package/dist/{dashboard → dashboard-server}/server.d.ts +0 -0
  93. /package/dist/{dashboard → dashboard-server}/start.d.ts +0 -0
  94. /package/dist/{dashboard → dashboard-server}/start.js +0 -0
@@ -1,2262 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Agent Relay</title>
7
- <link rel="preconnect" href="https://fonts.googleapis.com">
8
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
10
- <style>
11
- /* ========================================
12
- Design Tokens
13
- ======================================== */
14
- :root {
15
- /* Background colors */
16
- --bg-workspace: #1a1d21;
17
- --bg-sidebar: #19171d;
18
- --bg-channel-active: #1164a3;
19
- --bg-channel-hover: rgba(255, 255, 255, 0.04);
20
- --bg-main: #222529;
21
- --bg-message-hover: rgba(255, 255, 255, 0.03);
22
- --bg-composer: #222529;
23
- --bg-input: #222529;
24
- --bg-modal: #1a1d21;
25
- --bg-tooltip: #1d1c21;
26
-
27
- /* Text colors */
28
- --text-primary: #d1d2d3;
29
- --text-secondary: #ababad;
30
- --text-muted: #8d8d8e;
31
- --text-channel: #bcabbc;
32
- --text-channel-active: #ffffff;
33
- --text-link: #1d9bd1;
34
-
35
- /* Accent colors */
36
- --accent-primary: #1264a3;
37
- --accent-green: #2bac76;
38
- --accent-yellow: #e8a427;
39
- --accent-red: #e01e5a;
40
- --accent-purple: #7c3aed;
41
-
42
- /* Status colors */
43
- --status-online: #2bac76;
44
- --status-away: #e8a427;
45
- --status-offline: #616061;
46
- --status-busy: #e01e5a;
47
-
48
- /* Border colors */
49
- --border-subtle: rgba(255, 255, 255, 0.1);
50
- --border-divider: rgba(255, 255, 255, 0.06);
51
-
52
- /* Badge colors */
53
- --badge-bg: #e01e5a;
54
- --badge-text: #ffffff;
55
-
56
- /* Shadows */
57
- --shadow-modal: 0 18px 50px rgba(0, 0, 0, 0.6);
58
- --shadow-message: 0 1px 2px rgba(0, 0, 0, 0.1);
59
-
60
- /* Dimensions */
61
- --sidebar-width: 260px;
62
- --header-height: 49px;
63
- --composer-min-height: 44px;
64
-
65
- /* Typography */
66
- --font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
67
- --font-mono: 'JetBrains Mono', ui-monospace, monospace;
68
-
69
- /* Transitions */
70
- --transition-fast: 0.1s ease;
71
- --transition-normal: 0.2s ease;
72
- }
73
-
74
- /* ========================================
75
- Reset & Base
76
- ======================================== */
77
- *, *::before, *::after {
78
- box-sizing: border-box;
79
- margin: 0;
80
- padding: 0;
81
- }
82
-
83
- html, body {
84
- height: 100%;
85
- overflow: hidden;
86
- }
87
-
88
- body {
89
- font-family: var(--font-family);
90
- font-size: 15px;
91
- line-height: 1.46668;
92
- color: var(--text-primary);
93
- background: var(--bg-workspace);
94
- -webkit-font-smoothing: antialiased;
95
- -moz-osx-font-smoothing: grayscale;
96
- }
97
-
98
- /* ========================================
99
- Layout Structure
100
- ======================================== */
101
- .app-container {
102
- display: flex;
103
- height: 100vh;
104
- width: 100vw;
105
- }
106
-
107
- /* Sidebar */
108
- .sidebar {
109
- width: var(--sidebar-width);
110
- background: var(--bg-sidebar);
111
- display: flex;
112
- flex-direction: column;
113
- flex-shrink: 0;
114
- border-right: 1px solid var(--border-divider);
115
- }
116
-
117
- /* Main Content */
118
- .main-panel {
119
- flex: 1;
120
- display: flex;
121
- flex-direction: column;
122
- min-width: 0;
123
- background: var(--bg-main);
124
- }
125
-
126
- /* ========================================
127
- Sidebar Components
128
- ======================================== */
129
-
130
- /* Workspace Header */
131
- .workspace-header {
132
- height: var(--header-height);
133
- padding: 0 16px;
134
- display: flex;
135
- align-items: center;
136
- justify-content: space-between;
137
- border-bottom: 1px solid var(--border-divider);
138
- flex-shrink: 0;
139
- }
140
-
141
- .workspace-name {
142
- font-size: 18px;
143
- font-weight: 700;
144
- color: var(--text-primary);
145
- display: flex;
146
- align-items: center;
147
- gap: 6px;
148
- }
149
-
150
- .workspace-name .status-dot {
151
- width: 10px;
152
- height: 10px;
153
- border-radius: 50%;
154
- background: var(--status-online);
155
- flex-shrink: 0;
156
- }
157
-
158
- .workspace-name .status-dot.offline {
159
- background: var(--status-offline);
160
- }
161
-
162
- .compose-new-btn {
163
- width: 36px;
164
- height: 36px;
165
- border-radius: 50%;
166
- background: rgba(255, 255, 255, 0.1);
167
- border: none;
168
- color: var(--text-primary);
169
- cursor: pointer;
170
- display: flex;
171
- align-items: center;
172
- justify-content: center;
173
- transition: background var(--transition-fast);
174
- }
175
-
176
- .compose-new-btn:hover {
177
- background: rgba(255, 255, 255, 0.2);
178
- }
179
-
180
- /* Command Palette Trigger */
181
- .search-bar {
182
- margin: 12px 12px 8px;
183
- padding: 6px 12px;
184
- background: rgba(255, 255, 255, 0.06);
185
- border: 1px solid transparent;
186
- border-radius: 6px;
187
- display: flex;
188
- align-items: center;
189
- gap: 8px;
190
- cursor: pointer;
191
- transition: all var(--transition-fast);
192
- }
193
-
194
- .search-bar:hover {
195
- background: rgba(255, 255, 255, 0.1);
196
- }
197
-
198
- .search-bar svg {
199
- width: 16px;
200
- height: 16px;
201
- color: var(--text-muted);
202
- }
203
-
204
- .search-bar span {
205
- font-size: 13px;
206
- color: var(--text-muted);
207
- flex: 1;
208
- }
209
-
210
- .search-bar kbd {
211
- font-family: var(--font-family);
212
- font-size: 11px;
213
- color: var(--text-muted);
214
- background: rgba(255, 255, 255, 0.1);
215
- padding: 2px 6px;
216
- border-radius: 4px;
217
- }
218
-
219
- /* Sidebar Sections */
220
- .sidebar-content {
221
- flex: 1;
222
- overflow-y: auto;
223
- padding: 8px 0;
224
- }
225
-
226
- .section-header {
227
- padding: 8px 16px 4px;
228
- display: flex;
229
- align-items: center;
230
- justify-content: space-between;
231
- cursor: pointer;
232
- }
233
-
234
- .section-title {
235
- font-size: 15px;
236
- font-weight: 600;
237
- color: var(--text-channel);
238
- display: flex;
239
- align-items: center;
240
- gap: 4px;
241
- }
242
-
243
- .section-title svg {
244
- width: 12px;
245
- height: 12px;
246
- transition: transform var(--transition-fast);
247
- }
248
-
249
- .section-header.collapsed .section-title svg {
250
- transform: rotate(-90deg);
251
- }
252
-
253
- .section-add-btn {
254
- width: 24px;
255
- height: 24px;
256
- border: none;
257
- background: transparent;
258
- color: var(--text-muted);
259
- cursor: pointer;
260
- border-radius: 4px;
261
- display: flex;
262
- align-items: center;
263
- justify-content: center;
264
- opacity: 0;
265
- transition: all var(--transition-fast);
266
- }
267
-
268
- .section-header:hover .section-add-btn {
269
- opacity: 1;
270
- }
271
-
272
- .section-add-btn:hover {
273
- background: rgba(255, 255, 255, 0.1);
274
- color: var(--text-primary);
275
- }
276
-
277
- /* Channel/Agent List */
278
- .channel-list {
279
- list-style: none;
280
- }
281
-
282
- /* Sidebar Footer */
283
- .sidebar-footer {
284
- padding: 12px 16px;
285
- border-top: 1px solid var(--border-divider);
286
- }
287
-
288
- .nav-link {
289
- display: flex;
290
- align-items: center;
291
- gap: 8px;
292
- padding: 8px 12px;
293
- color: var(--text-muted);
294
- text-decoration: none;
295
- font-size: 13px;
296
- border-radius: 6px;
297
- transition: all var(--transition-fast);
298
- }
299
-
300
- .nav-link:hover {
301
- background: var(--bg-channel-hover);
302
- color: var(--text-primary);
303
- }
304
-
305
- .nav-link svg {
306
- width: 16px;
307
- height: 16px;
308
- }
309
-
310
- .channel-item {
311
- display: flex;
312
- align-items: center;
313
- padding: 6px 20px 6px 16px;
314
- cursor: pointer;
315
- transition: background var(--transition-fast);
316
- gap: 8px;
317
- position: relative;
318
- }
319
-
320
- .channel-item:hover {
321
- background: var(--bg-channel-hover);
322
- }
323
-
324
- .channel-item.active {
325
- background: var(--bg-channel-active);
326
- }
327
-
328
- .channel-item.active .channel-name,
329
- .channel-item.active .channel-prefix {
330
- color: var(--text-channel-active);
331
- }
332
-
333
- .channel-prefix {
334
- font-size: 15px;
335
- color: var(--text-muted);
336
- width: 18px;
337
- text-align: center;
338
- flex-shrink: 0;
339
- }
340
-
341
- .channel-name {
342
- font-size: 15px;
343
- color: var(--text-channel);
344
- flex: 1;
345
- white-space: nowrap;
346
- overflow: hidden;
347
- text-overflow: ellipsis;
348
- }
349
-
350
- .channel-item.unread .channel-name {
351
- font-weight: 600;
352
- color: var(--text-primary);
353
- }
354
-
355
- .unread-badge {
356
- min-width: 18px;
357
- height: 18px;
358
- padding: 0 5px;
359
- background: var(--badge-bg);
360
- color: var(--badge-text);
361
- font-size: 12px;
362
- font-weight: 600;
363
- border-radius: 9px;
364
- display: flex;
365
- align-items: center;
366
- justify-content: center;
367
- }
368
-
369
- /* Agent item with presence */
370
- .agent-avatar {
371
- width: 20px;
372
- height: 20px;
373
- border-radius: 4px;
374
- background: var(--accent-purple);
375
- color: white;
376
- font-size: 10px;
377
- font-weight: 600;
378
- display: flex;
379
- align-items: center;
380
- justify-content: center;
381
- position: relative;
382
- flex-shrink: 0;
383
- }
384
-
385
- .presence-indicator {
386
- position: absolute;
387
- bottom: -2px;
388
- right: -2px;
389
- width: 10px;
390
- height: 10px;
391
- border-radius: 50%;
392
- border: 2px solid var(--bg-sidebar);
393
- background: var(--status-offline);
394
- }
395
-
396
- .presence-indicator.online {
397
- background: var(--status-online);
398
- }
399
-
400
- .presence-indicator.away {
401
- background: var(--status-away);
402
- }
403
-
404
- .presence-indicator.busy {
405
- background: var(--status-busy);
406
- }
407
-
408
- /* Needs Attention Indicator */
409
- .channel-item.needs-attention {
410
- background: rgba(232, 164, 39, 0.1);
411
- }
412
-
413
- .channel-item.needs-attention::after {
414
- content: '';
415
- position: absolute;
416
- top: 50%;
417
- right: 12px;
418
- transform: translateY(-50%);
419
- width: 8px;
420
- height: 8px;
421
- background: var(--accent-yellow);
422
- border-radius: 50%;
423
- animation: attentionPulse 1.5s ease-in-out infinite;
424
- }
425
-
426
- .attention-badge {
427
- display: inline-flex;
428
- align-items: center;
429
- gap: 4px;
430
- padding: 2px 6px;
431
- margin-left: 8px;
432
- background: var(--accent-yellow);
433
- color: #1a1d21;
434
- font-size: 10px;
435
- font-weight: 600;
436
- border-radius: 4px;
437
- text-transform: uppercase;
438
- letter-spacing: 0.02em;
439
- }
440
-
441
- @keyframes attentionPulse {
442
- 0%, 100% {
443
- opacity: 1;
444
- transform: translateY(-50%) scale(1);
445
- }
446
- 50% {
447
- opacity: 0.5;
448
- transform: translateY(-50%) scale(1.2);
449
- }
450
- }
451
-
452
- /* ========================================
453
- Main Panel Components
454
- ======================================== */
455
-
456
- /* Channel Header */
457
- .channel-header {
458
- height: var(--header-height);
459
- padding: 0 20px;
460
- display: flex;
461
- align-items: center;
462
- border-bottom: 1px solid var(--border-divider);
463
- flex-shrink: 0;
464
- gap: 8px;
465
- }
466
-
467
- .channel-header-name {
468
- font-size: 18px;
469
- font-weight: 700;
470
- color: var(--text-primary);
471
- display: flex;
472
- align-items: center;
473
- gap: 6px;
474
- }
475
-
476
- .channel-header-name .prefix {
477
- color: var(--text-muted);
478
- font-weight: 500;
479
- }
480
-
481
- .header-divider {
482
- width: 1px;
483
- height: 20px;
484
- background: var(--border-subtle);
485
- margin: 0 8px;
486
- }
487
-
488
- .channel-topic {
489
- font-size: 13px;
490
- color: var(--text-muted);
491
- flex: 1;
492
- white-space: nowrap;
493
- overflow: hidden;
494
- text-overflow: ellipsis;
495
- }
496
-
497
- .header-actions {
498
- display: flex;
499
- align-items: center;
500
- gap: 4px;
501
- }
502
-
503
- .header-action-btn {
504
- width: 28px;
505
- height: 28px;
506
- border: none;
507
- background: transparent;
508
- color: var(--text-muted);
509
- border-radius: 4px;
510
- cursor: pointer;
511
- display: flex;
512
- align-items: center;
513
- justify-content: center;
514
- transition: all var(--transition-fast);
515
- }
516
-
517
- .header-action-btn:hover {
518
- background: rgba(255, 255, 255, 0.1);
519
- color: var(--text-primary);
520
- }
521
-
522
- .online-count {
523
- font-size: 13px;
524
- color: var(--text-muted);
525
- display: flex;
526
- align-items: center;
527
- gap: 4px;
528
- }
529
-
530
- .online-count .dot {
531
- width: 8px;
532
- height: 8px;
533
- border-radius: 50%;
534
- background: var(--status-online);
535
- }
536
-
537
- /* Message List */
538
- .messages-container {
539
- flex: 1;
540
- overflow-y: auto;
541
- overflow-x: hidden;
542
- display: flex;
543
- flex-direction: column;
544
- }
545
-
546
- .messages-list {
547
- flex: 1;
548
- padding: 16px 0;
549
- }
550
-
551
- /* Date Divider */
552
- .date-divider {
553
- display: flex;
554
- align-items: center;
555
- margin: 16px 20px;
556
- }
557
-
558
- .date-divider::before,
559
- .date-divider::after {
560
- content: '';
561
- flex: 1;
562
- height: 1px;
563
- background: var(--border-divider);
564
- }
565
-
566
- .date-divider-text {
567
- padding: 4px 16px;
568
- font-size: 13px;
569
- font-weight: 600;
570
- color: var(--text-secondary);
571
- background: var(--bg-main);
572
- border: 1px solid var(--border-divider);
573
- border-radius: 24px;
574
- }
575
-
576
- /* Message */
577
- .message {
578
- padding: 8px 20px;
579
- display: flex;
580
- gap: 8px;
581
- transition: background var(--transition-fast);
582
- position: relative;
583
- }
584
-
585
- .message:hover {
586
- background: var(--bg-message-hover);
587
- }
588
-
589
- .message:hover .message-actions {
590
- opacity: 1;
591
- }
592
-
593
- .message-avatar {
594
- width: 36px;
595
- height: 36px;
596
- border-radius: 4px;
597
- flex-shrink: 0;
598
- display: flex;
599
- align-items: center;
600
- justify-content: center;
601
- font-weight: 600;
602
- font-size: 14px;
603
- color: white;
604
- }
605
-
606
- .message-content {
607
- flex: 1;
608
- min-width: 0;
609
- }
610
-
611
- .message-header {
612
- display: flex;
613
- align-items: baseline;
614
- gap: 8px;
615
- margin-bottom: 4px;
616
- }
617
-
618
- .message-sender {
619
- font-size: 15px;
620
- font-weight: 700;
621
- color: var(--text-primary);
622
- }
623
-
624
- .message-recipient {
625
- font-size: 13px;
626
- color: var(--text-muted);
627
- }
628
-
629
- .message-recipient .target {
630
- color: var(--text-link);
631
- }
632
-
633
- .project-badge {
634
- display: inline-block;
635
- background: var(--accent-primary);
636
- color: white;
637
- font-size: 10px;
638
- font-weight: 600;
639
- padding: 2px 6px;
640
- border-radius: 4px;
641
- margin-right: 4px;
642
- text-transform: uppercase;
643
- letter-spacing: 0.5px;
644
- }
645
-
646
- .message-timestamp {
647
- font-size: 12px;
648
- color: var(--text-muted);
649
- }
650
-
651
- .message-body {
652
- font-size: 15px;
653
- line-height: 1.46668;
654
- color: var(--text-primary);
655
- word-wrap: break-word;
656
- white-space: pre-wrap;
657
- }
658
-
659
- .message-body code {
660
- font-family: var(--font-mono);
661
- font-size: 13px;
662
- background: rgba(255, 255, 255, 0.06);
663
- padding: 2px 4px;
664
- border-radius: 3px;
665
- }
666
-
667
- .message-body pre {
668
- font-family: var(--font-mono);
669
- font-size: 13px;
670
- background: rgba(0, 0, 0, 0.3);
671
- padding: 12px;
672
- border-radius: 4px;
673
- margin: 8px 0;
674
- overflow-x: auto;
675
- white-space: pre-wrap;
676
- word-wrap: break-word;
677
- }
678
-
679
- .message-body pre code {
680
- background: transparent;
681
- padding: 0;
682
- border-radius: 0;
683
- }
684
-
685
- .message-body strong {
686
- font-weight: 700;
687
- color: var(--text-primary);
688
- }
689
-
690
- .message-body em {
691
- font-style: italic;
692
- }
693
-
694
- /* Broadcast message styling */
695
- .message.broadcast {
696
- border-left: 3px solid var(--accent-yellow);
697
- margin-left: 17px;
698
- padding-left: 17px;
699
- }
700
-
701
- .message.broadcast .message-recipient .target {
702
- color: var(--accent-yellow);
703
- }
704
-
705
- /* Message Actions (hover toolbar) */
706
- .message-actions {
707
- position: absolute;
708
- top: -16px;
709
- right: 20px;
710
- background: var(--bg-tooltip);
711
- border: 1px solid var(--border-subtle);
712
- border-radius: 6px;
713
- padding: 4px;
714
- display: flex;
715
- gap: 2px;
716
- opacity: 0;
717
- transition: opacity var(--transition-fast);
718
- box-shadow: var(--shadow-message);
719
- }
720
-
721
- .message-action-btn {
722
- width: 28px;
723
- height: 28px;
724
- border: none;
725
- background: transparent;
726
- color: var(--text-muted);
727
- border-radius: 4px;
728
- cursor: pointer;
729
- display: flex;
730
- align-items: center;
731
- justify-content: center;
732
- transition: all var(--transition-fast);
733
- }
734
-
735
- .message-action-btn:hover {
736
- background: rgba(255, 255, 255, 0.1);
737
- color: var(--text-primary);
738
- }
739
-
740
- /* Thread Indicator */
741
- .thread-indicator {
742
- display: inline-flex;
743
- align-items: center;
744
- gap: 4px;
745
- margin-top: 6px;
746
- padding: 4px 8px;
747
- background: rgba(255, 255, 255, 0.04);
748
- border-radius: 4px;
749
- font-size: 13px;
750
- color: var(--text-link);
751
- cursor: pointer;
752
- transition: background var(--transition-fast);
753
- }
754
-
755
- .thread-indicator:hover {
756
- background: rgba(255, 255, 255, 0.08);
757
- }
758
-
759
- .thread-indicator svg {
760
- width: 14px;
761
- height: 14px;
762
- }
763
-
764
- /* Typing Indicator */
765
- .typing-indicator {
766
- padding: 8px 20px;
767
- font-size: 13px;
768
- color: var(--text-muted);
769
- display: none;
770
- }
771
-
772
- .typing-indicator.visible {
773
- display: flex;
774
- align-items: center;
775
- gap: 8px;
776
- }
777
-
778
- .typing-dots {
779
- display: flex;
780
- gap: 3px;
781
- }
782
-
783
- .typing-dots span {
784
- width: 6px;
785
- height: 6px;
786
- background: var(--text-muted);
787
- border-radius: 50%;
788
- animation: typingBounce 1.4s infinite;
789
- }
790
-
791
- .typing-dots span:nth-child(2) { animation-delay: 0.2s; }
792
- .typing-dots span:nth-child(3) { animation-delay: 0.4s; }
793
-
794
- @keyframes typingBounce {
795
- 0%, 60%, 100% { transform: translateY(0); }
796
- 30% { transform: translateY(-4px); }
797
- }
798
-
799
- /* ========================================
800
- Composer
801
- ======================================== */
802
- .composer {
803
- padding: 0 20px 20px;
804
- flex-shrink: 0;
805
- position: relative;
806
- z-index: 10;
807
- }
808
-
809
- .composer-container {
810
- background: var(--bg-input);
811
- border: 1px solid var(--border-subtle);
812
- border-radius: 8px;
813
- overflow: visible;
814
- transition: border-color var(--transition-fast);
815
- position: relative;
816
- }
817
-
818
- .composer-container:focus-within {
819
- border-color: var(--accent-primary);
820
- }
821
-
822
- .composer-input-row {
823
- display: flex;
824
- align-items: flex-end;
825
- }
826
-
827
- .composer-toolbar {
828
- padding: 8px 12px;
829
- display: flex;
830
- align-items: center;
831
- gap: 4px;
832
- border-right: 1px solid var(--border-divider);
833
- }
834
-
835
- .toolbar-btn {
836
- width: 28px;
837
- height: 28px;
838
- border: none;
839
- background: transparent;
840
- color: var(--text-muted);
841
- border-radius: 4px;
842
- cursor: pointer;
843
- display: flex;
844
- align-items: center;
845
- justify-content: center;
846
- transition: all var(--transition-fast);
847
- }
848
-
849
- .toolbar-btn:hover {
850
- background: rgba(255, 255, 255, 0.1);
851
- color: var(--text-primary);
852
- }
853
-
854
- .composer-input {
855
- flex: 1;
856
- padding: 12px;
857
- background: transparent;
858
- border: none;
859
- color: var(--text-primary);
860
- font-family: var(--font-family);
861
- font-size: 15px;
862
- line-height: 1.46668;
863
- resize: none;
864
- outline: none;
865
- min-height: var(--composer-min-height);
866
- max-height: 200px;
867
- }
868
-
869
- .composer-input::placeholder {
870
- color: var(--text-muted);
871
- }
872
-
873
- .composer-send {
874
- padding: 8px 12px;
875
- display: flex;
876
- align-items: center;
877
- }
878
-
879
- .send-btn {
880
- width: 32px;
881
- height: 32px;
882
- border: none;
883
- background: var(--accent-primary);
884
- color: white;
885
- border-radius: 4px;
886
- cursor: pointer;
887
- display: flex;
888
- align-items: center;
889
- justify-content: center;
890
- transition: all var(--transition-fast);
891
- }
892
-
893
- .send-btn:hover {
894
- background: #0b5d99;
895
- }
896
-
897
- .send-btn:disabled {
898
- background: var(--border-subtle);
899
- cursor: not-allowed;
900
- }
901
-
902
- .composer-hint {
903
- padding: 8px 12px 0;
904
- font-size: 12px;
905
- color: var(--text-muted);
906
- text-align: right;
907
- }
908
-
909
- .composer-hint kbd {
910
- font-family: var(--font-family);
911
- background: rgba(255, 255, 255, 0.06);
912
- padding: 2px 5px;
913
- border-radius: 3px;
914
- font-size: 11px;
915
- }
916
-
917
- /* ========================================
918
- @-Mention Autocomplete
919
- ======================================== */
920
- .mention-autocomplete {
921
- position: absolute;
922
- bottom: 100%;
923
- left: 0;
924
- right: 0;
925
- margin-bottom: 8px;
926
- background: var(--bg-modal);
927
- border: 1px solid var(--border-subtle);
928
- border-radius: 8px;
929
- box-shadow: var(--shadow-modal);
930
- max-height: 240px;
931
- overflow-y: auto;
932
- display: none;
933
- z-index: 500;
934
- }
935
-
936
- .mention-autocomplete.visible {
937
- display: block;
938
- animation: autocompleteSlideIn 0.1s ease-out;
939
- }
940
-
941
- @keyframes autocompleteSlideIn {
942
- from {
943
- opacity: 0;
944
- transform: translateY(4px);
945
- }
946
- to {
947
- opacity: 1;
948
- transform: translateY(0);
949
- }
950
- }
951
-
952
- .mention-autocomplete-header {
953
- padding: 8px 12px 4px;
954
- font-size: 11px;
955
- font-weight: 600;
956
- color: var(--text-muted);
957
- text-transform: uppercase;
958
- letter-spacing: 0.05em;
959
- border-bottom: 1px solid var(--border-divider);
960
- }
961
-
962
- .mention-autocomplete-item {
963
- padding: 8px 12px;
964
- display: flex;
965
- align-items: center;
966
- gap: 10px;
967
- cursor: pointer;
968
- transition: background var(--transition-fast);
969
- }
970
-
971
- .mention-autocomplete-item:hover,
972
- .mention-autocomplete-item.selected {
973
- background: rgba(255, 255, 255, 0.08);
974
- }
975
-
976
- .mention-autocomplete-item .agent-avatar {
977
- width: 24px;
978
- height: 24px;
979
- font-size: 10px;
980
- }
981
-
982
- .mention-autocomplete-name {
983
- font-size: 14px;
984
- font-weight: 500;
985
- color: var(--text-primary);
986
- }
987
-
988
- .mention-autocomplete-role {
989
- font-size: 12px;
990
- color: var(--text-muted);
991
- margin-left: auto;
992
- }
993
-
994
- .mention-autocomplete-hint {
995
- padding: 6px 12px;
996
- font-size: 11px;
997
- color: var(--text-muted);
998
- border-top: 1px solid var(--border-divider);
999
- display: flex;
1000
- gap: 12px;
1001
- }
1002
-
1003
- .mention-autocomplete-hint kbd {
1004
- font-family: var(--font-family);
1005
- background: rgba(255, 255, 255, 0.1);
1006
- padding: 1px 5px;
1007
- border-radius: 3px;
1008
- font-size: 10px;
1009
- }
1010
-
1011
- /* ========================================
1012
- Command Palette
1013
- ======================================== */
1014
- .command-palette-overlay {
1015
- position: fixed;
1016
- inset: 0;
1017
- background: rgba(0, 0, 0, 0.6);
1018
- display: none;
1019
- align-items: flex-start;
1020
- justify-content: center;
1021
- padding-top: 15vh;
1022
- z-index: 1000;
1023
- }
1024
-
1025
- .command-palette-overlay.visible {
1026
- display: flex;
1027
- }
1028
-
1029
- .command-palette {
1030
- width: 600px;
1031
- max-width: 90vw;
1032
- background: var(--bg-modal);
1033
- border-radius: 8px;
1034
- box-shadow: var(--shadow-modal);
1035
- overflow: hidden;
1036
- animation: paletteSlideIn 0.15s ease-out;
1037
- }
1038
-
1039
- @keyframes paletteSlideIn {
1040
- from {
1041
- opacity: 0;
1042
- transform: translateY(-10px) scale(0.98);
1043
- }
1044
- to {
1045
- opacity: 1;
1046
- transform: translateY(0) scale(1);
1047
- }
1048
- }
1049
-
1050
- .palette-search {
1051
- padding: 16px;
1052
- border-bottom: 1px solid var(--border-divider);
1053
- }
1054
-
1055
- .palette-search-input {
1056
- width: 100%;
1057
- background: transparent;
1058
- border: none;
1059
- color: var(--text-primary);
1060
- font-family: var(--font-family);
1061
- font-size: 18px;
1062
- outline: none;
1063
- }
1064
-
1065
- .palette-search-input::placeholder {
1066
- color: var(--text-muted);
1067
- }
1068
-
1069
- .palette-results {
1070
- max-height: 400px;
1071
- overflow-y: auto;
1072
- }
1073
-
1074
- .palette-section {
1075
- padding: 8px 0;
1076
- }
1077
-
1078
- .palette-section-title {
1079
- padding: 8px 16px 4px;
1080
- font-size: 12px;
1081
- font-weight: 600;
1082
- color: var(--text-muted);
1083
- text-transform: uppercase;
1084
- letter-spacing: 0.05em;
1085
- }
1086
-
1087
- .palette-item {
1088
- padding: 10px 16px;
1089
- display: flex;
1090
- align-items: center;
1091
- gap: 12px;
1092
- cursor: pointer;
1093
- transition: background var(--transition-fast);
1094
- }
1095
-
1096
- .palette-item:hover,
1097
- .palette-item.selected {
1098
- background: rgba(255, 255, 255, 0.06);
1099
- }
1100
-
1101
- .palette-item-icon {
1102
- width: 20px;
1103
- height: 20px;
1104
- color: var(--text-muted);
1105
- display: flex;
1106
- align-items: center;
1107
- justify-content: center;
1108
- }
1109
-
1110
- .palette-item-content {
1111
- flex: 1;
1112
- }
1113
-
1114
- .palette-item-title {
1115
- font-size: 14px;
1116
- color: var(--text-primary);
1117
- }
1118
-
1119
- .palette-item-subtitle {
1120
- font-size: 12px;
1121
- color: var(--text-muted);
1122
- }
1123
-
1124
- .palette-item-shortcut {
1125
- font-size: 12px;
1126
- color: var(--text-muted);
1127
- }
1128
-
1129
- .palette-item-shortcut kbd {
1130
- font-family: var(--font-family);
1131
- background: rgba(255, 255, 255, 0.1);
1132
- padding: 2px 6px;
1133
- border-radius: 3px;
1134
- margin-left: 4px;
1135
- }
1136
-
1137
- /* ========================================
1138
- Thread Panel
1139
- ======================================== */
1140
- .thread-panel-overlay {
1141
- position: fixed;
1142
- top: 0;
1143
- right: 0;
1144
- bottom: 0;
1145
- width: 400px;
1146
- background: var(--bg-modal);
1147
- border-left: 1px solid var(--border-divider);
1148
- display: none;
1149
- flex-direction: column;
1150
- z-index: 100;
1151
- box-shadow: -4px 0 20px rgba(0, 0, 0, 0.3);
1152
- animation: threadSlideIn 0.2s ease-out;
1153
- }
1154
-
1155
- .thread-panel-overlay.visible {
1156
- display: flex;
1157
- }
1158
-
1159
- @keyframes threadSlideIn {
1160
- from {
1161
- transform: translateX(100%);
1162
- opacity: 0;
1163
- }
1164
- to {
1165
- transform: translateX(0);
1166
- opacity: 1;
1167
- }
1168
- }
1169
-
1170
- .thread-panel {
1171
- display: flex;
1172
- flex-direction: column;
1173
- height: 100%;
1174
- }
1175
-
1176
- .thread-panel-header {
1177
- padding: 16px;
1178
- border-bottom: 1px solid var(--border-divider);
1179
- display: flex;
1180
- align-items: center;
1181
- justify-content: space-between;
1182
- flex-shrink: 0;
1183
- }
1184
-
1185
- .thread-panel-title {
1186
- display: flex;
1187
- align-items: center;
1188
- gap: 8px;
1189
- font-size: 16px;
1190
- font-weight: 600;
1191
- color: var(--text-primary);
1192
- }
1193
-
1194
- .thread-panel-title .thread-id {
1195
- font-size: 13px;
1196
- font-weight: 500;
1197
- color: var(--text-link);
1198
- background: rgba(29, 155, 209, 0.1);
1199
- padding: 2px 8px;
1200
- border-radius: 4px;
1201
- }
1202
-
1203
- .thread-panel-close {
1204
- width: 32px;
1205
- height: 32px;
1206
- border: none;
1207
- background: transparent;
1208
- color: var(--text-muted);
1209
- border-radius: 4px;
1210
- cursor: pointer;
1211
- display: flex;
1212
- align-items: center;
1213
- justify-content: center;
1214
- transition: all var(--transition-fast);
1215
- }
1216
-
1217
- .thread-panel-close:hover {
1218
- background: rgba(255, 255, 255, 0.1);
1219
- color: var(--text-primary);
1220
- }
1221
-
1222
- .thread-messages {
1223
- flex: 1;
1224
- overflow-y: auto;
1225
- padding: 16px;
1226
- }
1227
-
1228
- .thread-message {
1229
- padding: 12px;
1230
- background: rgba(255, 255, 255, 0.02);
1231
- border-radius: 8px;
1232
- margin-bottom: 12px;
1233
- }
1234
-
1235
- .thread-message:last-child {
1236
- margin-bottom: 0;
1237
- }
1238
-
1239
- .thread-message-header {
1240
- display: flex;
1241
- align-items: center;
1242
- gap: 8px;
1243
- margin-bottom: 6px;
1244
- }
1245
-
1246
- .thread-message-avatar {
1247
- width: 28px;
1248
- height: 28px;
1249
- border-radius: 4px;
1250
- display: flex;
1251
- align-items: center;
1252
- justify-content: center;
1253
- font-weight: 600;
1254
- font-size: 11px;
1255
- color: white;
1256
- }
1257
-
1258
- .thread-message-sender {
1259
- font-weight: 600;
1260
- color: var(--text-primary);
1261
- font-size: 14px;
1262
- }
1263
-
1264
- .thread-message-time {
1265
- font-size: 12px;
1266
- color: var(--text-muted);
1267
- }
1268
-
1269
- .thread-message-body {
1270
- font-size: 14px;
1271
- color: var(--text-primary);
1272
- line-height: 1.4;
1273
- word-wrap: break-word;
1274
- white-space: pre-wrap;
1275
- }
1276
-
1277
- .thread-composer {
1278
- padding: 16px;
1279
- border-top: 1px solid var(--border-divider);
1280
- display: flex;
1281
- gap: 8px;
1282
- align-items: flex-end;
1283
- flex-shrink: 0;
1284
- }
1285
-
1286
- .thread-composer-input {
1287
- flex: 1;
1288
- padding: 10px 12px;
1289
- background: var(--bg-input);
1290
- border: 1px solid var(--border-subtle);
1291
- border-radius: 6px;
1292
- color: var(--text-primary);
1293
- font-family: var(--font-family);
1294
- font-size: 14px;
1295
- resize: none;
1296
- outline: none;
1297
- min-height: 40px;
1298
- max-height: 120px;
1299
- }
1300
-
1301
- .thread-composer-input:focus {
1302
- border-color: var(--accent-primary);
1303
- }
1304
-
1305
- .thread-composer-input::placeholder {
1306
- color: var(--text-muted);
1307
- }
1308
-
1309
- .thread-send-btn {
1310
- width: 36px;
1311
- height: 36px;
1312
- border: none;
1313
- background: var(--accent-primary);
1314
- color: white;
1315
- border-radius: 6px;
1316
- cursor: pointer;
1317
- display: flex;
1318
- align-items: center;
1319
- justify-content: center;
1320
- transition: all var(--transition-fast);
1321
- flex-shrink: 0;
1322
- }
1323
-
1324
- .thread-send-btn:hover {
1325
- background: #0b5d99;
1326
- }
1327
-
1328
- .thread-empty {
1329
- text-align: center;
1330
- padding: 32px;
1331
- color: var(--text-muted);
1332
- }
1333
-
1334
- /* Reply count badge on messages */
1335
- .reply-count-badge {
1336
- display: inline-flex;
1337
- align-items: center;
1338
- gap: 4px;
1339
- margin-top: 8px;
1340
- padding: 4px 8px;
1341
- background: rgba(29, 155, 209, 0.1);
1342
- border-radius: 4px;
1343
- font-size: 12px;
1344
- color: var(--text-link);
1345
- cursor: pointer;
1346
- transition: background var(--transition-fast);
1347
- }
1348
-
1349
- .reply-count-badge:hover {
1350
- background: rgba(29, 155, 209, 0.2);
1351
- }
1352
-
1353
- .reply-count-badge svg {
1354
- width: 14px;
1355
- height: 14px;
1356
- }
1357
-
1358
- /* ========================================
1359
- Empty States
1360
- ======================================== */
1361
- .empty-state {
1362
- flex: 1;
1363
- display: flex;
1364
- flex-direction: column;
1365
- align-items: center;
1366
- justify-content: center;
1367
- padding: 48px 24px;
1368
- text-align: center;
1369
- }
1370
-
1371
- .empty-state-icon {
1372
- width: 64px;
1373
- height: 64px;
1374
- margin-bottom: 16px;
1375
- color: var(--text-muted);
1376
- }
1377
-
1378
- .empty-state-title {
1379
- font-size: 18px;
1380
- font-weight: 600;
1381
- color: var(--text-primary);
1382
- margin-bottom: 8px;
1383
- }
1384
-
1385
- .empty-state-text {
1386
- font-size: 14px;
1387
- color: var(--text-muted);
1388
- max-width: 300px;
1389
- }
1390
-
1391
- /* ========================================
1392
- Scrollbars
1393
- ======================================== */
1394
- ::-webkit-scrollbar {
1395
- width: 8px;
1396
- height: 8px;
1397
- }
1398
-
1399
- ::-webkit-scrollbar-track {
1400
- background: transparent;
1401
- }
1402
-
1403
- ::-webkit-scrollbar-thumb {
1404
- background: rgba(255, 255, 255, 0.2);
1405
- border-radius: 4px;
1406
- }
1407
-
1408
- ::-webkit-scrollbar-thumb:hover {
1409
- background: rgba(255, 255, 255, 0.3);
1410
- }
1411
-
1412
- /* ========================================
1413
- Utilities
1414
- ======================================== */
1415
- .visually-hidden {
1416
- position: absolute;
1417
- width: 1px;
1418
- height: 1px;
1419
- padding: 0;
1420
- margin: -1px;
1421
- overflow: hidden;
1422
- clip: rect(0, 0, 0, 0);
1423
- border: 0;
1424
- }
1425
-
1426
- /* ========================================
1427
- Spawn Modal
1428
- ======================================== */
1429
- .spawn-modal-overlay {
1430
- position: fixed;
1431
- inset: 0;
1432
- background: rgba(0, 0, 0, 0.6);
1433
- display: none;
1434
- align-items: center;
1435
- justify-content: center;
1436
- z-index: 1000;
1437
- }
1438
-
1439
- .spawn-modal-overlay.visible {
1440
- display: flex;
1441
- }
1442
-
1443
- .spawn-modal {
1444
- width: 480px;
1445
- max-width: 90vw;
1446
- background: var(--bg-modal);
1447
- border-radius: 12px;
1448
- box-shadow: var(--shadow-modal);
1449
- overflow: hidden;
1450
- animation: modalSlideIn 0.2s ease-out;
1451
- }
1452
-
1453
- @keyframes modalSlideIn {
1454
- from {
1455
- opacity: 0;
1456
- transform: translateY(-20px) scale(0.95);
1457
- }
1458
- to {
1459
- opacity: 1;
1460
- transform: translateY(0) scale(1);
1461
- }
1462
- }
1463
-
1464
- .spawn-modal-header {
1465
- padding: 16px 20px;
1466
- border-bottom: 1px solid var(--border-divider);
1467
- display: flex;
1468
- align-items: center;
1469
- justify-content: space-between;
1470
- }
1471
-
1472
- .spawn-modal-title {
1473
- display: flex;
1474
- align-items: center;
1475
- gap: 10px;
1476
- font-size: 18px;
1477
- font-weight: 600;
1478
- color: var(--text-primary);
1479
- }
1480
-
1481
- .spawn-modal-title svg {
1482
- color: var(--accent-green);
1483
- }
1484
-
1485
- .spawn-modal-close {
1486
- width: 32px;
1487
- height: 32px;
1488
- border: none;
1489
- background: transparent;
1490
- color: var(--text-muted);
1491
- border-radius: 6px;
1492
- cursor: pointer;
1493
- display: flex;
1494
- align-items: center;
1495
- justify-content: center;
1496
- transition: all var(--transition-fast);
1497
- }
1498
-
1499
- .spawn-modal-close:hover {
1500
- background: rgba(255, 255, 255, 0.1);
1501
- color: var(--text-primary);
1502
- }
1503
-
1504
- .spawn-modal-body {
1505
- padding: 20px;
1506
- }
1507
-
1508
- .spawn-form-group {
1509
- margin-bottom: 16px;
1510
- }
1511
-
1512
- .spawn-form-group:last-child {
1513
- margin-bottom: 0;
1514
- }
1515
-
1516
- .spawn-form-group label {
1517
- display: block;
1518
- font-size: 13px;
1519
- font-weight: 600;
1520
- color: var(--text-secondary);
1521
- margin-bottom: 6px;
1522
- }
1523
-
1524
- .spawn-input,
1525
- .spawn-textarea {
1526
- width: 100%;
1527
- padding: 10px 12px;
1528
- background: var(--bg-input);
1529
- border: 1px solid var(--border-subtle);
1530
- border-radius: 6px;
1531
- color: var(--text-primary);
1532
- font-family: var(--font-family);
1533
- font-size: 14px;
1534
- transition: border-color var(--transition-fast);
1535
- }
1536
-
1537
- .spawn-input:focus,
1538
- .spawn-textarea:focus {
1539
- outline: none;
1540
- border-color: var(--accent-primary);
1541
- }
1542
-
1543
- .spawn-input::placeholder,
1544
- .spawn-textarea::placeholder {
1545
- color: var(--text-muted);
1546
- }
1547
-
1548
- .spawn-textarea {
1549
- resize: vertical;
1550
- min-height: 80px;
1551
- line-height: 1.4;
1552
- }
1553
-
1554
- .spawn-hint {
1555
- display: block;
1556
- font-size: 12px;
1557
- color: var(--text-muted);
1558
- margin-top: 4px;
1559
- }
1560
-
1561
- .spawn-status {
1562
- min-height: 20px;
1563
- font-size: 13px;
1564
- margin-top: 12px;
1565
- }
1566
-
1567
- .spawn-status.success {
1568
- color: var(--accent-green);
1569
- }
1570
-
1571
- .spawn-status.error {
1572
- color: var(--accent-red);
1573
- }
1574
-
1575
- .spawn-status.loading {
1576
- color: var(--text-muted);
1577
- }
1578
-
1579
- .spawn-modal-footer {
1580
- padding: 16px 20px;
1581
- border-top: 1px solid var(--border-divider);
1582
- display: flex;
1583
- justify-content: flex-end;
1584
- gap: 10px;
1585
- }
1586
-
1587
- .spawn-cancel-btn {
1588
- padding: 8px 16px;
1589
- background: transparent;
1590
- border: 1px solid var(--border-subtle);
1591
- border-radius: 6px;
1592
- color: var(--text-secondary);
1593
- font-size: 14px;
1594
- font-weight: 500;
1595
- cursor: pointer;
1596
- transition: all var(--transition-fast);
1597
- }
1598
-
1599
- .spawn-cancel-btn:hover {
1600
- background: rgba(255, 255, 255, 0.05);
1601
- color: var(--text-primary);
1602
- }
1603
-
1604
- .spawn-submit-btn {
1605
- display: flex;
1606
- align-items: center;
1607
- gap: 6px;
1608
- padding: 8px 16px;
1609
- background: var(--accent-green);
1610
- border: none;
1611
- border-radius: 6px;
1612
- color: white;
1613
- font-size: 14px;
1614
- font-weight: 600;
1615
- cursor: pointer;
1616
- transition: all var(--transition-fast);
1617
- }
1618
-
1619
- .spawn-submit-btn:hover:not(:disabled) {
1620
- background: #249966;
1621
- }
1622
-
1623
- .spawn-submit-btn:disabled {
1624
- opacity: 0.5;
1625
- cursor: not-allowed;
1626
- }
1627
-
1628
- /* Spawned Agent Indicator */
1629
- .channel-item .spawned-icon {
1630
- width: 14px;
1631
- height: 14px;
1632
- color: var(--accent-green);
1633
- flex-shrink: 0;
1634
- }
1635
-
1636
- .channel-item .release-btn {
1637
- opacity: 0;
1638
- width: 18px;
1639
- height: 18px;
1640
- border: none;
1641
- background: var(--accent-red);
1642
- color: white;
1643
- border-radius: 4px;
1644
- cursor: pointer;
1645
- display: flex;
1646
- align-items: center;
1647
- justify-content: center;
1648
- transition: opacity var(--transition-fast);
1649
- flex-shrink: 0;
1650
- }
1651
-
1652
- .channel-item:hover .release-btn {
1653
- opacity: 1;
1654
- }
1655
-
1656
- .channel-item .release-btn:hover {
1657
- background: #c41a4f;
1658
- }
1659
-
1660
- /* ========================================
1661
- Fleet View Toggle
1662
- ======================================== */
1663
- .view-toggle {
1664
- display: flex;
1665
- background: rgba(255, 255, 255, 0.06);
1666
- border-radius: 6px;
1667
- padding: 2px;
1668
- margin: 0 12px 8px;
1669
- }
1670
-
1671
- .view-toggle-btn {
1672
- flex: 1;
1673
- padding: 6px 12px;
1674
- border: none;
1675
- background: transparent;
1676
- color: var(--text-muted);
1677
- font-size: 12px;
1678
- font-weight: 500;
1679
- border-radius: 4px;
1680
- cursor: pointer;
1681
- transition: all var(--transition-fast);
1682
- display: flex;
1683
- align-items: center;
1684
- justify-content: center;
1685
- gap: 6px;
1686
- }
1687
-
1688
- .view-toggle-btn:hover {
1689
- color: var(--text-secondary);
1690
- }
1691
-
1692
- .view-toggle-btn.active {
1693
- background: var(--accent-primary);
1694
- color: white;
1695
- }
1696
-
1697
- .view-toggle-btn svg {
1698
- width: 14px;
1699
- height: 14px;
1700
- }
1701
-
1702
- .view-toggle-btn .peer-count {
1703
- font-size: 10px;
1704
- background: rgba(255, 255, 255, 0.2);
1705
- padding: 1px 5px;
1706
- border-radius: 8px;
1707
- margin-left: 4px;
1708
- }
1709
-
1710
- /* Server badge for fleet agents */
1711
- .server-badge {
1712
- display: inline-flex;
1713
- align-items: center;
1714
- gap: 3px;
1715
- padding: 1px 6px;
1716
- background: var(--accent-purple);
1717
- color: white;
1718
- font-size: 9px;
1719
- font-weight: 600;
1720
- border-radius: 3px;
1721
- margin-right: 6px;
1722
- text-transform: uppercase;
1723
- letter-spacing: 0.3px;
1724
- }
1725
-
1726
- .server-badge.local {
1727
- background: var(--accent-primary);
1728
- }
1729
-
1730
- .server-badge .server-dot {
1731
- width: 5px;
1732
- height: 5px;
1733
- border-radius: 50%;
1734
- background: var(--status-online);
1735
- }
1736
-
1737
- .server-badge .server-dot.offline {
1738
- background: var(--status-offline);
1739
- }
1740
-
1741
- /* Peer status in header */
1742
- .peer-status {
1743
- display: flex;
1744
- align-items: center;
1745
- gap: 8px;
1746
- padding: 4px 10px;
1747
- background: rgba(124, 58, 237, 0.15);
1748
- border-radius: 12px;
1749
- font-size: 12px;
1750
- color: var(--accent-purple);
1751
- margin-left: 8px;
1752
- }
1753
-
1754
- .peer-status .peer-dot {
1755
- width: 6px;
1756
- height: 6px;
1757
- border-radius: 50%;
1758
- background: var(--accent-purple);
1759
- }
1760
-
1761
- .peer-status.connected .peer-dot {
1762
- background: var(--status-online);
1763
- }
1764
-
1765
- .peer-status.disconnected {
1766
- background: rgba(97, 96, 97, 0.15);
1767
- color: var(--status-offline);
1768
- }
1769
-
1770
- .peer-status.disconnected .peer-dot {
1771
- background: var(--status-offline);
1772
- }
1773
-
1774
- /* Fleet section in sidebar */
1775
- .fleet-servers-list {
1776
- list-style: none;
1777
- padding: 0 8px;
1778
- margin-bottom: 8px;
1779
- }
1780
-
1781
- .server-item {
1782
- display: flex;
1783
- align-items: center;
1784
- gap: 8px;
1785
- padding: 6px 8px;
1786
- border-radius: 6px;
1787
- font-size: 13px;
1788
- color: var(--text-channel);
1789
- cursor: pointer;
1790
- transition: background var(--transition-fast);
1791
- }
1792
-
1793
- .server-item:hover {
1794
- background: var(--bg-channel-hover);
1795
- }
1796
-
1797
- .server-item .server-icon {
1798
- width: 20px;
1799
- height: 20px;
1800
- border-radius: 4px;
1801
- background: var(--accent-purple);
1802
- display: flex;
1803
- align-items: center;
1804
- justify-content: center;
1805
- position: relative;
1806
- }
1807
-
1808
- .server-item .server-icon svg {
1809
- width: 12px;
1810
- height: 12px;
1811
- color: white;
1812
- }
1813
-
1814
- .server-item .server-icon .status-dot {
1815
- position: absolute;
1816
- bottom: -2px;
1817
- right: -2px;
1818
- width: 8px;
1819
- height: 8px;
1820
- border-radius: 50%;
1821
- background: var(--status-online);
1822
- border: 2px solid var(--bg-sidebar);
1823
- }
1824
-
1825
- .server-item .server-icon .status-dot.offline {
1826
- background: var(--status-offline);
1827
- }
1828
-
1829
- .server-item .server-name {
1830
- flex: 1;
1831
- }
1832
-
1833
- .server-item .agent-count {
1834
- font-size: 11px;
1835
- color: var(--text-muted);
1836
- font-family: var(--font-mono);
1837
- }
1838
-
1839
- /* Fleet agent avatar with server indicator */
1840
- .channel-item .agent-avatar .server-indicator {
1841
- position: absolute;
1842
- top: -3px;
1843
- right: -3px;
1844
- width: 10px;
1845
- height: 10px;
1846
- border-radius: 2px;
1847
- background: var(--accent-purple);
1848
- border: 2px solid var(--bg-sidebar);
1849
- display: flex;
1850
- align-items: center;
1851
- justify-content: center;
1852
- }
1853
-
1854
- .channel-item .agent-avatar .server-indicator.local {
1855
- background: var(--accent-primary);
1856
- }
1857
- </style>
1858
- </head>
1859
- <body>
1860
- <div class="app-container">
1861
- <!-- Sidebar -->
1862
- <aside class="sidebar">
1863
- <div class="workspace-header">
1864
- <div class="workspace-name">
1865
- <span class="status-dot" id="connection-dot"></span>
1866
- Agent Relay
1867
- </div>
1868
- <button class="compose-new-btn" title="New message">
1869
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1870
- <path d="M12 20h9"/>
1871
- <path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/>
1872
- </svg>
1873
- </button>
1874
- </div>
1875
-
1876
- <div class="search-bar" id="search-trigger">
1877
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1878
- <circle cx="11" cy="11" r="8"/>
1879
- <path d="M21 21l-4.35-4.35"/>
1880
- </svg>
1881
- <span>Search</span>
1882
- <kbd>Ctrl K</kbd>
1883
- </div>
1884
-
1885
- <div class="sidebar-content">
1886
- <!-- View Toggle (Local/Fleet) -->
1887
- <div class="view-toggle" id="view-toggle" style="display: none;">
1888
- <button class="view-toggle-btn active" data-view="local">
1889
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1890
- <rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
1891
- <line x1="9" y1="9" x2="15" y2="15"/>
1892
- <line x1="15" y1="9" x2="9" y2="15"/>
1893
- </svg>
1894
- Local
1895
- </button>
1896
- <button class="view-toggle-btn" data-view="fleet">
1897
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1898
- <circle cx="12" cy="12" r="10"/>
1899
- <circle cx="12" cy="12" r="4"/>
1900
- <line x1="12" y1="2" x2="12" y2="6"/>
1901
- <line x1="12" y1="18" x2="12" y2="22"/>
1902
- <line x1="2" y1="12" x2="6" y2="12"/>
1903
- <line x1="18" y1="12" x2="22" y2="12"/>
1904
- </svg>
1905
- Fleet
1906
- <span class="peer-count" id="peer-count">0</span>
1907
- </button>
1908
- </div>
1909
-
1910
- <!-- Peer Servers Section (shown in fleet mode) -->
1911
- <div class="section" id="servers-section" style="display: none;">
1912
- <div class="section-header">
1913
- <div class="section-title">
1914
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1915
- <path d="M6 9l6 6 6-6"/>
1916
- </svg>
1917
- Servers
1918
- </div>
1919
- </div>
1920
- <ul class="fleet-servers-list" id="servers-list">
1921
- <!-- Servers injected here -->
1922
- </ul>
1923
- </div>
1924
-
1925
- <!-- Channels Section -->
1926
- <div class="section">
1927
- <div class="section-header" id="channels-header">
1928
- <div class="section-title">
1929
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1930
- <path d="M6 9l6 6 6-6"/>
1931
- </svg>
1932
- Channels
1933
- </div>
1934
- </div>
1935
- <ul class="channel-list" id="channels-list">
1936
- <li class="channel-item active" data-channel="general">
1937
- <span class="channel-prefix">#</span>
1938
- <span class="channel-name">general</span>
1939
- </li>
1940
- </ul>
1941
- </div>
1942
-
1943
- <!-- Agents Section -->
1944
- <div class="section">
1945
- <div class="section-header" id="agents-header">
1946
- <div class="section-title">
1947
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1948
- <path d="M6 9l6 6 6-6"/>
1949
- </svg>
1950
- Agents
1951
- </div>
1952
- <button class="section-add-btn" id="spawn-btn" title="Spawn new agent" style="opacity: 1;">
1953
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1954
- <line x1="12" y1="5" x2="12" y2="19"/>
1955
- <line x1="5" y1="12" x2="19" y2="12"/>
1956
- </svg>
1957
- </button>
1958
- </div>
1959
- <ul class="channel-list" id="agents-list">
1960
- <!-- Agents injected here -->
1961
- </ul>
1962
- </div>
1963
-
1964
- </div>
1965
-
1966
- <div class="sidebar-footer">
1967
- <a href="/metrics" class="nav-link">
1968
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1969
- <path d="M3 3v18h18"/>
1970
- <path d="M18 17V9"/>
1971
- <path d="M13 17V5"/>
1972
- <path d="M8 17v-3"/>
1973
- </svg>
1974
- Metrics
1975
- </a>
1976
- <a href="/bridge" class="nav-link">
1977
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1978
- <rect x="3" y="3" width="7" height="7"/>
1979
- <rect x="14" y="3" width="7" height="7"/>
1980
- <rect x="14" y="14" width="7" height="7"/>
1981
- <rect x="3" y="14" width="7" height="7"/>
1982
- </svg>
1983
- Bridge View
1984
- </a>
1985
- </div>
1986
- </aside>
1987
-
1988
- <!-- Main Panel -->
1989
- <main class="main-panel">
1990
- <header class="channel-header">
1991
- <div class="channel-header-name">
1992
- <span class="prefix">#</span>
1993
- <span id="current-channel-name">general</span>
1994
- </div>
1995
- <div class="header-divider"></div>
1996
- <div class="channel-topic" id="channel-topic">All agent communications</div>
1997
- <div class="header-actions">
1998
- <div class="online-count">
1999
- <span class="dot"></span>
2000
- <span id="online-count">0 online</span>
2001
- </div>
2002
- </div>
2003
- </header>
2004
-
2005
- <div class="messages-container">
2006
- <div class="messages-list" id="messages-list">
2007
- <!-- Messages injected here -->
2008
- </div>
2009
- <div class="typing-indicator" id="typing-indicator">
2010
- <div class="typing-dots">
2011
- <span></span>
2012
- <span></span>
2013
- <span></span>
2014
- </div>
2015
- <span id="typing-text">Someone is typing...</span>
2016
- </div>
2017
- </div>
2018
-
2019
- <div class="composer">
2020
- <div class="composer-container" style="position: relative;">
2021
- <!-- @-Mention Autocomplete Dropdown -->
2022
- <div class="mention-autocomplete" id="mention-autocomplete">
2023
- <div class="mention-autocomplete-header">Agents</div>
2024
- <div id="mention-autocomplete-list">
2025
- <!-- Agent items will be injected here -->
2026
- </div>
2027
- <div class="mention-autocomplete-hint">
2028
- <span><kbd>Tab</kbd> or <kbd>Enter</kbd> to select</span>
2029
- <span><kbd>↑↓</kbd> to navigate</span>
2030
- <span><kbd>Esc</kbd> to close</span>
2031
- </div>
2032
- </div>
2033
- <div class="composer-input-row">
2034
- <div class="composer-toolbar">
2035
- <button class="toolbar-btn" id="bold-btn" title="Bold (Ctrl+B)">
2036
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2037
- <path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/>
2038
- <path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/>
2039
- </svg>
2040
- </button>
2041
- <button class="toolbar-btn" id="emoji-btn" title="Add emoji">
2042
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2043
- <circle cx="12" cy="12" r="10"/>
2044
- <path d="M8 14s1.5 2 4 2 4-2 4-2"/>
2045
- <line x1="9" y1="9" x2="9.01" y2="9"/>
2046
- <line x1="15" y1="9" x2="15.01" y2="9"/>
2047
- </svg>
2048
- </button>
2049
- </div>
2050
- <textarea
2051
- id="message-input"
2052
- class="composer-input"
2053
- placeholder="@AgentName message... (or @* to broadcast)"
2054
- rows="1"
2055
- ></textarea>
2056
- <div class="composer-send">
2057
- <button class="send-btn" id="send-btn" title="Send message">
2058
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2059
- <line x1="22" y1="2" x2="11" y2="13"/>
2060
- <polygon points="22 2 15 22 11 13 2 9 22 2"/>
2061
- </svg>
2062
- </button>
2063
- </div>
2064
- </div>
2065
- </div>
2066
- <div class="composer-hint">
2067
- <kbd>Ctrl</kbd> + <kbd>Enter</kbd> to send
2068
- </div>
2069
- </div>
2070
- </main>
2071
- </div>
2072
-
2073
- <!-- Command Palette -->
2074
- <div class="command-palette-overlay" id="command-palette-overlay">
2075
- <div class="command-palette">
2076
- <div class="palette-search">
2077
- <input
2078
- type="text"
2079
- class="palette-search-input"
2080
- id="palette-search"
2081
- placeholder="Search messages, agents, or type a command..."
2082
- autocomplete="off"
2083
- >
2084
- </div>
2085
- <div class="palette-results" id="palette-results">
2086
- <div class="palette-section">
2087
- <div class="palette-section-title">Commands</div>
2088
- <div class="palette-item" data-command="broadcast">
2089
- <div class="palette-item-icon">
2090
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2091
- <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/>
2092
- <path d="M15.54 8.46a5 5 0 0 1 0 7.07"/>
2093
- <path d="M19.07 4.93a10 10 0 0 1 0 14.14"/>
2094
- </svg>
2095
- </div>
2096
- <div class="palette-item-content">
2097
- <div class="palette-item-title">/broadcast</div>
2098
- <div class="palette-item-subtitle">Send message to all agents</div>
2099
- </div>
2100
- </div>
2101
- <div class="palette-item" data-command="status">
2102
- <div class="palette-item-icon">
2103
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2104
- <circle cx="12" cy="12" r="10"/>
2105
- <path d="M12 6v6l4 2"/>
2106
- </svg>
2107
- </div>
2108
- <div class="palette-item-content">
2109
- <div class="palette-item-title">/status</div>
2110
- <div class="palette-item-subtitle">Set your status message</div>
2111
- </div>
2112
- </div>
2113
- <div class="palette-item" data-command="clear">
2114
- <div class="palette-item-icon">
2115
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2116
- <path d="M3 6h18"/>
2117
- <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
2118
- </svg>
2119
- </div>
2120
- <div class="palette-item-content">
2121
- <div class="palette-item-title">/clear</div>
2122
- <div class="palette-item-subtitle">Clear message view</div>
2123
- </div>
2124
- </div>
2125
- </div>
2126
- <div class="palette-section" id="palette-channels-section">
2127
- <div class="palette-section-title">Channels</div>
2128
- <div class="palette-item" data-jump-channel="general">
2129
- <div class="palette-item-icon">
2130
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2131
- <path d="M4 9l4-4 4 4"/>
2132
- <path d="M12 15l4 4 4-4"/>
2133
- <line x1="8" y1="5" x2="8" y2="19"/>
2134
- <line x1="16" y1="5" x2="16" y2="19"/>
2135
- </svg>
2136
- </div>
2137
- <div class="palette-item-content">
2138
- <div class="palette-item-title">#general</div>
2139
- <div class="palette-item-subtitle">All agent communications</div>
2140
- </div>
2141
- </div>
2142
- </div>
2143
- <div class="palette-section" id="palette-agents-section">
2144
- <div class="palette-section-title">Jump to Agent</div>
2145
- <!-- Agents will be injected here -->
2146
- </div>
2147
- <div class="palette-section" id="palette-messages-section" style="display: none;">
2148
- <div class="palette-section-title">Recent Messages</div>
2149
- <!-- Filtered messages will be injected here -->
2150
- </div>
2151
- </div>
2152
- </div>
2153
- </div>
2154
-
2155
- <!-- Thread Panel -->
2156
- <div class="thread-panel-overlay" id="thread-panel-overlay">
2157
- <div class="thread-panel">
2158
- <div class="thread-panel-header">
2159
- <div class="thread-panel-title">
2160
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2161
- <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
2162
- </svg>
2163
- <span>Thread</span>
2164
- <span class="thread-id" id="thread-panel-id"></span>
2165
- </div>
2166
- <button class="thread-panel-close" id="thread-panel-close" title="Close thread">
2167
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2168
- <line x1="18" y1="6" x2="6" y2="18"/>
2169
- <line x1="6" y1="6" x2="18" y2="18"/>
2170
- </svg>
2171
- </button>
2172
- </div>
2173
- <div class="thread-messages" id="thread-messages">
2174
- <!-- Thread messages will be injected here -->
2175
- </div>
2176
- <div class="thread-composer">
2177
- <textarea
2178
- id="thread-message-input"
2179
- class="thread-composer-input"
2180
- placeholder="Reply in thread..."
2181
- rows="1"
2182
- ></textarea>
2183
- <button class="thread-send-btn" id="thread-send-btn" title="Send reply">
2184
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2185
- <line x1="22" y1="2" x2="11" y2="13"/>
2186
- <polygon points="22 2 15 22 11 13 2 9 22 2"/>
2187
- </svg>
2188
- </button>
2189
- </div>
2190
- </div>
2191
- </div>
2192
-
2193
- <!-- Spawn Agent Modal -->
2194
- <div class="spawn-modal-overlay" id="spawn-modal-overlay">
2195
- <div class="spawn-modal">
2196
- <div class="spawn-modal-header">
2197
- <div class="spawn-modal-title">
2198
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2199
- <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
2200
- <circle cx="12" cy="7" r="4"/>
2201
- <line x1="12" y1="11" x2="12" y2="17"/>
2202
- <line x1="9" y1="14" x2="15" y2="14"/>
2203
- </svg>
2204
- Spawn New Agent
2205
- </div>
2206
- <button class="spawn-modal-close" id="spawn-modal-close" title="Close">
2207
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2208
- <line x1="18" y1="6" x2="6" y2="18"/>
2209
- <line x1="6" y1="6" x2="18" y2="18"/>
2210
- </svg>
2211
- </button>
2212
- </div>
2213
- <div class="spawn-modal-body">
2214
- <div class="spawn-form-group">
2215
- <label for="spawn-name-input">Agent Name</label>
2216
- <input
2217
- type="text"
2218
- id="spawn-name-input"
2219
- class="spawn-input"
2220
- placeholder="e.g., Developer, Reviewer, Tester"
2221
- autocomplete="off"
2222
- />
2223
- </div>
2224
- <div class="spawn-form-group">
2225
- <label for="spawn-cli-input">CLI Command</label>
2226
- <input
2227
- type="text"
2228
- id="spawn-cli-input"
2229
- class="spawn-input"
2230
- value="claude"
2231
- placeholder="e.g., claude, aider, cursor"
2232
- />
2233
- <span class="spawn-hint">The AI CLI tool to wrap</span>
2234
- </div>
2235
- <div class="spawn-form-group">
2236
- <label for="spawn-task-input">Initial Task (optional)</label>
2237
- <textarea
2238
- id="spawn-task-input"
2239
- class="spawn-textarea"
2240
- placeholder="Enter an initial task to send to the agent..."
2241
- rows="4"
2242
- ></textarea>
2243
- <span class="spawn-hint">This will be injected into the agent's terminal</span>
2244
- </div>
2245
- <div class="spawn-status" id="spawn-status"></div>
2246
- </div>
2247
- <div class="spawn-modal-footer">
2248
- <button class="spawn-cancel-btn" id="spawn-cancel-btn">Cancel</button>
2249
- <button class="spawn-submit-btn" id="spawn-submit-btn">
2250
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2251
- <polygon points="5 3 19 12 5 21 5 3"/>
2252
- </svg>
2253
- Spawn Agent
2254
- </button>
2255
- </div>
2256
- </div>
2257
- </div>
2258
-
2259
- <!-- Dashboard Application (TypeScript bundled) -->
2260
- <script type="module" src="/js/app.js"></script>
2261
- </body>
2262
- </html>