neohive 6.1.4 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.js +9 -1
- package/dashboard.html +300 -842
- package/dashboard.js +13 -4
- package/package.json +1 -1
package/dashboard.html
CHANGED
|
@@ -402,57 +402,46 @@
|
|
|
402
402
|
.agent-card {
|
|
403
403
|
background: var(--surface-2);
|
|
404
404
|
border: 1px solid var(--border);
|
|
405
|
-
border-radius:
|
|
406
|
-
padding:
|
|
407
|
-
margin-bottom:
|
|
408
|
-
transition:
|
|
405
|
+
border-radius: 10px;
|
|
406
|
+
padding: 10px 12px;
|
|
407
|
+
margin-bottom: 4px;
|
|
408
|
+
transition: background 0.15s ease, border-color 0.15s ease;
|
|
409
409
|
cursor: pointer;
|
|
410
410
|
position: relative;
|
|
411
411
|
overflow: hidden;
|
|
412
412
|
}
|
|
413
413
|
|
|
414
414
|
.agent-card:hover {
|
|
415
|
-
transform: translateX(4px);
|
|
416
|
-
border-color: var(--nh-accent-50);
|
|
417
415
|
background: var(--surface-3);
|
|
418
|
-
|
|
416
|
+
border-color: var(--border-light);
|
|
419
417
|
}
|
|
420
418
|
|
|
421
419
|
.agent-card.working, .agent-card.active {
|
|
422
|
-
|
|
423
|
-
box-shadow: 0 0 15px var(--green-dim);
|
|
424
|
-
animation: nh-glow-pulse 2s infinite ease-in-out;
|
|
420
|
+
background: var(--surface-3);
|
|
425
421
|
}
|
|
426
422
|
|
|
427
|
-
.agent-card.dead, .agent-card.offline {
|
|
428
|
-
|
|
429
|
-
}
|
|
430
|
-
.agent-card.unknown {
|
|
431
|
-
opacity: 0.4;
|
|
432
|
-
border-left: 3px solid var(--nh-text-muted);
|
|
433
|
-
}
|
|
434
|
-
.agent-card.stale {
|
|
435
|
-
opacity: 0.65;
|
|
436
|
-
border-left: 3px solid var(--orange);
|
|
437
|
-
}
|
|
423
|
+
.agent-card.dead, .agent-card.offline { opacity: 0.45; }
|
|
424
|
+
.agent-card.unknown { opacity: 0.35; }
|
|
425
|
+
.agent-card.stale { opacity: 0.6; }
|
|
438
426
|
|
|
439
427
|
.agent-top {
|
|
440
428
|
display: flex;
|
|
441
429
|
align-items: center;
|
|
442
|
-
gap:
|
|
430
|
+
gap: 10px;
|
|
443
431
|
}
|
|
444
432
|
|
|
445
433
|
.agent-avatar {
|
|
446
|
-
width:
|
|
447
|
-
height:
|
|
448
|
-
border-radius:
|
|
434
|
+
width: 32px;
|
|
435
|
+
height: 32px;
|
|
436
|
+
border-radius: 8px;
|
|
449
437
|
display: flex;
|
|
450
438
|
align-items: center;
|
|
451
439
|
justify-content: center;
|
|
452
440
|
font-weight: 700;
|
|
453
|
-
font-size:
|
|
441
|
+
font-size: 13px;
|
|
454
442
|
color: #fff;
|
|
455
443
|
flex-shrink: 0;
|
|
444
|
+
letter-spacing: -0.02em;
|
|
456
445
|
}
|
|
457
446
|
|
|
458
447
|
.agent-info { flex: 1; min-width: 0; }
|
|
@@ -463,18 +452,18 @@
|
|
|
463
452
|
border-radius: 50%;
|
|
464
453
|
flex-shrink: 0;
|
|
465
454
|
}
|
|
466
|
-
.agent-status-dot.active, .agent-status-dot.working { background: var(--green); box-shadow: var(--
|
|
467
|
-
.agent-status-dot.listening { background: var(--nh-blue); box-shadow: 0 0
|
|
468
|
-
.agent-status-dot.sleeping, .agent-status-dot.idle { background: var(--nh-accent);
|
|
469
|
-
.agent-status-dot.dead, .agent-status-dot.offline { background: var(--nh-text-muted); }
|
|
470
|
-
.agent-status-dot.unknown { background: var(--nh-text-muted); opacity: 0.
|
|
471
|
-
.agent-status-dot.stale { background: var(--orange);
|
|
472
|
-
.agent-status-dot.unresponsive { background: var(--orange, #f97316);
|
|
473
|
-
.agent-status-dot.stuck { background: var(--red, #ef4444);
|
|
455
|
+
.agent-status-dot.active, .agent-status-dot.working { background: var(--green); box-shadow: 0 0 4px var(--green); }
|
|
456
|
+
.agent-status-dot.listening { background: var(--nh-blue); box-shadow: 0 0 4px var(--nh-blue); animation: pulse 2s infinite; }
|
|
457
|
+
.agent-status-dot.sleeping, .agent-status-dot.idle { background: var(--nh-accent); }
|
|
458
|
+
.agent-status-dot.dead, .agent-status-dot.offline { background: var(--nh-text-muted); opacity: 0.4; }
|
|
459
|
+
.agent-status-dot.unknown { background: var(--nh-text-muted); opacity: 0.3; }
|
|
460
|
+
.agent-status-dot.stale { background: var(--orange); }
|
|
461
|
+
.agent-status-dot.unresponsive { background: var(--orange, #f97316); animation: pulse 2s infinite; }
|
|
462
|
+
.agent-status-dot.stuck { background: var(--red, #ef4444); animation: pulse 1.2s infinite; }
|
|
474
463
|
|
|
475
464
|
.agent-state-pill { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 99px; font-size: 10px; font-weight: 600; letter-spacing: 0.02em; line-height: 16px; flex-shrink: 0; }
|
|
476
|
-
.agent-state-pill.listening { background: rgba(96,165,250,0.
|
|
477
|
-
.agent-state-pill.working { background: rgba(
|
|
465
|
+
.agent-state-pill.listening { background: rgba(96,165,250,0.12); color: #60a5fa; }
|
|
466
|
+
.agent-state-pill.working { background: rgba(74,222,128,0.12); color: #4ade80; }
|
|
478
467
|
.agent-current-tool { font-size: 10px; color: var(--nh-text-muted, #6b7280); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 150px; }
|
|
479
468
|
|
|
480
469
|
.agent-card.stuck { border-color: rgba(239, 68, 68, 0.3); }
|
|
@@ -483,20 +472,22 @@
|
|
|
483
472
|
.agent-name {
|
|
484
473
|
font-weight: 600;
|
|
485
474
|
font-size: 13px;
|
|
475
|
+
color: var(--text);
|
|
486
476
|
white-space: nowrap;
|
|
487
477
|
overflow: hidden;
|
|
488
478
|
text-overflow: ellipsis;
|
|
489
479
|
}
|
|
490
480
|
|
|
491
481
|
.agent-subtitle {
|
|
492
|
-
font-size:
|
|
482
|
+
font-size: 11px;
|
|
493
483
|
color: var(--text-muted);
|
|
494
484
|
white-space: nowrap;
|
|
495
485
|
overflow: hidden;
|
|
496
486
|
text-overflow: ellipsis;
|
|
487
|
+
margin-top: 1px;
|
|
497
488
|
}
|
|
498
489
|
|
|
499
|
-
/* ===== AGENT SKILLS ===== */
|
|
490
|
+
/* ===== AGENT SKILLS (visible in popup, hidden in card) ===== */
|
|
500
491
|
.agent-skills {
|
|
501
492
|
display: flex;
|
|
502
493
|
flex-wrap: wrap;
|
|
@@ -508,66 +499,45 @@
|
|
|
508
499
|
font-size: 9px;
|
|
509
500
|
padding: 1px 5px;
|
|
510
501
|
border-radius: 4px;
|
|
511
|
-
background: var(--
|
|
512
|
-
color: var(--
|
|
513
|
-
border:
|
|
502
|
+
background: var(--accent-dim);
|
|
503
|
+
color: var(--accent);
|
|
504
|
+
border: none;
|
|
505
|
+
font-weight: 500;
|
|
514
506
|
}
|
|
515
507
|
|
|
516
|
-
/* ===== NUDGE
|
|
508
|
+
/* ===== NUDGE ===== */
|
|
517
509
|
.agent-nudge-btn {
|
|
518
510
|
position: absolute;
|
|
519
511
|
top: 8px;
|
|
520
512
|
right: 8px;
|
|
521
|
-
width:
|
|
522
|
-
height:
|
|
513
|
+
width: 22px;
|
|
514
|
+
height: 22px;
|
|
523
515
|
border-radius: 6px;
|
|
524
|
-
background:
|
|
525
|
-
border: 1px solid
|
|
526
|
-
color: var(--
|
|
516
|
+
background: transparent;
|
|
517
|
+
border: 1px solid transparent;
|
|
518
|
+
color: var(--text-muted);
|
|
527
519
|
display: flex;
|
|
528
520
|
align-items: center;
|
|
529
521
|
justify-content: center;
|
|
530
522
|
cursor: pointer;
|
|
531
523
|
opacity: 0;
|
|
532
|
-
transition: all 0.
|
|
524
|
+
transition: all 0.15s ease;
|
|
533
525
|
z-index: 10;
|
|
534
526
|
}
|
|
535
|
-
.agent-card:hover .agent-nudge-btn { opacity:
|
|
536
|
-
.agent-nudge-btn:hover {
|
|
527
|
+
.agent-card:hover .agent-nudge-btn { opacity: 0.6; }
|
|
528
|
+
.agent-nudge-btn:hover { opacity: 1 !important; color: var(--red); }
|
|
537
529
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
border-top: 1px solid var(--nh-divider);
|
|
544
|
-
align-items: center;
|
|
545
|
-
}
|
|
546
|
-
.listen-sparkline-label {
|
|
547
|
-
font-size: 9px;
|
|
548
|
-
color: var(--text-muted);
|
|
549
|
-
text-transform: uppercase;
|
|
550
|
-
font-weight: 700;
|
|
551
|
-
margin-right: 4px;
|
|
552
|
-
letter-spacing: 0.5px;
|
|
553
|
-
}
|
|
554
|
-
.hb-dot {
|
|
555
|
-
width: 6px;
|
|
556
|
-
height: 6px;
|
|
557
|
-
border-radius: 50%;
|
|
558
|
-
background: var(--nh-divider-strong);
|
|
559
|
-
transition: all 0.3s ease;
|
|
560
|
-
}
|
|
561
|
-
.hb-dot.active {
|
|
562
|
-
background: var(--nh-green);
|
|
563
|
-
box-shadow: 0 0 6px var(--nh-green);
|
|
564
|
-
}
|
|
530
|
+
/* Sparkline kept for JS compat but hidden in card */
|
|
531
|
+
.listen-sparkline { display: none; }
|
|
532
|
+
.listen-sparkline-label { display: none; }
|
|
533
|
+
.hb-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--nh-divider-strong); }
|
|
534
|
+
.hb-dot.active { background: var(--nh-green); }
|
|
565
535
|
.hb-dot.stale { background: var(--nh-orange); opacity: 0.5; }
|
|
566
536
|
.hb-dot.empty { background: transparent; border: 1px solid var(--nh-divider); }
|
|
567
537
|
|
|
568
538
|
@keyframes stuck-pulse {
|
|
569
539
|
0% { border-color: var(--nh-divider); }
|
|
570
|
-
50% { border-color: var(--nh-red);
|
|
540
|
+
50% { border-color: var(--nh-red); }
|
|
571
541
|
100% { border-color: var(--nh-divider); }
|
|
572
542
|
}
|
|
573
543
|
.agent-card.stuck {
|
|
@@ -1073,7 +1043,7 @@
|
|
|
1073
1043
|
.msg-avatar {
|
|
1074
1044
|
width: 36px;
|
|
1075
1045
|
height: 36px;
|
|
1076
|
-
border-radius:
|
|
1046
|
+
border-radius: 8px;
|
|
1077
1047
|
display: flex;
|
|
1078
1048
|
align-items: center;
|
|
1079
1049
|
justify-content: center;
|
|
@@ -1845,18 +1815,17 @@
|
|
|
1845
1815
|
margin: 1px 6px;
|
|
1846
1816
|
position: relative;
|
|
1847
1817
|
}
|
|
1848
|
-
.nav-item:hover { background: var(--
|
|
1818
|
+
.nav-item:hover { background: var(--surface-2); color: var(--text); }
|
|
1849
1819
|
.nav-item.active {
|
|
1850
|
-
background:
|
|
1820
|
+
background: var(--surface-2);
|
|
1851
1821
|
border-color: transparent;
|
|
1852
|
-
box-shadow: inset 3px 0 0 var(--nh-accent);
|
|
1853
1822
|
}
|
|
1854
1823
|
.nav-item .nav-icon { line-height: 0; flex-shrink: 0; width: 20px; min-width: 20px; display: flex; align-items: center; justify-content: center; color: var(--text-muted); }
|
|
1855
1824
|
.nav-item .nav-icon svg { flex-shrink: 0; width: 16px; height: 16px; }
|
|
1856
|
-
.nav-item.active .nav-icon { color: var(--
|
|
1825
|
+
.nav-item.active .nav-icon { color: var(--text); }
|
|
1857
1826
|
.nav-item:hover .nav-icon { color: var(--text); }
|
|
1858
1827
|
.nav-item .nav-text { font-size: 14px; font-weight: 500; color: var(--text-dim); }
|
|
1859
|
-
.nav-item.active .nav-text { color: var(--
|
|
1828
|
+
.nav-item.active .nav-text { color: var(--text); font-weight: 600; }
|
|
1860
1829
|
.nav-item:hover .nav-text { color: var(--text); }
|
|
1861
1830
|
.nav-sidebar.collapsed .nav-item { justify-content: center; padding: 10px 4px; margin: 0; }
|
|
1862
1831
|
.nav-sidebar.collapsed .nav-item .nav-text { display: none; }
|
|
@@ -2584,6 +2553,8 @@
|
|
|
2584
2553
|
.kanban-title.blocked { background: var(--red-dim); color: var(--red); }
|
|
2585
2554
|
.kanban-title.blocked_permanent { background: var(--red); color: #fff; }
|
|
2586
2555
|
|
|
2556
|
+
.task-card.blocked_permanent { border-color: var(--red); border-left: 3px solid var(--red); background: var(--red-dim); }
|
|
2557
|
+
|
|
2587
2558
|
.kanban-count {
|
|
2588
2559
|
font-size: 10px;
|
|
2589
2560
|
opacity: 0.7;
|
|
@@ -2941,7 +2912,6 @@
|
|
|
2941
2912
|
display: flex;
|
|
2942
2913
|
align-items: flex-start;
|
|
2943
2914
|
gap: 8px;
|
|
2944
|
-
border-left: 3px solid var(--nh-border, var(--border));
|
|
2945
2915
|
}
|
|
2946
2916
|
.system-event-banner .event-icon {
|
|
2947
2917
|
flex-shrink: 0;
|
|
@@ -2973,22 +2943,16 @@
|
|
|
2973
2943
|
flex-shrink: 0;
|
|
2974
2944
|
margin-top: 2px;
|
|
2975
2945
|
}
|
|
2976
|
-
/* Type colors —
|
|
2977
|
-
.system-event-banner.evt-critical { border-left-color: #ef4444; }
|
|
2946
|
+
/* Type colors — icon + text */
|
|
2978
2947
|
.system-event-banner.evt-critical .event-icon { color: #ef4444; }
|
|
2979
2948
|
.system-event-banner.evt-critical .event-text { color: #ef4444; font-weight: 500; }
|
|
2980
|
-
.system-event-banner.evt-warning { border-left-color: #f59e0b; }
|
|
2981
2949
|
.system-event-banner.evt-warning .event-icon { color: #f59e0b; }
|
|
2982
2950
|
.system-event-banner.evt-warning .event-text { color: #f59e0b; }
|
|
2983
|
-
.system-event-banner.evt-event { border-left-color: #22c55e; }
|
|
2984
2951
|
.system-event-banner.evt-event .event-icon { color: #22c55e; }
|
|
2985
|
-
.system-event-banner.evt-review { border-left-color: #3b82f6; }
|
|
2986
2952
|
.system-event-banner.evt-review .event-icon { color: #3b82f6; }
|
|
2987
|
-
.system-event-banner.evt-status { border-left-color: #6b7280; }
|
|
2988
2953
|
.system-event-banner.evt-status .event-icon { color: #6b7280; }
|
|
2989
|
-
.system-event-banner.evt-role { border-left-color: #8b5cf6; }
|
|
2990
2954
|
.system-event-banner.evt-role .event-icon { color: #8b5cf6; }
|
|
2991
|
-
.system-event-banner.evt-violation {
|
|
2955
|
+
.system-event-banner.evt-violation { background: rgba(239,68,68,0.05); }
|
|
2992
2956
|
.system-event-banner.evt-violation .event-icon { color: #ef4444; }
|
|
2993
2957
|
.system-event-banner.evt-violation .event-text { color: var(--text); font-weight: 500; }
|
|
2994
2958
|
|
|
@@ -3244,9 +3208,9 @@
|
|
|
3244
3208
|
|
|
3245
3209
|
/* ===== v3.0: PROFILE AVATAR ===== */
|
|
3246
3210
|
.agent-avatar-img {
|
|
3247
|
-
width:
|
|
3248
|
-
height:
|
|
3249
|
-
border-radius:
|
|
3211
|
+
width: 32px;
|
|
3212
|
+
height: 32px;
|
|
3213
|
+
border-radius: 8px;
|
|
3250
3214
|
object-fit: cover;
|
|
3251
3215
|
flex-shrink: 0;
|
|
3252
3216
|
}
|
|
@@ -3254,7 +3218,7 @@
|
|
|
3254
3218
|
.msg-avatar-img {
|
|
3255
3219
|
width: 36px;
|
|
3256
3220
|
height: 36px;
|
|
3257
|
-
border-radius:
|
|
3221
|
+
border-radius: 8px;
|
|
3258
3222
|
object-fit: cover;
|
|
3259
3223
|
flex-shrink: 0;
|
|
3260
3224
|
margin-top: 2px;
|
|
@@ -3263,33 +3227,27 @@
|
|
|
3263
3227
|
|
|
3264
3228
|
.role-badge {
|
|
3265
3229
|
font-size: 9px;
|
|
3266
|
-
padding:
|
|
3230
|
+
padding: 2px 6px;
|
|
3267
3231
|
border-radius: 6px;
|
|
3268
3232
|
font-weight: 600;
|
|
3269
|
-
background: var(--purple-dim);
|
|
3270
|
-
color: var(--purple);
|
|
3271
3233
|
margin-left: 4px;
|
|
3272
3234
|
}
|
|
3273
3235
|
|
|
3274
|
-
/* =====
|
|
3236
|
+
/* ===== v4.0: AGENT POPUP (stats-first, compact) ===== */
|
|
3275
3237
|
.profile-popup {
|
|
3276
3238
|
display: none;
|
|
3277
3239
|
position: fixed;
|
|
3278
3240
|
z-index: 300;
|
|
3279
3241
|
background: var(--surface);
|
|
3280
|
-
background-image: var(--gradient-surface);
|
|
3281
3242
|
border: 1px solid var(--border-light);
|
|
3282
|
-
border-radius:
|
|
3243
|
+
border-radius: 12px;
|
|
3283
3244
|
padding: 0;
|
|
3284
|
-
width:
|
|
3245
|
+
width: 280px;
|
|
3285
3246
|
box-sizing: border-box;
|
|
3286
|
-
max-height:
|
|
3287
|
-
overflow
|
|
3288
|
-
overflow-y: hidden;
|
|
3247
|
+
max-height: 70vh;
|
|
3248
|
+
overflow: hidden;
|
|
3289
3249
|
word-break: break-word;
|
|
3290
|
-
box-shadow:
|
|
3291
|
-
backdrop-filter: blur(12px);
|
|
3292
|
-
-webkit-backdrop-filter: blur(12px);
|
|
3250
|
+
box-shadow: 0 8px 30px rgba(0,0,0,0.35);
|
|
3293
3251
|
}
|
|
3294
3252
|
|
|
3295
3253
|
.profile-popup.open { display: block; }
|
|
@@ -3297,40 +3255,40 @@
|
|
|
3297
3255
|
.profile-popup-header {
|
|
3298
3256
|
display: flex;
|
|
3299
3257
|
align-items: center;
|
|
3300
|
-
gap:
|
|
3301
|
-
padding: 16px
|
|
3258
|
+
gap: 10px;
|
|
3259
|
+
padding: 14px 16px 10px;
|
|
3302
3260
|
}
|
|
3303
3261
|
|
|
3304
3262
|
.profile-popup-avatar {
|
|
3305
|
-
width:
|
|
3306
|
-
height:
|
|
3307
|
-
border-radius:
|
|
3263
|
+
width: 36px;
|
|
3264
|
+
height: 36px;
|
|
3265
|
+
border-radius: 8px;
|
|
3308
3266
|
object-fit: cover;
|
|
3309
3267
|
flex-shrink: 0;
|
|
3310
3268
|
}
|
|
3311
3269
|
|
|
3312
3270
|
.profile-popup-name {
|
|
3313
3271
|
font-weight: 700;
|
|
3314
|
-
font-size:
|
|
3272
|
+
font-size: 14px;
|
|
3315
3273
|
line-height: 1.2;
|
|
3316
3274
|
}
|
|
3317
3275
|
|
|
3318
3276
|
.profile-popup-id {
|
|
3319
|
-
font-size:
|
|
3277
|
+
font-size: 10px;
|
|
3320
3278
|
color: var(--text-muted);
|
|
3279
|
+
margin-top: 1px;
|
|
3321
3280
|
}
|
|
3322
3281
|
|
|
3323
3282
|
.pp-status-badge {
|
|
3324
3283
|
display: inline-flex;
|
|
3325
3284
|
align-items: center;
|
|
3326
|
-
|
|
3327
|
-
font-size: 10px;
|
|
3285
|
+
font-size: 9px;
|
|
3328
3286
|
font-weight: 600;
|
|
3329
3287
|
text-transform: uppercase;
|
|
3330
3288
|
letter-spacing: 0.3px;
|
|
3331
|
-
padding:
|
|
3332
|
-
border-radius:
|
|
3333
|
-
margin-left:
|
|
3289
|
+
padding: 1px 6px;
|
|
3290
|
+
border-radius: 6px;
|
|
3291
|
+
margin-left: 4px;
|
|
3334
3292
|
}
|
|
3335
3293
|
.pp-status-badge.online { background: rgba(52,211,153,0.15); color: #34d399; }
|
|
3336
3294
|
.pp-status-badge.offline { background: rgba(156,163,175,0.15); color: #9ca3af; }
|
|
@@ -3338,36 +3296,15 @@
|
|
|
3338
3296
|
.pp-status-badge.unresponsive { background: rgba(249,115,22,0.15); color: #f97316; }
|
|
3339
3297
|
.pp-status-badge.stuck { background: rgba(239,68,68,0.15); color: #ef4444; }
|
|
3340
3298
|
|
|
3341
|
-
/*
|
|
3342
|
-
.pp-tabs {
|
|
3343
|
-
|
|
3344
|
-
border-bottom: 1px solid var(--border);
|
|
3345
|
-
padding: 0 18px;
|
|
3346
|
-
gap: 0;
|
|
3347
|
-
}
|
|
3348
|
-
.pp-tab {
|
|
3349
|
-
flex: 1;
|
|
3350
|
-
padding: 8px 0;
|
|
3351
|
-
font-size: 11px;
|
|
3352
|
-
font-weight: 600;
|
|
3353
|
-
text-transform: uppercase;
|
|
3354
|
-
letter-spacing: 0.4px;
|
|
3355
|
-
color: var(--text-muted);
|
|
3356
|
-
background: none;
|
|
3357
|
-
border: none;
|
|
3358
|
-
border-bottom: 2px solid transparent;
|
|
3359
|
-
cursor: pointer;
|
|
3360
|
-
text-align: center;
|
|
3361
|
-
transition: color 0.15s, border-color 0.15s;
|
|
3362
|
-
}
|
|
3363
|
-
.pp-tab:hover { color: var(--text); }
|
|
3364
|
-
.pp-tab.active { color: var(--nh-accent); border-bottom-color: var(--nh-accent); }
|
|
3299
|
+
/* Tabs hidden by default — kept for JS compat */
|
|
3300
|
+
.pp-tabs { display: none; }
|
|
3301
|
+
.pp-tab { display: none; }
|
|
3365
3302
|
|
|
3366
|
-
/* Tab content */
|
|
3303
|
+
/* Tab content — stats always visible */
|
|
3367
3304
|
.pp-tab-content {
|
|
3368
3305
|
display: none;
|
|
3369
|
-
padding:
|
|
3370
|
-
max-height: calc(
|
|
3306
|
+
padding: 0 16px 14px;
|
|
3307
|
+
max-height: calc(70vh - 100px);
|
|
3371
3308
|
overflow-y: auto;
|
|
3372
3309
|
overflow-x: hidden;
|
|
3373
3310
|
}
|
|
@@ -3398,12 +3335,11 @@
|
|
|
3398
3335
|
display: grid;
|
|
3399
3336
|
grid-template-columns: 1fr 1fr;
|
|
3400
3337
|
gap: 6px;
|
|
3401
|
-
margin-top: 8px;
|
|
3402
3338
|
}
|
|
3403
3339
|
|
|
3404
3340
|
.profile-popup-stat {
|
|
3405
3341
|
font-size: 11px;
|
|
3406
|
-
color: var(--text-
|
|
3342
|
+
color: var(--text-muted);
|
|
3407
3343
|
background: var(--surface-2);
|
|
3408
3344
|
border-radius: 8px;
|
|
3409
3345
|
padding: 8px 10px;
|
|
@@ -3413,9 +3349,38 @@
|
|
|
3413
3349
|
font-weight: 600;
|
|
3414
3350
|
color: var(--text);
|
|
3415
3351
|
display: block;
|
|
3416
|
-
font-size:
|
|
3417
|
-
margin-bottom:
|
|
3352
|
+
font-size: 15px;
|
|
3353
|
+
margin-bottom: 1px;
|
|
3354
|
+
}
|
|
3355
|
+
|
|
3356
|
+
.pp-quick-actions {
|
|
3357
|
+
display: flex;
|
|
3358
|
+
gap: 6px;
|
|
3359
|
+
padding: 0 16px 12px;
|
|
3360
|
+
border-top: 1px solid var(--border);
|
|
3361
|
+
padding-top: 10px;
|
|
3362
|
+
margin-top: 2px;
|
|
3363
|
+
}
|
|
3364
|
+
.pp-quick-action {
|
|
3365
|
+
flex: 1;
|
|
3366
|
+
display: flex;
|
|
3367
|
+
align-items: center;
|
|
3368
|
+
justify-content: center;
|
|
3369
|
+
gap: 5px;
|
|
3370
|
+
background: var(--surface-2);
|
|
3371
|
+
border: 1px solid var(--border);
|
|
3372
|
+
border-radius: 6px;
|
|
3373
|
+
padding: 7px 0;
|
|
3374
|
+
font-size: 11px;
|
|
3375
|
+
font-weight: 600;
|
|
3376
|
+
font-family: inherit;
|
|
3377
|
+
color: var(--text-dim);
|
|
3378
|
+
cursor: pointer;
|
|
3379
|
+
text-align: center;
|
|
3380
|
+
transition: all 0.15s;
|
|
3418
3381
|
}
|
|
3382
|
+
.pp-quick-action:hover { background: var(--accent-dim); color: var(--accent); border-color: var(--accent); }
|
|
3383
|
+
.pp-quick-action svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 1.8; flex-shrink: 0; }
|
|
3419
3384
|
|
|
3420
3385
|
/* Actions tab */
|
|
3421
3386
|
.pp-actions-grid {
|
|
@@ -4250,7 +4215,7 @@
|
|
|
4250
4215
|
.avatar-option {
|
|
4251
4216
|
width: 44px;
|
|
4252
4217
|
height: 44px;
|
|
4253
|
-
border-radius:
|
|
4218
|
+
border-radius: 10px;
|
|
4254
4219
|
border: 2px solid var(--border);
|
|
4255
4220
|
cursor: pointer;
|
|
4256
4221
|
transition: all 0.15s;
|
|
@@ -4265,7 +4230,7 @@
|
|
|
4265
4230
|
.char-designer {
|
|
4266
4231
|
position: fixed;
|
|
4267
4232
|
top: 0; right: 0; bottom: 0;
|
|
4268
|
-
width:
|
|
4233
|
+
width: 380px;
|
|
4269
4234
|
max-width: 100vw;
|
|
4270
4235
|
background: var(--surface);
|
|
4271
4236
|
border-left: 1px solid var(--border);
|
|
@@ -4305,28 +4270,13 @@
|
|
|
4305
4270
|
flex: 1; overflow-y: auto; padding: 0;
|
|
4306
4271
|
}
|
|
4307
4272
|
|
|
4308
|
-
.cd-preview {
|
|
4309
|
-
width: 100%;
|
|
4310
|
-
height: 250px;
|
|
4311
|
-
background: #12151c;
|
|
4312
|
-
position: relative;
|
|
4313
|
-
border-bottom: 1px solid var(--border);
|
|
4314
|
-
cursor: grab;
|
|
4315
|
-
}
|
|
4316
|
-
.cd-preview:active { cursor: grabbing; }
|
|
4317
|
-
.cd-preview canvas { display: block; width: 100% !important; height: 100% !important; }
|
|
4318
|
-
|
|
4319
4273
|
.cd-info-section {
|
|
4320
4274
|
padding: 14px 18px;
|
|
4321
|
-
display: flex; flex-direction: column; gap:
|
|
4275
|
+
display: flex; flex-direction: column; gap: 10px;
|
|
4322
4276
|
border-bottom: 1px solid var(--border);
|
|
4323
4277
|
}
|
|
4324
|
-
.cd-info-section .cd-avatar-row {
|
|
4325
|
-
display: flex; align-items: center; gap: 10px; margin-bottom: 4px;
|
|
4326
|
-
}
|
|
4327
|
-
.cd-info-section .cd-avatar-row .avatar-option { width: 36px; height: 36px; }
|
|
4328
4278
|
.cd-avatar-grid {
|
|
4329
|
-
display: grid; grid-template-columns: repeat(6, 1fr); gap:
|
|
4279
|
+
display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; margin-bottom: 2px;
|
|
4330
4280
|
}
|
|
4331
4281
|
.cd-avatar-upload-row {
|
|
4332
4282
|
display: flex; gap: 6px; align-items: center;
|
|
@@ -4353,82 +4303,6 @@
|
|
|
4353
4303
|
border-color: var(--accent);
|
|
4354
4304
|
}
|
|
4355
4305
|
|
|
4356
|
-
.cd-tabs {
|
|
4357
|
-
display: flex;
|
|
4358
|
-
padding: 0 18px;
|
|
4359
|
-
border-bottom: 1px solid var(--border);
|
|
4360
|
-
gap: 0;
|
|
4361
|
-
flex-shrink: 0;
|
|
4362
|
-
overflow-x: auto;
|
|
4363
|
-
}
|
|
4364
|
-
.cd-tab {
|
|
4365
|
-
background: none; border: none; border-bottom: 2px solid transparent;
|
|
4366
|
-
color: var(--text-dim); padding: 10px 12px; font-size: 12px; font-weight: 600;
|
|
4367
|
-
cursor: pointer; transition: all 0.15s; white-space: nowrap;
|
|
4368
|
-
font-family: inherit;
|
|
4369
|
-
}
|
|
4370
|
-
.cd-tab:hover { color: var(--text); background: var(--surface-2); }
|
|
4371
|
-
.cd-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
|
|
4372
|
-
|
|
4373
|
-
.cd-tab-content {
|
|
4374
|
-
padding: 14px 18px;
|
|
4375
|
-
display: none;
|
|
4376
|
-
flex-direction: column;
|
|
4377
|
-
gap: 14px;
|
|
4378
|
-
}
|
|
4379
|
-
.cd-tab-content.active { display: flex; }
|
|
4380
|
-
|
|
4381
|
-
.cd-subsection-label {
|
|
4382
|
-
font-size: 10px; color: var(--text-muted);
|
|
4383
|
-
text-transform: uppercase; letter-spacing: 0.5px;
|
|
4384
|
-
margin-bottom: 2px;
|
|
4385
|
-
}
|
|
4386
|
-
|
|
4387
|
-
.cd-item-grid {
|
|
4388
|
-
display: grid;
|
|
4389
|
-
grid-template-columns: repeat(3, 1fr);
|
|
4390
|
-
gap: 6px;
|
|
4391
|
-
}
|
|
4392
|
-
|
|
4393
|
-
.cd-item-card {
|
|
4394
|
-
display: flex; flex-direction: column;
|
|
4395
|
-
align-items: center; justify-content: center;
|
|
4396
|
-
gap: 4px;
|
|
4397
|
-
background: var(--surface-2);
|
|
4398
|
-
border: 2px solid var(--border);
|
|
4399
|
-
border-radius: 8px;
|
|
4400
|
-
padding: 10px 6px;
|
|
4401
|
-
cursor: pointer;
|
|
4402
|
-
transition: all 0.15s;
|
|
4403
|
-
font-size: 11px; color: var(--text-dim);
|
|
4404
|
-
text-align: center;
|
|
4405
|
-
min-height: 56px;
|
|
4406
|
-
}
|
|
4407
|
-
.cd-item-card:hover { border-color: var(--border-light); color: var(--text); background: var(--surface-3); }
|
|
4408
|
-
.cd-item-card.active {
|
|
4409
|
-
border-color: var(--accent);
|
|
4410
|
-
background: var(--accent-dim);
|
|
4411
|
-
color: var(--text);
|
|
4412
|
-
box-shadow: 0 0 0 1px var(--accent-glow);
|
|
4413
|
-
}
|
|
4414
|
-
.cd-item-card .cd-card-icon { font-size: 18px; line-height: 1; }
|
|
4415
|
-
.cd-item-card .cd-card-label { font-size: 10px; font-weight: 500; }
|
|
4416
|
-
|
|
4417
|
-
.cd-color-row {
|
|
4418
|
-
display: flex; align-items: center; gap: 10px;
|
|
4419
|
-
}
|
|
4420
|
-
.cd-color-row label {
|
|
4421
|
-
font-size: 11px; color: var(--text-dim); min-width: 70px;
|
|
4422
|
-
}
|
|
4423
|
-
.cd-color-row input[type="color"] {
|
|
4424
|
-
width: 40px; height: 28px; border: 1px solid var(--border);
|
|
4425
|
-
border-radius: 6px; background: var(--surface-2);
|
|
4426
|
-
cursor: pointer; padding: 2px;
|
|
4427
|
-
}
|
|
4428
|
-
.cd-color-row .cd-color-hex {
|
|
4429
|
-
font-size: 11px; color: var(--text-muted); font-family: monospace;
|
|
4430
|
-
}
|
|
4431
|
-
|
|
4432
4306
|
.cd-footer {
|
|
4433
4307
|
display: flex; gap: 10px; padding: 14px 18px;
|
|
4434
4308
|
border-top: 1px solid var(--border);
|
|
@@ -4533,7 +4407,7 @@
|
|
|
4533
4407
|
<span class="nav-icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="2" y="2" width="12" height="12" rx="2"/><path d="M5 8l2 2 4-4"/></svg></span><span class="nav-text">Tasks</span>
|
|
4534
4408
|
</div>
|
|
4535
4409
|
<div class="nav-item" data-view="workflows" onclick="switchView('workflows')">
|
|
4536
|
-
<span class="nav-icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5"><
|
|
4410
|
+
<span class="nav-icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="3" cy="8" r="1.5"/><circle cx="13" cy="4" r="1.5"/><circle cx="13" cy="12" r="1.5"/><path d="M4.5 7.2L11.5 4.5M4.5 8.8L11.5 11.5"/></svg></span><span class="nav-text">Workflows</span>
|
|
4537
4411
|
</div>
|
|
4538
4412
|
<div class="nav-item" data-view="stats" onclick="switchView('stats')">
|
|
4539
4413
|
<span class="nav-icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M3 14V8M8 14V3M13 14V6"/></svg></span><span class="nav-text">Analytics</span>
|
|
@@ -4548,9 +4422,8 @@
|
|
|
4548
4422
|
<div class="nav-sidebar-label">AGENTS</div>
|
|
4549
4423
|
<div id="agents-list"></div>
|
|
4550
4424
|
</div>
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
<div class="nav-sidebar-section nav-sidebar-project">
|
|
4425
|
+
<!-- Project (hidden — single-project mode) -->
|
|
4426
|
+
<div class="nav-sidebar-section nav-sidebar-project" style="display:none">
|
|
4554
4427
|
<div class="nav-sidebar-label" style="display:flex;align-items:center;justify-content:space-between;gap:6px">
|
|
4555
4428
|
<span>PROJECT</span>
|
|
4556
4429
|
<span style="display:flex;align-items:center;gap:2px">
|
|
@@ -4620,14 +4493,15 @@
|
|
|
4620
4493
|
<div class="branch-tabs" id="branch-tabs"></div>
|
|
4621
4494
|
<div class="search-bar" id="search-bar">
|
|
4622
4495
|
<input class="search-input" id="search-input" placeholder="Search messages... ( / )" oninput="onSearch()">
|
|
4623
|
-
<button id="search-all-btn" onclick="toggleSearchAll()" title="Search across all projects" style="background:var(--surface-2);border:1px solid var(--border);border-radius:6px;padding:4px 8px;font-size:10px;cursor:pointer;color:var(--text-muted);white-space:nowrap;transition:all 0.2s">All Projects</button>
|
|
4624
|
-
<button id="deep-search-btn" onclick="deepSearch()" title="Search full history (server-side, includes compacted messages and channels)" style="background:var(--surface-2);border:1px solid var(--border);border-radius:6px;padding:4px 8px;font-size:10px;cursor:pointer;color:var(--text-muted);white-space:nowrap;transition:all 0.2s">Deep Search</button>
|
|
4625
4496
|
<span class="search-count" id="search-count"></span>
|
|
4626
4497
|
<button class="compact-toggle" id="compact-toggle" onclick="toggleCompactMode()" title="Toggle compact view">Compact</button>
|
|
4627
4498
|
<select id="conversation-select" onchange="loadConversation()" title="Load saved conversation" style="background:var(--surface-2);border:1px solid var(--border);border-radius:6px;padding:4px 8px;font-size:10px;cursor:pointer;color:var(--text-muted)"><option value="">Current</option></select>
|
|
4628
4499
|
<button onclick="newConversation()" title="Archive current and start fresh" style="background:var(--surface-2);border:1px solid var(--border);border-radius:6px;padding:4px 8px;font-size:10px;cursor:pointer;color:var(--text-muted);white-space:nowrap;transition:all 0.2s">New Conversation</button>
|
|
4629
|
-
<button onclick="
|
|
4500
|
+
<button onclick="scrollToLatest()" title="Scroll to latest message" style="background:var(--surface-2);border:1px solid var(--border);border-radius:6px;padding:4px 8px;font-size:10px;cursor:pointer;color:var(--text-muted);white-space:nowrap;transition:all 0.2s;display:flex;align-items:center;gap:4px"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M8 3v10M4 9l4 4 4-4"/></svg>Latest</button>
|
|
4630
4501
|
</div>
|
|
4502
|
+
<!-- Hidden but preserved for JS compatibility -->
|
|
4503
|
+
<button id="search-all-btn" style="display:none"></button>
|
|
4504
|
+
<button id="deep-search-btn" style="display:none"></button>
|
|
4631
4505
|
<div class="channel-filter-bar" id="channel-filter-bar" style="display:none"></div>
|
|
4632
4506
|
<div class="pinned-section" id="pinned-section">
|
|
4633
4507
|
<div class="pinned-header" onclick="togglePinnedSection()"><span>Pinned Messages</span><span class="pinned-toggle" id="pinned-toggle">Hide</span></div>
|
|
@@ -4682,52 +4556,42 @@
|
|
|
4682
4556
|
<div class="profile-popup-id" id="pp-id"></div>
|
|
4683
4557
|
</div>
|
|
4684
4558
|
</div>
|
|
4685
|
-
|
|
4559
|
+
<!-- Tabs (hidden but kept for JS compat) -->
|
|
4560
|
+
<div class="pp-tabs" style="display:none">
|
|
4686
4561
|
<button class="pp-tab active" data-tab="stats" onclick="switchPpTab('stats')">Stats</button>
|
|
4687
4562
|
<button class="pp-tab" data-tab="actions" onclick="switchPpTab('actions')">Actions</button>
|
|
4688
4563
|
<button class="pp-tab" data-tab="profile" onclick="switchPpTab('profile')">Profile</button>
|
|
4689
|
-
<button class="pp-tab" data-tab="terminal" onclick="switchPpTab('terminal', true)"
|
|
4564
|
+
<button class="pp-tab" data-tab="terminal" onclick="switchPpTab('terminal', true)">Terminal</button>
|
|
4690
4565
|
</div>
|
|
4691
|
-
<!-- Stats
|
|
4566
|
+
<!-- Stats (always visible) -->
|
|
4692
4567
|
<div class="pp-tab-content active" id="pp-tab-stats">
|
|
4693
|
-
<div id="pp-badges" style="display:flex;gap:
|
|
4568
|
+
<div id="pp-badges" style="display:flex;gap:4px;flex-wrap:wrap;margin-bottom:8px"></div>
|
|
4694
4569
|
<div class="profile-popup-stats" id="pp-stats"></div>
|
|
4695
|
-
<div id="pp-skills-readonly" style="margin-top:
|
|
4696
|
-
</div>
|
|
4697
|
-
<!-- Actions Tab -->
|
|
4698
|
-
<div class="pp-tab-content" id="pp-tab-actions">
|
|
4699
|
-
<div class="pp-actions-grid" id="pp-actions"></div>
|
|
4570
|
+
<div id="pp-skills-readonly" style="margin-top:10px"></div>
|
|
4700
4571
|
</div>
|
|
4701
|
-
<!--
|
|
4702
|
-
<div class="pp-
|
|
4572
|
+
<!-- Quick actions row -->
|
|
4573
|
+
<div class="pp-quick-actions" id="pp-quick-actions"></div>
|
|
4574
|
+
<!-- Hidden tabs for JS compat -->
|
|
4575
|
+
<div class="pp-tab-content" id="pp-tab-actions" style="display:none"><div class="pp-actions-grid" id="pp-actions"></div></div>
|
|
4576
|
+
<div class="pp-tab-content" id="pp-tab-profile" style="display:none">
|
|
4703
4577
|
<div class="profile-popup-bio" id="pp-bio"></div>
|
|
4704
|
-
<div id="pp-skills-container"
|
|
4705
|
-
<button class="btn btn-
|
|
4706
|
-
<button class="btn btn-danger" style="width:100%;margin-top:6px" id="pp-delete-btn" onclick="confirmDeleteAgent()">Delete Agent</button>
|
|
4578
|
+
<div id="pp-skills-container"></div>
|
|
4579
|
+
<button class="btn btn-danger" style="display:none" id="pp-delete-btn" onclick="confirmDeleteAgent()">Delete Agent</button>
|
|
4707
4580
|
</div>
|
|
4708
|
-
<!-- Terminal Tab -->
|
|
4709
4581
|
<div class="pp-tab-content" id="pp-tab-terminal" style="display:none">
|
|
4710
|
-
<div
|
|
4711
|
-
<
|
|
4712
|
-
<div id="pp-terminal-container"></div>
|
|
4713
|
-
</div>
|
|
4714
|
-
<div style="font-size:10px;color:var(--text-muted);margin-top:8px;display:flex;justify-content:space-between">
|
|
4715
|
-
<span>Real-time agent stream</span>
|
|
4716
|
-
<span id="terminal-status">Ready</span>
|
|
4717
|
-
</div>
|
|
4582
|
+
<div class="terminal-wrapper"><div id="pp-terminal-container"></div></div>
|
|
4583
|
+
<span id="terminal-status" style="display:none">Ready</span>
|
|
4718
4584
|
</div>
|
|
4719
4585
|
</div>
|
|
4720
4586
|
|
|
4721
|
-
<!-- Character Designer
|
|
4587
|
+
<!-- Profile Editor Panel (replaces Character Designer) -->
|
|
4722
4588
|
<div class="char-designer-backdrop" id="cd-backdrop" onclick="closeProfileEditor()"></div>
|
|
4723
4589
|
<div class="char-designer" id="char-designer">
|
|
4724
4590
|
<div class="cd-header">
|
|
4725
|
-
<h3>
|
|
4591
|
+
<h3>Edit Profile</h3>
|
|
4726
4592
|
<button class="cd-close" onclick="closeProfileEditor()">×</button>
|
|
4727
4593
|
</div>
|
|
4728
4594
|
<div class="cd-body">
|
|
4729
|
-
|
|
4730
|
-
<!-- Info Section: Avatar + Name/Role/Bio -->
|
|
4731
4595
|
<div class="cd-info-section">
|
|
4732
4596
|
<div class="cd-field">
|
|
4733
4597
|
<label>Avatar</label>
|
|
@@ -4744,349 +4608,52 @@
|
|
|
4744
4608
|
<label>Display Name</label>
|
|
4745
4609
|
<input type="text" id="pe-display-name" maxlength="30">
|
|
4746
4610
|
</div>
|
|
4747
|
-
<div style="display:flex;gap:8px">
|
|
4748
|
-
<div class="cd-field" style="flex:1">
|
|
4749
|
-
<label>Role</label>
|
|
4750
|
-
<input type="text" id="pe-role" maxlength="30" placeholder="e.g. Architect, Coder">
|
|
4751
|
-
</div>
|
|
4752
|
-
</div>
|
|
4753
4611
|
<div class="cd-field">
|
|
4754
|
-
<label>
|
|
4755
|
-
<
|
|
4612
|
+
<label>Role</label>
|
|
4613
|
+
<input type="text" id="pe-role" maxlength="30" placeholder="e.g. Architect, Coder">
|
|
4756
4614
|
</div>
|
|
4615
|
+
<textarea id="pe-bio" style="display:none"></textarea>
|
|
4757
4616
|
</div>
|
|
4758
4617
|
|
|
4759
|
-
<!--
|
|
4760
|
-
<div class="cd-
|
|
4761
|
-
<
|
|
4762
|
-
<
|
|
4763
|
-
<button class="cd-tab" onclick="cdSwitchTab('face', this)">Face</button>
|
|
4764
|
-
<button class="cd-tab" onclick="cdSwitchTab('outfit', this)">Outfit</button>
|
|
4765
|
-
<button class="cd-tab" onclick="cdSwitchTab('accessories', this)">Acc.</button>
|
|
4766
|
-
<button class="cd-tab" onclick="cdSwitchTab('stats', this)">Stats</button>
|
|
4618
|
+
<!-- Stats -->
|
|
4619
|
+
<div class="cd-info-section" style="border-bottom:none">
|
|
4620
|
+
<div style="font-size:10px;text-transform:uppercase;letter-spacing:0.5px;color:var(--text-muted)">Stats</div>
|
|
4621
|
+
<div id="pe-stats-container" style="display:grid;grid-template-columns:1fr 1fr;gap:6px;font-size:12px;color:var(--text)"></div>
|
|
4767
4622
|
</div>
|
|
4768
4623
|
|
|
4769
|
-
<!--
|
|
4770
|
-
<div class="cd-
|
|
4771
|
-
<
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
<!-- Tab: Body -->
|
|
4775
|
-
<div class="cd-tab-content active" id="cd-tab-body">
|
|
4776
|
-
<div class="cd-color-row">
|
|
4777
|
-
<label>Skin color</label>
|
|
4778
|
-
<input type="color" id="pe-head-color" value="#FFD5B8" onchange="cdOnChange()">
|
|
4779
|
-
<span class="cd-color-hex" id="cd-skin-hex">#FFD5B8</span>
|
|
4780
|
-
</div>
|
|
4781
|
-
<div>
|
|
4782
|
-
<div class="cd-subsection-label">Body Type</div>
|
|
4783
|
-
<div class="cd-item-grid" id="cd-body-types">
|
|
4784
|
-
<div class="cd-item-card" data-value="default" onclick="cdPickBodyType(this)">
|
|
4785
|
-
<span class="cd-card-icon">🧍</span>
|
|
4786
|
-
<span class="cd-card-label">Default</span>
|
|
4787
|
-
</div>
|
|
4788
|
-
<div class="cd-item-card" data-value="stocky" onclick="cdPickBodyType(this)">
|
|
4789
|
-
<span class="cd-card-icon">💪</span>
|
|
4790
|
-
<span class="cd-card-label">Stocky</span>
|
|
4791
|
-
</div>
|
|
4792
|
-
<div class="cd-item-card" data-value="slim" onclick="cdPickBodyType(this)">
|
|
4793
|
-
<span class="cd-card-icon">💃</span>
|
|
4794
|
-
<span class="cd-card-label">Slim</span>
|
|
4795
|
-
</div>
|
|
4796
|
-
</div>
|
|
4797
|
-
</div>
|
|
4624
|
+
<!-- Hidden tab elements for JS compat -->
|
|
4625
|
+
<div class="cd-tabs" style="display:none">
|
|
4626
|
+
<button class="cd-tab" onclick="cdSwitchTab('body', this)">Body</button>
|
|
4627
|
+
<button class="cd-tab" onclick="cdSwitchTab('stats', this)">Stats</button>
|
|
4798
4628
|
</div>
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
<
|
|
4803
|
-
<div class="cd-subsection-label">Style</div>
|
|
4804
|
-
<div class="cd-item-grid" id="cd-hair-styles">
|
|
4805
|
-
<div class="cd-item-card" data-value="none" onclick="cdPickHairStyle(this)">
|
|
4806
|
-
<span class="cd-card-icon">🚫</span>
|
|
4807
|
-
<span class="cd-card-label">None</span>
|
|
4808
|
-
</div>
|
|
4809
|
-
<div class="cd-item-card" data-value="short" onclick="cdPickHairStyle(this)">
|
|
4810
|
-
<span class="cd-card-icon">✂</span>
|
|
4811
|
-
<span class="cd-card-label">Short</span>
|
|
4812
|
-
</div>
|
|
4813
|
-
<div class="cd-item-card" data-value="spiky" onclick="cdPickHairStyle(this)">
|
|
4814
|
-
<span class="cd-card-icon">⚡</span>
|
|
4815
|
-
<span class="cd-card-label">Spiky</span>
|
|
4816
|
-
</div>
|
|
4817
|
-
<div class="cd-item-card" data-value="long" onclick="cdPickHairStyle(this)">
|
|
4818
|
-
<span class="cd-card-icon">🧑</span>
|
|
4819
|
-
<span class="cd-card-label">Long</span>
|
|
4820
|
-
</div>
|
|
4821
|
-
<div class="cd-item-card" data-value="ponytail" onclick="cdPickHairStyle(this)">
|
|
4822
|
-
<span class="cd-card-icon">🏃</span>
|
|
4823
|
-
<span class="cd-card-label">Ponytail</span>
|
|
4824
|
-
</div>
|
|
4825
|
-
<div class="cd-item-card" data-value="bob" onclick="cdPickHairStyle(this)">
|
|
4826
|
-
<span class="cd-card-icon">💇</span>
|
|
4827
|
-
<span class="cd-card-label">Bob</span>
|
|
4828
|
-
</div>
|
|
4829
|
-
<div class="cd-item-card" data-value="curly" onclick="cdPickHairStyle(this)">
|
|
4830
|
-
<span class="cd-card-icon">➰</span>
|
|
4831
|
-
<span class="cd-card-label">Curly</span>
|
|
4832
|
-
</div>
|
|
4833
|
-
<div class="cd-item-card" data-value="afro" onclick="cdPickHairStyle(this)">
|
|
4834
|
-
<span class="cd-card-icon">⭕</span>
|
|
4835
|
-
<span class="cd-card-label">Afro</span>
|
|
4836
|
-
</div>
|
|
4837
|
-
<div class="cd-item-card" data-value="bun" onclick="cdPickHairStyle(this)">
|
|
4838
|
-
<span class="cd-card-icon">🍡</span>
|
|
4839
|
-
<span class="cd-card-label">Bun</span>
|
|
4840
|
-
</div>
|
|
4841
|
-
<div class="cd-item-card" data-value="braids" onclick="cdPickHairStyle(this)">
|
|
4842
|
-
<span class="cd-card-icon">🎀</span>
|
|
4843
|
-
<span class="cd-card-label">Braids</span>
|
|
4844
|
-
</div>
|
|
4845
|
-
<div class="cd-item-card" data-value="mohawk" onclick="cdPickHairStyle(this)">
|
|
4846
|
-
<span class="cd-card-icon">🔥</span>
|
|
4847
|
-
<span class="cd-card-label">Mohawk</span>
|
|
4848
|
-
</div>
|
|
4849
|
-
<div class="cd-item-card" data-value="wavy" onclick="cdPickHairStyle(this)">
|
|
4850
|
-
<span class="cd-card-icon">🌊</span>
|
|
4851
|
-
<span class="cd-card-label">Wavy</span>
|
|
4852
|
-
</div>
|
|
4853
|
-
</div>
|
|
4854
|
-
</div>
|
|
4855
|
-
<div class="cd-color-row">
|
|
4856
|
-
<label>Hair color</label>
|
|
4857
|
-
<input type="color" id="pe-hair-color" value="#4A3728" onchange="cdOnChange()">
|
|
4858
|
-
<span class="cd-color-hex" id="cd-hair-hex">#4A3728</span>
|
|
4859
|
-
</div>
|
|
4629
|
+
<div class="cd-tab-content" id="cd-tab-stats" style="display:none"></div>
|
|
4630
|
+
<div class="cd-tab-content" id="cd-tab-body" style="display:none">
|
|
4631
|
+
<input type="color" id="pe-head-color" value="#FFD5B8" style="display:none">
|
|
4632
|
+
<span id="cd-skin-hex" style="display:none"></span>
|
|
4860
4633
|
</div>
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
<div>
|
|
4865
|
-
<div class="cd-subsection-label">Eyes</div>
|
|
4866
|
-
<div class="cd-item-grid" id="cd-eye-styles">
|
|
4867
|
-
<div class="cd-item-card" data-value="dots" onclick="cdPickEyeStyle(this)">
|
|
4868
|
-
<span class="cd-card-icon">👁</span>
|
|
4869
|
-
<span class="cd-card-label">Dots</span>
|
|
4870
|
-
</div>
|
|
4871
|
-
<div class="cd-item-card" data-value="anime" onclick="cdPickEyeStyle(this)">
|
|
4872
|
-
<span class="cd-card-icon">✨</span>
|
|
4873
|
-
<span class="cd-card-label">Anime</span>
|
|
4874
|
-
</div>
|
|
4875
|
-
<div class="cd-item-card" data-value="glasses" onclick="cdPickEyeStyle(this)">
|
|
4876
|
-
<span class="cd-card-icon">👓</span>
|
|
4877
|
-
<span class="cd-card-label">Glasses</span>
|
|
4878
|
-
</div>
|
|
4879
|
-
<div class="cd-item-card" data-value="sleepy" onclick="cdPickEyeStyle(this)">
|
|
4880
|
-
<span class="cd-card-icon">😴</span>
|
|
4881
|
-
<span class="cd-card-label">Sleepy</span>
|
|
4882
|
-
</div>
|
|
4883
|
-
<div class="cd-item-card" data-value="surprised" onclick="cdPickEyeStyle(this)">
|
|
4884
|
-
<span class="cd-card-icon">😲</span>
|
|
4885
|
-
<span class="cd-card-label">Surprised</span>
|
|
4886
|
-
</div>
|
|
4887
|
-
<div class="cd-item-card" data-value="angry" onclick="cdPickEyeStyle(this)">
|
|
4888
|
-
<span class="cd-card-icon">😠</span>
|
|
4889
|
-
<span class="cd-card-label">Angry</span>
|
|
4890
|
-
</div>
|
|
4891
|
-
<div class="cd-item-card" data-value="happy" onclick="cdPickEyeStyle(this)">
|
|
4892
|
-
<span class="cd-card-icon">😄</span>
|
|
4893
|
-
<span class="cd-card-label">Happy</span>
|
|
4894
|
-
</div>
|
|
4895
|
-
<div class="cd-item-card" data-value="wink" onclick="cdPickEyeStyle(this)">
|
|
4896
|
-
<span class="cd-card-icon">😉</span>
|
|
4897
|
-
<span class="cd-card-label">Wink</span>
|
|
4898
|
-
</div>
|
|
4899
|
-
<div class="cd-item-card" data-value="confident" onclick="cdPickEyeStyle(this)">
|
|
4900
|
-
<span class="cd-card-icon">😎</span>
|
|
4901
|
-
<span class="cd-card-label">Confident</span>
|
|
4902
|
-
</div>
|
|
4903
|
-
<div class="cd-item-card" data-value="tired" onclick="cdPickEyeStyle(this)">
|
|
4904
|
-
<span class="cd-card-icon">😫</span>
|
|
4905
|
-
<span class="cd-card-label">Tired</span>
|
|
4906
|
-
</div>
|
|
4907
|
-
</div>
|
|
4908
|
-
</div>
|
|
4909
|
-
<div>
|
|
4910
|
-
<div class="cd-subsection-label">Mouth</div>
|
|
4911
|
-
<div class="cd-item-grid" id="cd-mouth-styles">
|
|
4912
|
-
<div class="cd-item-card" data-value="smile" onclick="cdPickMouthStyle(this)">
|
|
4913
|
-
<span class="cd-card-icon">🙂</span>
|
|
4914
|
-
<span class="cd-card-label">Smile</span>
|
|
4915
|
-
</div>
|
|
4916
|
-
<div class="cd-item-card" data-value="neutral" onclick="cdPickMouthStyle(this)">
|
|
4917
|
-
<span class="cd-card-icon">😐</span>
|
|
4918
|
-
<span class="cd-card-label">Neutral</span>
|
|
4919
|
-
</div>
|
|
4920
|
-
<div class="cd-item-card" data-value="open" onclick="cdPickMouthStyle(this)">
|
|
4921
|
-
<span class="cd-card-icon">😮</span>
|
|
4922
|
-
<span class="cd-card-label">Open</span>
|
|
4923
|
-
</div>
|
|
4924
|
-
<div class="cd-item-card" data-value="grin" onclick="cdPickMouthStyle(this)">
|
|
4925
|
-
<span class="cd-card-icon">😁</span>
|
|
4926
|
-
<span class="cd-card-label">Grin</span>
|
|
4927
|
-
</div>
|
|
4928
|
-
<div class="cd-item-card" data-value="frown" onclick="cdPickMouthStyle(this)">
|
|
4929
|
-
<span class="cd-card-icon">☹</span>
|
|
4930
|
-
<span class="cd-card-label">Frown</span>
|
|
4931
|
-
</div>
|
|
4932
|
-
<div class="cd-item-card" data-value="smirk" onclick="cdPickMouthStyle(this)">
|
|
4933
|
-
<span class="cd-card-icon">😏</span>
|
|
4934
|
-
<span class="cd-card-label">Smirk</span>
|
|
4935
|
-
</div>
|
|
4936
|
-
<div class="cd-item-card" data-value="tongue" onclick="cdPickMouthStyle(this)">
|
|
4937
|
-
<span class="cd-card-icon">😛</span>
|
|
4938
|
-
<span class="cd-card-label">Tongue</span>
|
|
4939
|
-
</div>
|
|
4940
|
-
<div class="cd-item-card" data-value="whistle" onclick="cdPickMouthStyle(this)">
|
|
4941
|
-
<span class="cd-card-icon">😗</span>
|
|
4942
|
-
<span class="cd-card-label">Whistle</span>
|
|
4943
|
-
</div>
|
|
4944
|
-
</div>
|
|
4945
|
-
</div>
|
|
4634
|
+
<div class="cd-tab-content" id="cd-tab-hair" style="display:none">
|
|
4635
|
+
<input type="color" id="pe-hair-color" value="#4A3728" style="display:none">
|
|
4636
|
+
<span id="cd-hair-hex" style="display:none"></span>
|
|
4946
4637
|
</div>
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
<
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
<span class="cd-card-label">None</span>
|
|
4956
|
-
</div>
|
|
4957
|
-
<div class="cd-item-card" data-value="hoodie" onclick="cdPickOutfit(this)">
|
|
4958
|
-
<span class="cd-card-icon">🧥</span>
|
|
4959
|
-
<span class="cd-card-label">Hoodie</span>
|
|
4960
|
-
</div>
|
|
4961
|
-
<div class="cd-item-card" data-value="suit" onclick="cdPickOutfit(this)">
|
|
4962
|
-
<span class="cd-card-icon">👔</span>
|
|
4963
|
-
<span class="cd-card-label">Suit</span>
|
|
4964
|
-
</div>
|
|
4965
|
-
<div class="cd-item-card" data-value="dress" onclick="cdPickOutfit(this)">
|
|
4966
|
-
<span class="cd-card-icon">👗</span>
|
|
4967
|
-
<span class="cd-card-label">Dress</span>
|
|
4968
|
-
</div>
|
|
4969
|
-
<div class="cd-item-card" data-value="labcoat" onclick="cdPickOutfit(this)">
|
|
4970
|
-
<span class="cd-card-icon">🧪</span>
|
|
4971
|
-
<span class="cd-card-label">Lab Coat</span>
|
|
4972
|
-
</div>
|
|
4973
|
-
<div class="cd-item-card" data-value="vest" onclick="cdPickOutfit(this)">
|
|
4974
|
-
<span class="cd-card-icon">🎽</span>
|
|
4975
|
-
<span class="cd-card-label">Vest</span>
|
|
4976
|
-
</div>
|
|
4977
|
-
<div class="cd-item-card" data-value="jacket" onclick="cdPickOutfit(this)">
|
|
4978
|
-
<span class="cd-card-icon">🧥</span>
|
|
4979
|
-
<span class="cd-card-label">Jacket</span>
|
|
4980
|
-
</div>
|
|
4981
|
-
</div>
|
|
4982
|
-
</div>
|
|
4983
|
-
<div class="cd-color-row">
|
|
4984
|
-
<label>Shirt color</label>
|
|
4985
|
-
<input type="color" id="pe-shirt-color" value="#f59e0b" onchange="cdOnChange()">
|
|
4986
|
-
<span class="cd-color-hex" id="cd-shirt-hex">#f59e0b</span>
|
|
4987
|
-
</div>
|
|
4988
|
-
<div class="cd-color-row">
|
|
4989
|
-
<label>Pants color</label>
|
|
4990
|
-
<input type="color" id="pe-pants-color" value="#2d3748" onchange="cdOnChange()">
|
|
4991
|
-
<span class="cd-color-hex" id="cd-pants-hex">#2d3748</span>
|
|
4992
|
-
</div>
|
|
4993
|
-
<div class="cd-color-row">
|
|
4994
|
-
<label>Shoe color</label>
|
|
4995
|
-
<input type="color" id="pe-shoe-color" value="#1a1a2e" onchange="cdOnChange()">
|
|
4996
|
-
<span class="cd-color-hex" id="cd-shoe-hex">#1a1a2e</span>
|
|
4997
|
-
</div>
|
|
4638
|
+
<div class="cd-tab-content" id="cd-tab-face" style="display:none"></div>
|
|
4639
|
+
<div class="cd-tab-content" id="cd-tab-outfit" style="display:none">
|
|
4640
|
+
<input type="color" id="pe-shirt-color" value="#f59e0b" style="display:none">
|
|
4641
|
+
<span id="cd-shirt-hex" style="display:none"></span>
|
|
4642
|
+
<input type="color" id="pe-pants-color" value="#2d3748" style="display:none">
|
|
4643
|
+
<span id="cd-pants-hex" style="display:none"></span>
|
|
4644
|
+
<input type="color" id="pe-shoe-color" value="#1a1a2e" style="display:none">
|
|
4645
|
+
<span id="cd-shoe-hex" style="display:none"></span>
|
|
4998
4646
|
</div>
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
<div>
|
|
5003
|
-
<div class="cd-subsection-label">Glasses</div>
|
|
5004
|
-
<div class="cd-item-grid" id="cd-glasses-styles">
|
|
5005
|
-
<div class="cd-item-card" data-value="" onclick="cdPickGlasses(this)">
|
|
5006
|
-
<span class="cd-card-icon">🚫</span>
|
|
5007
|
-
<span class="cd-card-label">None</span>
|
|
5008
|
-
</div>
|
|
5009
|
-
<div class="cd-item-card" data-value="round" onclick="cdPickGlasses(this)">
|
|
5010
|
-
<span class="cd-card-icon">💠</span>
|
|
5011
|
-
<span class="cd-card-label">Round</span>
|
|
5012
|
-
</div>
|
|
5013
|
-
<div class="cd-item-card" data-value="square" onclick="cdPickGlasses(this)">
|
|
5014
|
-
<span class="cd-card-icon">◻</span>
|
|
5015
|
-
<span class="cd-card-label">Square</span>
|
|
5016
|
-
</div>
|
|
5017
|
-
<div class="cd-item-card" data-value="sunglasses" onclick="cdPickGlasses(this)">
|
|
5018
|
-
<span class="cd-card-icon">🕶</span>
|
|
5019
|
-
<span class="cd-card-label">Sunglasses</span>
|
|
5020
|
-
</div>
|
|
5021
|
-
</div>
|
|
5022
|
-
<div class="cd-color-row" id="cd-glasses-color-row" style="margin-top:8px;display:none">
|
|
5023
|
-
<label>Frame color</label>
|
|
5024
|
-
<input type="color" id="pe-glasses-color" value="#555555" onchange="cdOnChange()">
|
|
5025
|
-
<span class="cd-color-hex" id="cd-glasses-hex">#555555</span>
|
|
5026
|
-
</div>
|
|
5027
|
-
</div>
|
|
5028
|
-
<div>
|
|
5029
|
-
<div class="cd-subsection-label">Headwear</div>
|
|
5030
|
-
<div class="cd-item-grid" id="cd-headwear-styles">
|
|
5031
|
-
<div class="cd-item-card" data-value="" onclick="cdPickHeadwear(this)">
|
|
5032
|
-
<span class="cd-card-icon">🚫</span>
|
|
5033
|
-
<span class="cd-card-label">None</span>
|
|
5034
|
-
</div>
|
|
5035
|
-
<div class="cd-item-card" data-value="beanie" onclick="cdPickHeadwear(this)">
|
|
5036
|
-
<span class="cd-card-icon">🧢</span>
|
|
5037
|
-
<span class="cd-card-label">Beanie</span>
|
|
5038
|
-
</div>
|
|
5039
|
-
<div class="cd-item-card" data-value="cap" onclick="cdPickHeadwear(this)">
|
|
5040
|
-
<span class="cd-card-icon">🧢</span>
|
|
5041
|
-
<span class="cd-card-label">Cap</span>
|
|
5042
|
-
</div>
|
|
5043
|
-
<div class="cd-item-card" data-value="headphones" onclick="cdPickHeadwear(this)">
|
|
5044
|
-
<span class="cd-card-icon">🎧</span>
|
|
5045
|
-
<span class="cd-card-label">Headphones</span>
|
|
5046
|
-
</div>
|
|
5047
|
-
<div class="cd-item-card" data-value="headband" onclick="cdPickHeadwear(this)">
|
|
5048
|
-
<span class="cd-card-icon">🎽</span>
|
|
5049
|
-
<span class="cd-card-label">Headband</span>
|
|
5050
|
-
</div>
|
|
5051
|
-
</div>
|
|
5052
|
-
<div class="cd-color-row" id="cd-headwear-color-row" style="margin-top:8px;display:none">
|
|
5053
|
-
<label>Color</label>
|
|
5054
|
-
<input type="color" id="pe-headwear-color" value="#333333" onchange="cdOnChange()">
|
|
5055
|
-
<span class="cd-color-hex" id="cd-headwear-hex">#333333</span>
|
|
5056
|
-
</div>
|
|
5057
|
-
</div>
|
|
5058
|
-
<div>
|
|
5059
|
-
<div class="cd-subsection-label">Neckwear</div>
|
|
5060
|
-
<div class="cd-item-grid" id="cd-neckwear-styles">
|
|
5061
|
-
<div class="cd-item-card" data-value="" onclick="cdPickNeckwear(this)">
|
|
5062
|
-
<span class="cd-card-icon">🚫</span>
|
|
5063
|
-
<span class="cd-card-label">None</span>
|
|
5064
|
-
</div>
|
|
5065
|
-
<div class="cd-item-card" data-value="tie" onclick="cdPickNeckwear(this)">
|
|
5066
|
-
<span class="cd-card-icon">👔</span>
|
|
5067
|
-
<span class="cd-card-label">Tie</span>
|
|
5068
|
-
</div>
|
|
5069
|
-
<div class="cd-item-card" data-value="bowtie" onclick="cdPickNeckwear(this)">
|
|
5070
|
-
<span class="cd-card-icon">🎀</span>
|
|
5071
|
-
<span class="cd-card-label">Bowtie</span>
|
|
5072
|
-
</div>
|
|
5073
|
-
<div class="cd-item-card" data-value="lanyard" onclick="cdPickNeckwear(this)">
|
|
5074
|
-
<span class="cd-card-icon">📛</span>
|
|
5075
|
-
<span class="cd-card-label">Lanyard</span>
|
|
5076
|
-
</div>
|
|
5077
|
-
</div>
|
|
5078
|
-
<div class="cd-color-row" id="cd-neckwear-color-row" style="margin-top:8px;display:none">
|
|
5079
|
-
<label>Color</label>
|
|
5080
|
-
<input type="color" id="pe-neckwear-color" value="#c0392b" onchange="cdOnChange()">
|
|
5081
|
-
<span class="cd-color-hex" id="cd-neckwear-hex">#c0392b</span>
|
|
5082
|
-
</div>
|
|
5083
|
-
</div>
|
|
4647
|
+
<div class="cd-tab-content" id="cd-tab-accessories" style="display:none">
|
|
4648
|
+
<div id="cd-glasses-color-row" style="display:none"><input type="color" id="pe-glasses-color" value="#555555"><span id="cd-glasses-hex"></span></div>
|
|
4649
|
+
<div id="cd-headwear-color-row" style="display:none"><input type="color" id="pe-headwear-color" value="#333333"><span id="cd-headwear-hex"></span></div>
|
|
4650
|
+
<div id="cd-neckwear-color-row" style="display:none"><input type="color" id="pe-neckwear-color" value="#c0392b"><span id="cd-neckwear-hex"></span></div>
|
|
5084
4651
|
</div>
|
|
5085
4652
|
</div>
|
|
5086
4653
|
|
|
5087
4654
|
<!-- Footer -->
|
|
5088
4655
|
<div class="cd-footer">
|
|
5089
|
-
<button class="btn" onclick="
|
|
4656
|
+
<button class="btn" onclick="closeProfileEditor()">Cancel</button>
|
|
5090
4657
|
<button class="btn btn-primary" onclick="saveProfile()">Save</button>
|
|
5091
4658
|
</div>
|
|
5092
4659
|
</div>
|
|
@@ -5453,6 +5020,14 @@ function renderAgents(agents) {
|
|
|
5453
5020
|
var sleepCount = 0;
|
|
5454
5021
|
var html = '';
|
|
5455
5022
|
|
|
5023
|
+
function getAgentAvatar(name, info) {
|
|
5024
|
+
var av = info.avatar;
|
|
5025
|
+
if (av && av.indexOf("rx='32'") === -1) return av;
|
|
5026
|
+
var hash = 0;
|
|
5027
|
+
for (var c = 0; c < name.length; c++) hash = ((hash << 5) - hash) + name.charCodeAt(c);
|
|
5028
|
+
return BUILT_IN_AVATARS[Math.abs(hash) % BUILT_IN_AVATARS.length];
|
|
5029
|
+
}
|
|
5030
|
+
|
|
5456
5031
|
function renderAgentCards(agentNames) {
|
|
5457
5032
|
var cardHtml = '';
|
|
5458
5033
|
for (var i = 0; i < agentNames.length; i++) {
|
|
@@ -5486,82 +5061,24 @@ function renderAgents(agents) {
|
|
|
5486
5061
|
}
|
|
5487
5062
|
|
|
5488
5063
|
var cardClass = 'agent-card' + (state !== 'working' ? ' ' + state : '');
|
|
5489
|
-
var
|
|
5490
|
-
|
|
5491
|
-
: '<div class="agent-avatar" style="background:' + color + '">' + initial(name) + '</div>';
|
|
5064
|
+
var agentAv = getAgentAvatar(name, info);
|
|
5065
|
+
var avatarHtml = '<img class="agent-avatar-img" src="' + escapeHtml(agentAv) + '" alt="' + escapeHtml(name) + '" onerror="this.outerHTML=\'<div class="agent-avatar" style="background:' + color + '">' + initial(name) + '</div>\'">';
|
|
5492
5066
|
var displayName = info.display_name || name;
|
|
5493
5067
|
|
|
5494
|
-
// Subtitle: role + activity
|
|
5495
5068
|
var subtitleParts = [];
|
|
5496
5069
|
if (info.role) subtitleParts.push(info.role);
|
|
5497
5070
|
if (activityText) subtitleParts.push(activityText);
|
|
5498
5071
|
var subtitleText = subtitleParts.join(' \u00B7 ');
|
|
5499
5072
|
|
|
5500
|
-
// Skills: limited to 3 for sidebar cards
|
|
5501
|
-
var skillsHtml = '';
|
|
5502
|
-
if (info.skills && info.skills.length > 0) {
|
|
5503
|
-
var platformClass = 'platform-' + (info.provider || 'unknown').toLowerCase();
|
|
5504
|
-
var platformSkills = info.platform_skills || [];
|
|
5505
|
-
skillsHtml = '<div class="agent-skills">';
|
|
5506
|
-
for (var s = 0; s < Math.min(info.skills.length, 3); s++) {
|
|
5507
|
-
var skill = info.skills[s];
|
|
5508
|
-
var isPlatform = platformSkills.indexOf(skill) !== -1;
|
|
5509
|
-
skillsHtml += '<span class="skill-tag' + (isPlatform ? ' ' + platformClass : '') + '">' + escapeHtml(skill) + '</span>';
|
|
5510
|
-
}
|
|
5511
|
-
if (info.skills.length > 3) {
|
|
5512
|
-
skillsHtml += '<span class="skill-tag" style="opacity:0.5">+' + (info.skills.length - 3) + '</span>';
|
|
5513
|
-
}
|
|
5514
|
-
skillsHtml += '</div>';
|
|
5515
|
-
}
|
|
5516
|
-
|
|
5517
|
-
// Nudge button (Bell icon)
|
|
5518
|
-
var nudgeBtnHtml = '';
|
|
5519
|
-
if (state !== 'offline' && state !== 'dead' && state !== 'unknown') {
|
|
5520
|
-
nudgeBtnHtml = '<div class="agent-nudge-btn" title="Nudge agent to listen()" onclick="sendNudge(\'' + escapeHtml(name) + '\', event)">' +
|
|
5521
|
-
'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path><path d="M13.73 21a2 2 0 0 1-3.46 0"></path></svg>' +
|
|
5522
|
-
'</div>';
|
|
5523
|
-
}
|
|
5524
|
-
|
|
5525
|
-
// Liveness Sparkline (Heartbeat dots)
|
|
5526
|
-
var sparklineHtml = '';
|
|
5527
|
-
if (state !== 'offline' && state !== 'dead' && state !== 'unknown') {
|
|
5528
|
-
var dots = '';
|
|
5529
|
-
var history = info.listen_history || [];
|
|
5530
|
-
// Fallback: synthesize from last_listen_call if listen_history is missing
|
|
5531
|
-
if (history.length === 0) {
|
|
5532
|
-
var llc = info.last_listen_call || info.last_listened_at;
|
|
5533
|
-
if (llc) {
|
|
5534
|
-
var llcTs = typeof llc === 'string' ? new Date(llc).getTime() : llc;
|
|
5535
|
-
if (llcTs > 0) history = [llcTs];
|
|
5536
|
-
}
|
|
5537
|
-
}
|
|
5538
|
-
for (var d = 0; d < 10; d++) {
|
|
5539
|
-
var dotClass = 'hb-dot';
|
|
5540
|
-
if (d < history.length) {
|
|
5541
|
-
var age = (Date.now() - history[d]) / 1000;
|
|
5542
|
-
if (age < 30) dotClass += ' active';
|
|
5543
|
-
else if (age < 120) dotClass += ' stale';
|
|
5544
|
-
} else {
|
|
5545
|
-
dotClass += ' empty';
|
|
5546
|
-
}
|
|
5547
|
-
dots += '<div class="' + dotClass + '"></div>';
|
|
5548
|
-
}
|
|
5549
|
-
sparklineHtml = '<div class="listen-sparkline"><span class="listen-sparkline-label">Liveness</span>' + dots + '</div>';
|
|
5550
|
-
}
|
|
5551
|
-
|
|
5552
5073
|
var indicatorHtml = (state === 'listening' || state === 'working')
|
|
5553
5074
|
? '<span class="agent-state-pill ' + state + '">' + state + '</span>'
|
|
5554
5075
|
: '<span class="agent-status-dot ' + state + '" title="' + state + '"></span>';
|
|
5555
5076
|
cardHtml += '<div class="' + cardClass + '" data-agent="' + escapeHtml(name) + '" onclick="showProfilePopup(\'' + escapeHtml(name) + '\', event)">' +
|
|
5556
|
-
nudgeBtnHtml +
|
|
5557
5077
|
'<div class="agent-top">' +
|
|
5558
5078
|
avatarHtml +
|
|
5559
5079
|
'<div class="agent-info">' +
|
|
5560
|
-
'<div class="agent-name"
|
|
5080
|
+
'<div class="agent-name">' + escapeHtml(displayName) + '</div>' +
|
|
5561
5081
|
'<div class="agent-subtitle">' + escapeHtml(subtitleText) + '</div>' +
|
|
5562
|
-
currentToolHtml +
|
|
5563
|
-
skillsHtml +
|
|
5564
|
-
sparklineHtml +
|
|
5565
5082
|
'</div>' +
|
|
5566
5083
|
indicatorHtml +
|
|
5567
5084
|
'</div>' +
|
|
@@ -6376,6 +5893,10 @@ function scrollToBottom() {
|
|
|
6376
5893
|
document.getElementById('scroll-bottom').classList.remove('visible');
|
|
6377
5894
|
}
|
|
6378
5895
|
|
|
5896
|
+
function scrollToLatest() {
|
|
5897
|
+
scrollToBottom();
|
|
5898
|
+
}
|
|
5899
|
+
|
|
6379
5900
|
// ==================== COMPACT MODE ====================
|
|
6380
5901
|
|
|
6381
5902
|
var compactMode = localStorage.getItem('compactMode') === 'true';
|
|
@@ -7194,7 +6715,7 @@ function renderTasks() {
|
|
|
7194
6715
|
}
|
|
7195
6716
|
|
|
7196
6717
|
// Data hash to skip unnecessary DOM rebuilds
|
|
7197
|
-
var tasksHash = cachedTasks.map(function(t) { return t.id + ':' + t.status + ':' + (t.assignee || ''); }).join('|');
|
|
6718
|
+
var tasksHash = cachedTasks.map(function(t) { return t.id + ':' + t.status + ':' + (t.assignee || '') + ':' + (t.retry_count || 0); }).join('|');
|
|
7198
6719
|
if (tasksHash === _lastTasksHash) return;
|
|
7199
6720
|
_lastTasksHash = tasksHash;
|
|
7200
6721
|
|
|
@@ -7247,6 +6768,7 @@ function buildTaskCard(t) {
|
|
|
7247
6768
|
'<option value="in_review"' + (t.status === 'in_review' ? ' selected' : '') + '>In Review</option>' +
|
|
7248
6769
|
'<option value="done"' + (t.status === 'done' ? ' selected' : '') + '>Done</option>' +
|
|
7249
6770
|
'<option value="blocked"' + (t.status === 'blocked' ? ' selected' : '') + '>Blocked</option>' +
|
|
6771
|
+
'<option value="blocked_permanent"' + (t.status === 'blocked_permanent' ? ' selected' : '') + '>Needs Intervention</option>' +
|
|
7250
6772
|
'</select>';
|
|
7251
6773
|
|
|
7252
6774
|
var badgesHtml = '';
|
|
@@ -7264,7 +6786,7 @@ function buildTaskCard(t) {
|
|
|
7264
6786
|
? '<div style="font-size:10px;color:var(--red);margin-top:4px;font-style:italic">' + escapeHtml(t.blocked_reason) + '</div>'
|
|
7265
6787
|
: '';
|
|
7266
6788
|
|
|
7267
|
-
return '<div class="task-card" draggable="true" data-task-id="' + t.id + '" ondragstart="onTaskDragStart(event)" ondragend="onTaskDragEnd(event)" onclick="showTaskDetail(\'' + t.id + '\')">' +
|
|
6789
|
+
return '<div class="task-card' + (t.status === 'blocked_permanent' ? ' blocked_permanent' : '') + '" draggable="true" data-task-id="' + t.id + '" ondragstart="onTaskDragStart(event)" ondragend="onTaskDragEnd(event)" onclick="showTaskDetail(\'' + t.id + '\')">' +
|
|
7268
6790
|
'<div class="task-title">' + escapeHtml(t.title || 'Untitled') + (badgesHtml ? ' ' + badgesHtml : '') + '</div>' +
|
|
7269
6791
|
(t.description ? '<div class="task-desc">' + escapeHtml(t.description) + '</div>' : '') +
|
|
7270
6792
|
blockedReasonHtml +
|
|
@@ -7299,7 +6821,14 @@ function showTaskDetail(taskId) {
|
|
|
7299
6821
|
|
|
7300
6822
|
var html = '';
|
|
7301
6823
|
html += '<div style="margin-bottom:16px"><div style="font-size:18px;font-weight:700;color:var(--text);margin-bottom:6px">' + escapeHtml(task.title || 'Untitled') + '</div>';
|
|
7302
|
-
|
|
6824
|
+
var statusLabel = task.status === 'blocked_permanent' ? 'Needs Intervention' : escapeHtml(task.status || 'pending');
|
|
6825
|
+
html += '<span style="font-size:11px;padding:3px 8px;border-radius:6px;font-weight:600;background:' + statusColor + '20;color:' + statusColor + '">' + statusLabel + '</span>';
|
|
6826
|
+
if (task.retry_count > 0) html += ' <span style="font-size:10px;padding:2px 6px;border-radius:6px;font-weight:600;background:var(--yellow)20;color:var(--yellow)" title="Reclaimed ' + task.retry_count + ' time(s) by watchdog">↺' + task.retry_count + '</span>';
|
|
6827
|
+
html += '</div>';
|
|
6828
|
+
|
|
6829
|
+
if (task.status === 'blocked_permanent' && task.blocked_reason) {
|
|
6830
|
+
html += '<div style="font-size:12px;color:var(--red);padding:8px 12px;background:var(--red-dim);border-radius:8px;margin-bottom:16px;border-left:3px solid var(--red)">' + escapeHtml(task.blocked_reason) + '</div>';
|
|
6831
|
+
}
|
|
7303
6832
|
|
|
7304
6833
|
if (task.description) {
|
|
7305
6834
|
html += '<div style="font-size:13px;color:var(--text-dim);line-height:1.6;margin-bottom:16px;padding:12px;background:var(--surface-2);border-radius:8px">' + escapeHtml(task.description) + '</div>';
|
|
@@ -7909,12 +7438,18 @@ textarea.addEventListener('input', function() {
|
|
|
7909
7438
|
|
|
7910
7439
|
// ==================== v3.0: MESSAGE AVATAR HELPER ====================
|
|
7911
7440
|
|
|
7912
|
-
function
|
|
7441
|
+
function getMsgAvatarUrl(name) {
|
|
7913
7442
|
var agent = cachedAgents[name];
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7443
|
+
var av = agent && agent.avatar;
|
|
7444
|
+
if (av && av.indexOf("rx='32'") === -1) return av;
|
|
7445
|
+
var hash = 0;
|
|
7446
|
+
for (var c = 0; c < name.length; c++) hash = ((hash << 5) - hash) + name.charCodeAt(c);
|
|
7447
|
+
return BUILT_IN_AVATARS[Math.abs(hash) % BUILT_IN_AVATARS.length];
|
|
7448
|
+
}
|
|
7449
|
+
|
|
7450
|
+
function getMsgAvatar(name, color) {
|
|
7451
|
+
var src = getMsgAvatarUrl(name);
|
|
7452
|
+
return '<img class="msg-avatar-img" src="' + escapeHtml(src) + '" alt="' + escapeHtml(name) + '" onerror="this.outerHTML=\'<div class="msg-avatar" style="background:' + color + '">' + initial(name) + '</div>\'">';
|
|
7918
7453
|
}
|
|
7919
7454
|
|
|
7920
7455
|
// ==================== v3.0: PROFILE POPUP ====================
|
|
@@ -8059,39 +7594,43 @@ function ppPing(agentName) {
|
|
|
8059
7594
|
}
|
|
8060
7595
|
|
|
8061
7596
|
function ppMessage(agentName) {
|
|
7597
|
+
document.getElementById('profile-popup').classList.remove('open');
|
|
7598
|
+
switchView('messages');
|
|
8062
7599
|
var sel = document.getElementById('inject-target');
|
|
8063
7600
|
if (sel) sel.value = agentName;
|
|
8064
7601
|
var ta = document.getElementById('inject-content');
|
|
8065
7602
|
if (ta) { ta.value = ''; ta.focus(); }
|
|
8066
7603
|
updateSendBtn();
|
|
8067
|
-
document.getElementById('profile-popup').classList.remove('open');
|
|
8068
7604
|
}
|
|
8069
7605
|
|
|
8070
7606
|
function ppNudge(agentName) {
|
|
7607
|
+
document.getElementById('profile-popup').classList.remove('open');
|
|
7608
|
+
switchView('messages');
|
|
8071
7609
|
var sel = document.getElementById('inject-target');
|
|
8072
7610
|
if (sel) sel.value = agentName;
|
|
8073
7611
|
var ta = document.getElementById('inject-content');
|
|
8074
7612
|
if (ta) { ta.value = '@' + agentName + ' '; ta.focus(); }
|
|
8075
7613
|
updateSendBtn();
|
|
8076
|
-
document.getElementById('profile-popup').classList.remove('open');
|
|
8077
7614
|
}
|
|
8078
7615
|
|
|
8079
7616
|
function ppFilterChat(agentName) {
|
|
7617
|
+
document.getElementById('profile-popup').classList.remove('open');
|
|
7618
|
+
switchView('messages');
|
|
8080
7619
|
searchQuery = agentName.toLowerCase();
|
|
8081
7620
|
var input = document.getElementById('search-input');
|
|
8082
7621
|
if (input) input.value = agentName;
|
|
8083
7622
|
lastMessageCount = 0;
|
|
8084
7623
|
renderMessages(cachedHistory);
|
|
8085
|
-
document.getElementById('profile-popup').classList.remove('open');
|
|
8086
7624
|
}
|
|
8087
7625
|
|
|
8088
7626
|
function ppViewHistory(agentName) {
|
|
7627
|
+
document.getElementById('profile-popup').classList.remove('open');
|
|
7628
|
+
switchView('messages');
|
|
8089
7629
|
searchQuery = agentName.toLowerCase();
|
|
8090
7630
|
var input = document.getElementById('search-input');
|
|
8091
7631
|
if (input) input.value = agentName;
|
|
8092
7632
|
lastMessageCount = 0;
|
|
8093
7633
|
renderMessages(cachedHistory);
|
|
8094
|
-
document.getElementById('profile-popup').classList.remove('open');
|
|
8095
7634
|
}
|
|
8096
7635
|
|
|
8097
7636
|
function showProfilePopup(agentName, event) {
|
|
@@ -8106,7 +7645,9 @@ function showProfilePopup(agentName, event) {
|
|
|
8106
7645
|
|
|
8107
7646
|
// Header: avatar, name, status badge
|
|
8108
7647
|
var ppAvatar = document.getElementById('pp-avatar');
|
|
8109
|
-
|
|
7648
|
+
var ppAvatarUrl = getMsgAvatarUrl(agentName);
|
|
7649
|
+
ppAvatar.setAttribute('src', ppAvatarUrl);
|
|
7650
|
+
ppAvatar.style.display = '';
|
|
8110
7651
|
document.getElementById('pp-name').textContent = agent.display_name || agentName;
|
|
8111
7652
|
document.getElementById('pp-name').style.color = color;
|
|
8112
7653
|
document.getElementById('pp-id').textContent = '@' + agentName;
|
|
@@ -8118,21 +7659,38 @@ function showProfilePopup(agentName, event) {
|
|
|
8118
7659
|
document.getElementById('pp-status-badge').className = 'pp-status-badge ' + badgeClass;
|
|
8119
7660
|
document.getElementById('pp-status-badge').textContent = statusLabel;
|
|
8120
7661
|
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
7662
|
+
switchPpTab('stats', false);
|
|
7663
|
+
|
|
7664
|
+
// === Stats ===
|
|
7665
|
+
var _badgePalette = [
|
|
7666
|
+
{ bg: 'rgba(96,165,250,0.15)', fg: '#60a5fa' },
|
|
7667
|
+
{ bg: 'rgba(52,211,153,0.15)', fg: '#34d399' },
|
|
7668
|
+
{ bg: 'rgba(251,191,36,0.15)', fg: '#fbbf24' },
|
|
7669
|
+
{ bg: 'rgba(167,139,250,0.15)', fg: '#a78bfa' },
|
|
7670
|
+
{ bg: 'rgba(251,113,133,0.15)', fg: '#fb7185' },
|
|
7671
|
+
{ bg: 'rgba(56,189,248,0.15)', fg: '#38bdf8' },
|
|
7672
|
+
{ bg: 'rgba(249,115,22,0.15)', fg: '#f97316' },
|
|
7673
|
+
{ bg: 'rgba(232,121,249,0.15)', fg: '#e879f9' },
|
|
7674
|
+
];
|
|
7675
|
+
function _badgeColor(text) {
|
|
7676
|
+
var h = 0;
|
|
7677
|
+
for (var i = 0; i < text.length; i++) h = ((h << 5) - h) + text.charCodeAt(i);
|
|
7678
|
+
return _badgePalette[Math.abs(h) % _badgePalette.length];
|
|
7679
|
+
}
|
|
8125
7680
|
var badgesHtml = '';
|
|
8126
|
-
if (agent.provider) badgesHtml += '<span class="role-badge" style="font-size:10px">' + escapeHtml(agent.provider) + '</span>';
|
|
8127
|
-
if (agent.role) badgesHtml += '<span class="role-badge" style="font-size:10px">' + escapeHtml(agent.role) + '</span>';
|
|
7681
|
+
if (agent.provider) { var bc = _badgeColor(agent.provider); badgesHtml += '<span class="role-badge" style="font-size:10px;background:' + bc.bg + ';color:' + bc.fg + '">' + escapeHtml(agent.provider) + '</span>'; }
|
|
7682
|
+
if (agent.role) { var bc2 = _badgeColor(agent.role); badgesHtml += '<span class="role-badge" style="font-size:10px;background:' + bc2.bg + ';color:' + bc2.fg + '">' + escapeHtml(agent.role) + '</span>'; }
|
|
8128
7683
|
document.getElementById('pp-badges').innerHTML = badgesHtml;
|
|
8129
7684
|
|
|
8130
|
-
// Count tasks completed and messages for this agent
|
|
8131
7685
|
var tasksCompleted = 0;
|
|
7686
|
+
var tasksActive = 0;
|
|
8132
7687
|
var msgCount = 0;
|
|
8133
7688
|
if (cachedTasks) {
|
|
8134
7689
|
for (var t = 0; t < cachedTasks.length; t++) {
|
|
8135
|
-
if (cachedTasks[t].assignee === agentName
|
|
7690
|
+
if (cachedTasks[t].assignee === agentName) {
|
|
7691
|
+
if (cachedTasks[t].status === 'done') tasksCompleted++;
|
|
7692
|
+
else if (cachedTasks[t].status === 'in_progress' || cachedTasks[t].status === 'in_review') tasksActive++;
|
|
7693
|
+
}
|
|
8136
7694
|
}
|
|
8137
7695
|
}
|
|
8138
7696
|
if (cachedHistory) {
|
|
@@ -8141,68 +7699,50 @@ function showProfilePopup(agentName, event) {
|
|
|
8141
7699
|
}
|
|
8142
7700
|
}
|
|
8143
7701
|
|
|
8144
|
-
var statsHtml = '<div class="profile-popup-stat"><span>' + tasksCompleted + '</span>
|
|
8145
|
-
'<div class="profile-popup-stat"><span>' +
|
|
7702
|
+
var statsHtml = '<div class="profile-popup-stat"><span>' + tasksCompleted + '</span>Done</div>' +
|
|
7703
|
+
'<div class="profile-popup-stat"><span>' + tasksActive + '</span>Active</div>' +
|
|
7704
|
+
'<div class="profile-popup-stat"><span>' + msgCount + '</span>Sent</div>' +
|
|
7705
|
+
'<div class="profile-popup-stat"><span>' + (agent.branch || 'main') + '</span>Branch</div>';
|
|
8146
7706
|
document.getElementById('pp-stats').innerHTML = statsHtml;
|
|
8147
7707
|
|
|
8148
|
-
// Skills (read-only display)
|
|
8149
7708
|
var skills = agent.skills || [];
|
|
8150
7709
|
var skillsRoHtml = '';
|
|
8151
7710
|
if (skills.length > 0) {
|
|
8152
|
-
|
|
8153
|
-
var platformSkills = agent.platform_skills || [];
|
|
8154
|
-
skillsRoHtml = '<div style="font-size:10px;text-transform:uppercase;letter-spacing:0.5px;color:var(--text-muted);margin-bottom:6px">Skills</div><div class="skill-tags-inline">';
|
|
7711
|
+
skillsRoHtml = '<div style="display:flex;flex-wrap:wrap;gap:4px">';
|
|
8155
7712
|
for (var s = 0; s < skills.length; s++) {
|
|
8156
|
-
|
|
8157
|
-
skillsRoHtml += '<span class="skill-tag' + (isPlatform ? ' ' + platformClass : '') + '">' + escapeHtml(skills[s]) + '</span>';
|
|
7713
|
+
skillsRoHtml += '<span class="skill-tag">' + escapeHtml(skills[s]) + '</span>';
|
|
8158
7714
|
}
|
|
8159
7715
|
skillsRoHtml += '</div>';
|
|
8160
7716
|
}
|
|
8161
7717
|
document.getElementById('pp-skills-readonly').innerHTML = skillsRoHtml;
|
|
8162
7718
|
|
|
8163
|
-
// ===
|
|
7719
|
+
// === Quick actions ===
|
|
8164
7720
|
var eName = escapeHtml(agentName);
|
|
8165
|
-
|
|
8166
|
-
'<svg viewBox="0 0
|
|
8167
|
-
'
|
|
8168
|
-
'<button class="pp-action
|
|
8169
|
-
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
'Nudge</button>' +
|
|
8174
|
-
'<button class="pp-action-btn" onclick="ppFilterChat(\'' + eName + '\')">' +
|
|
8175
|
-
'<svg viewBox="0 0 24 24"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>' +
|
|
8176
|
-
'Messages</button>' +
|
|
8177
|
-
'<button class="pp-action-btn" onclick="ppViewHistory(\'' + eName + '\')">' +
|
|
8178
|
-
'<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>' +
|
|
8179
|
-
'History</button>';
|
|
8180
|
-
document.getElementById('pp-actions').innerHTML = actionsHtml;
|
|
8181
|
-
|
|
8182
|
-
// === Profile Tab ===
|
|
8183
|
-
document.getElementById('pp-bio').textContent = agent.bio || 'No bio set.';
|
|
8184
|
-
renderSkillEditor(agentName);
|
|
8185
|
-
|
|
8186
|
-
// Position near click — find closest clickable ancestor
|
|
8187
|
-
var anchor = event.target.closest('.agent-top') || event.target.closest('.agent-card') || event.target;
|
|
7721
|
+
document.getElementById('pp-quick-actions').innerHTML =
|
|
7722
|
+
'<button class="pp-quick-action" onclick="ppMessage(\'' + eName + '\')"><svg viewBox="0 0 16 16"><path d="M2 3h12v8H6l-3 2.5V11H2z" stroke-linejoin="round"/></svg>Message</button>' +
|
|
7723
|
+
'<button class="pp-quick-action" onclick="ppFilterChat(\'' + eName + '\')"><svg viewBox="0 0 16 16"><path d="M8 14A6 6 0 108 2a6 6 0 000 12z"/><path d="M8 5v3l2 1"/></svg>History</button>' +
|
|
7724
|
+
'<button class="pp-quick-action" onclick="ppNudge(\'' + eName + '\')"><svg viewBox="0 0 16 16"><path d="M13 3L3 8l4 1.5L8.5 14z" stroke-linejoin="round"/></svg>Nudge</button>';
|
|
7725
|
+
|
|
7726
|
+
document.getElementById('pp-bio').textContent = agent.bio || '';
|
|
7727
|
+
|
|
7728
|
+
var anchor = event.target.closest('.agent-card') || event.target.closest('.agent-pill') || event.target;
|
|
8188
7729
|
var rect = anchor.getBoundingClientRect();
|
|
8189
7730
|
popup.style.visibility = 'hidden';
|
|
8190
7731
|
popup.classList.add('open');
|
|
8191
|
-
var
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8197
|
-
if (topSpace > bottomSpace && topSpace > popupHeight) {
|
|
8198
|
-
topPos = rect.top - popupHeight - 4;
|
|
8199
|
-
} else {
|
|
8200
|
-
topPos = window.innerHeight - popupHeight - 10;
|
|
8201
|
-
}
|
|
7732
|
+
var popupW = popup.offsetWidth;
|
|
7733
|
+
var popupH = popup.offsetHeight;
|
|
7734
|
+
|
|
7735
|
+
var topPos = rect.bottom + 6;
|
|
7736
|
+
if (topPos + popupH > window.innerHeight - 10) {
|
|
7737
|
+
topPos = rect.top - popupH - 6;
|
|
8202
7738
|
}
|
|
7739
|
+
topPos = Math.max(10, Math.min(topPos, window.innerHeight - popupH - 10));
|
|
8203
7740
|
|
|
8204
|
-
|
|
8205
|
-
|
|
7741
|
+
var leftPos = rect.left;
|
|
7742
|
+
leftPos = Math.max(10, Math.min(leftPos, window.innerWidth - popupW - 10));
|
|
7743
|
+
|
|
7744
|
+
popup.style.top = topPos + 'px';
|
|
7745
|
+
popup.style.left = leftPos + 'px';
|
|
8206
7746
|
popup.style.visibility = 'visible';
|
|
8207
7747
|
}
|
|
8208
7748
|
|
|
@@ -8288,15 +7828,6 @@ function showAgentPopup(agentName) {
|
|
|
8288
7828
|
if (!agent) return;
|
|
8289
7829
|
editingAgent = agentName;
|
|
8290
7830
|
openProfileEditor();
|
|
8291
|
-
|
|
8292
|
-
// Auto-switch to stats tab
|
|
8293
|
-
var tabs = document.querySelectorAll('.cd-tab');
|
|
8294
|
-
for (var i = 0; i < tabs.length; i++) {
|
|
8295
|
-
if (tabs[i].textContent === 'Stats') {
|
|
8296
|
-
cdSwitchTab('stats', tabs[i]);
|
|
8297
|
-
break;
|
|
8298
|
-
}
|
|
8299
|
-
}
|
|
8300
7831
|
}
|
|
8301
7832
|
|
|
8302
7833
|
document.addEventListener('click', function() {
|
|
@@ -8357,18 +7888,18 @@ function confirmDeleteAgent() {
|
|
|
8357
7888
|
// ==================== v3.0: PROFILE EDITOR ====================
|
|
8358
7889
|
|
|
8359
7890
|
var BUILT_IN_AVATARS = [
|
|
8360
|
-
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='
|
|
8361
|
-
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='
|
|
8362
|
-
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='
|
|
8363
|
-
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='
|
|
8364
|
-
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='
|
|
8365
|
-
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='
|
|
8366
|
-
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='
|
|
8367
|
-
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='
|
|
8368
|
-
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='
|
|
8369
|
-
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='
|
|
8370
|
-
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='
|
|
8371
|
-
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='
|
|
7891
|
+
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%231e293b'/%3E%3Ccircle cx='32' cy='28' r='12' fill='none' stroke='%2360a5fa' stroke-width='2'/%3E%3Ccircle cx='32' cy='28' r='4' fill='%2360a5fa'/%3E%3Cpath d='M20 48h24' stroke='%2360a5fa' stroke-width='2' stroke-linecap='round'/%3E%3Cpath d='M24 52h16' stroke='%2360a5fa' stroke-width='1.5' stroke-linecap='round' opacity='0.5'/%3E%3C/svg%3E",
|
|
7892
|
+
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%231e293b'/%3E%3Cpolygon points='32,12 52,42 12,42' fill='none' stroke='%2334d399' stroke-width='2'/%3E%3Ccircle cx='32' cy='36' r='3' fill='%2334d399'/%3E%3C/svg%3E",
|
|
7893
|
+
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%231e293b'/%3E%3Crect x='16' y='16' width='32' height='32' rx='4' fill='none' stroke='%23f59e0b' stroke-width='2' transform='rotate(45 32 32)'/%3E%3Ccircle cx='32' cy='32' r='5' fill='%23f59e0b'/%3E%3C/svg%3E",
|
|
7894
|
+
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%231e293b'/%3E%3Ccircle cx='32' cy='32' r='18' fill='none' stroke='%23a78bfa' stroke-width='1.5'/%3E%3Ccircle cx='32' cy='32' r='10' fill='none' stroke='%23a78bfa' stroke-width='1.5'/%3E%3Ccircle cx='32' cy='32' r='3' fill='%23a78bfa'/%3E%3C/svg%3E",
|
|
7895
|
+
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%231e293b'/%3E%3Cpath d='M16 32h32' stroke='%23fb7185' stroke-width='2'/%3E%3Cpath d='M32 16v32' stroke='%23fb7185' stroke-width='2'/%3E%3Ccircle cx='32' cy='32' r='8' fill='none' stroke='%23fb7185' stroke-width='1.5'/%3E%3Ccircle cx='32' cy='32' r='2' fill='%23fb7185'/%3E%3C/svg%3E",
|
|
7896
|
+
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%231e293b'/%3E%3Cpath d='M14 42L32 18L50 42Z' fill='none' stroke='%2338bdf8' stroke-width='2' stroke-linejoin='round'/%3E%3Cpath d='M22 42L32 28L42 42' fill='none' stroke='%2338bdf8' stroke-width='1.5' stroke-linejoin='round' opacity='0.5'/%3E%3C/svg%3E",
|
|
7897
|
+
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%231e293b'/%3E%3Cpath d='M18 18h28v28H18z' fill='none' stroke='%234ade80' stroke-width='2'/%3E%3Cpath d='M26 18v28M38 18v28M18 26h28M18 38h28' stroke='%234ade80' stroke-width='1' opacity='0.4'/%3E%3Crect x='27' y='27' width='10' height='10' fill='%234ade80' opacity='0.3'/%3E%3C/svg%3E",
|
|
7898
|
+
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%231e293b'/%3E%3Cpath d='M32 14L48 24v16L32 50L16 40V24z' fill='none' stroke='%23fbbf24' stroke-width='2' stroke-linejoin='round'/%3E%3Ccircle cx='32' cy='32' r='4' fill='%23fbbf24'/%3E%3C/svg%3E",
|
|
7899
|
+
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%231e293b'/%3E%3Ccircle cx='22' cy='22' r='8' fill='none' stroke='%23f97316' stroke-width='1.5'/%3E%3Ccircle cx='42' cy='22' r='8' fill='none' stroke='%23f97316' stroke-width='1.5'/%3E%3Ccircle cx='32' cy='42' r='8' fill='none' stroke='%23f97316' stroke-width='1.5'/%3E%3Ccircle cx='22' cy='22' r='2' fill='%23f97316'/%3E%3Ccircle cx='42' cy='22' r='2' fill='%23f97316'/%3E%3Ccircle cx='32' cy='42' r='2' fill='%23f97316'/%3E%3C/svg%3E",
|
|
7900
|
+
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%231e293b'/%3E%3Cpath d='M12 50L32 14L52 50Z' fill='none' stroke='%23e879f9' stroke-width='2' stroke-linejoin='round'/%3E%3Cpath d='M32 50L22 32L42 32Z' fill='%23e879f9' opacity='0.2'/%3E%3Ccircle cx='32' cy='38' r='3' fill='%23e879f9'/%3E%3C/svg%3E",
|
|
7901
|
+
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%231e293b'/%3E%3Cpath d='M16 32C16 20 32 14 32 14S48 20 48 32S32 50 32 50S16 44 16 32Z' fill='none' stroke='%23f43f5e' stroke-width='2'/%3E%3Ccircle cx='32' cy='32' r='4' fill='%23f43f5e' opacity='0.6'/%3E%3C/svg%3E",
|
|
7902
|
+
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%231e293b'/%3E%3Ccircle cx='32' cy='32' r='16' fill='none' stroke='%2394a3b8' stroke-width='1.5' stroke-dasharray='4 3'/%3E%3Cpath d='M32 16v32M16 32h32' stroke='%2394a3b8' stroke-width='1' opacity='0.3'/%3E%3Ccircle cx='32' cy='32' r='5' fill='%2394a3b8' opacity='0.4'/%3E%3Ccircle cx='32' cy='32' r='2' fill='%2394a3b8'/%3E%3C/svg%3E",
|
|
8372
7903
|
];
|
|
8373
7904
|
|
|
8374
7905
|
var editingAgent = '';
|
|
@@ -8422,11 +7953,6 @@ function cdOnChange() {
|
|
|
8422
7953
|
|
|
8423
7954
|
function cdSwitchTab(name, btn) {
|
|
8424
7955
|
cdCurrentTab = name;
|
|
8425
|
-
document.querySelectorAll('.cd-tab-content').forEach(function(el) { el.classList.remove('active'); });
|
|
8426
|
-
document.querySelectorAll('.cd-tab').forEach(function(el) { el.classList.remove('active'); });
|
|
8427
|
-
var target = document.getElementById('cd-tab-' + name);
|
|
8428
|
-
if (target) target.classList.add('active');
|
|
8429
|
-
if (btn) btn.classList.add('active');
|
|
8430
7956
|
}
|
|
8431
7957
|
|
|
8432
7958
|
function cdActivateCard(container, value) {
|
|
@@ -8541,52 +8067,12 @@ function openProfileEditor() {
|
|
|
8541
8067
|
|
|
8542
8068
|
document.getElementById('profile-popup').classList.remove('open');
|
|
8543
8069
|
|
|
8544
|
-
// Populate basic fields
|
|
8545
8070
|
document.getElementById('pe-display-name').value = agent.display_name || editingAgent;
|
|
8546
8071
|
document.getElementById('pe-role').value = agent.role || '';
|
|
8547
8072
|
document.getElementById('pe-bio').value = agent.bio || '';
|
|
8548
8073
|
document.getElementById('pe-avatar-url').value = '';
|
|
8549
8074
|
selectedAvatar = agent.avatar || '';
|
|
8550
8075
|
|
|
8551
|
-
var app = agent.appearance || {};
|
|
8552
|
-
var defApp = app;
|
|
8553
|
-
|
|
8554
|
-
// Set color pickers
|
|
8555
|
-
document.getElementById('pe-head-color').value = defApp.head_color || '#FFD5B8';
|
|
8556
|
-
document.getElementById('pe-shirt-color').value = defApp.shirt_color || '#f59e0b';
|
|
8557
|
-
document.getElementById('pe-hair-color').value = defApp.hair_color || '#4A3728';
|
|
8558
|
-
document.getElementById('pe-pants-color').value = defApp.pants_color || '#2d3748';
|
|
8559
|
-
document.getElementById('pe-shoe-color').value = defApp.shoe_color || '#1a1a2e';
|
|
8560
|
-
document.getElementById('pe-glasses-color').value = defApp.glasses_color || '#555555';
|
|
8561
|
-
document.getElementById('pe-headwear-color').value = defApp.headwear_color || '#333333';
|
|
8562
|
-
document.getElementById('pe-neckwear-color').value = defApp.neckwear_color || '#c0392b';
|
|
8563
|
-
|
|
8564
|
-
// Set appearance state
|
|
8565
|
-
cdAppearance.hair_style = defApp.hair_style || 'short';
|
|
8566
|
-
cdAppearance.eye_style = defApp.eye_style || 'dots';
|
|
8567
|
-
cdAppearance.mouth_style = defApp.mouth_style || 'smile';
|
|
8568
|
-
cdAppearance.glasses = defApp.glasses || null;
|
|
8569
|
-
cdAppearance.headwear = defApp.headwear || null;
|
|
8570
|
-
cdAppearance.neckwear = defApp.neckwear || null;
|
|
8571
|
-
cdAppearance.outfit = defApp.outfit || null;
|
|
8572
|
-
cdAppearance.body_type = defApp.body_type || 'default';
|
|
8573
|
-
|
|
8574
|
-
// Activate correct cards
|
|
8575
|
-
cdActivateCard('cd-hair-styles', cdAppearance.hair_style);
|
|
8576
|
-
cdActivateCard('cd-eye-styles', cdAppearance.eye_style);
|
|
8577
|
-
cdActivateCard('cd-mouth-styles', cdAppearance.mouth_style);
|
|
8578
|
-
cdActivateCard('cd-glasses-styles', cdAppearance.glasses || '');
|
|
8579
|
-
cdActivateCard('cd-headwear-styles', cdAppearance.headwear || '');
|
|
8580
|
-
cdActivateCard('cd-neckwear-styles', cdAppearance.neckwear || '');
|
|
8581
|
-
cdActivateCard('cd-outfit-styles', cdAppearance.outfit || '');
|
|
8582
|
-
cdActivateCard('cd-body-types', cdAppearance.body_type);
|
|
8583
|
-
|
|
8584
|
-
// Show/hide accessory color rows
|
|
8585
|
-
document.getElementById('cd-glasses-color-row').style.display = cdAppearance.glasses ? 'flex' : 'none';
|
|
8586
|
-
document.getElementById('cd-headwear-color-row').style.display = cdAppearance.headwear ? 'flex' : 'none';
|
|
8587
|
-
document.getElementById('cd-neckwear-color-row').style.display = cdAppearance.neckwear ? 'flex' : 'none';
|
|
8588
|
-
|
|
8589
|
-
// Build avatar picker grid
|
|
8590
8076
|
var picker = document.getElementById('avatar-picker');
|
|
8591
8077
|
var html = '';
|
|
8592
8078
|
for (var i = 0; i < BUILT_IN_AVATARS.length; i++) {
|
|
@@ -8595,20 +8081,17 @@ function openProfileEditor() {
|
|
|
8595
8081
|
}
|
|
8596
8082
|
picker.innerHTML = html;
|
|
8597
8083
|
|
|
8598
|
-
// Reset to Body tab
|
|
8599
|
-
cdSwitchTab('body', document.querySelector('.cd-tab'));
|
|
8600
|
-
|
|
8601
|
-
// Calculate and populate stats
|
|
8602
8084
|
var sent = 0, received = 0;
|
|
8603
8085
|
for (var i = 0; i < cachedHistory.length; i++) {
|
|
8604
8086
|
if (cachedHistory[i].from === editingAgent) sent++;
|
|
8605
8087
|
if (cachedHistory[i].to === editingAgent) received++;
|
|
8606
8088
|
}
|
|
8089
|
+
var statCell = 'background:var(--surface-2);padding:7px 10px;border-radius:6px;border:1px solid var(--border)';
|
|
8607
8090
|
var statsHtml =
|
|
8608
|
-
'<div style="
|
|
8609
|
-
'<div style="
|
|
8610
|
-
'<div style="
|
|
8611
|
-
'<div style="
|
|
8091
|
+
'<div style="' + statCell + '">Sent: <b style="color:var(--text)">' + sent + '</b></div>' +
|
|
8092
|
+
'<div style="' + statCell + '">Received: <b style="color:var(--text)">' + received + '</b></div>' +
|
|
8093
|
+
'<div style="' + statCell + '">Provider: <b style="color:var(--text)">' + escapeHtml(agent.provider || 'unknown') + '</b></div>' +
|
|
8094
|
+
'<div style="' + statCell + '">Branch: <b style="color:var(--text)">' + escapeHtml(agent.branch || 'main') + '</b></div>';
|
|
8612
8095
|
document.getElementById('pe-stats-container').innerHTML = statsHtml;
|
|
8613
8096
|
|
|
8614
8097
|
var pq = projectParam();
|
|
@@ -8616,28 +8099,22 @@ function openProfileEditor() {
|
|
|
8616
8099
|
if (!data || !data.agents || !data.agents[editingAgent]) return;
|
|
8617
8100
|
var tu = data.agents[editingAgent];
|
|
8618
8101
|
var tokenHtml =
|
|
8619
|
-
'<div style="grid-column:1/-1;margin-top:
|
|
8620
|
-
'<div style="
|
|
8621
|
-
'<div style="
|
|
8622
|
-
'<div style="
|
|
8623
|
-
'<div style="background:var(--accent-dim);color:var(--accent);padding:10px;border-radius:6px;border:1px solid var(--accent);font-weight:700">Cost: $' + (tu.estimated_cost_usd || 0).toFixed(2) + '</div>';
|
|
8102
|
+
'<div style="grid-column:1/-1;margin-top:8px;font-weight:800;color:var(--text);font-size:11px;text-transform:uppercase;border-bottom:1px solid var(--border);padding-bottom:4px">Token Usage (<span style="color:var(--accent);font-weight:600">' + escapeHtml(tu.model || 'unknown') + '</span>)</div>' +
|
|
8103
|
+
'<div style="' + statCell + '">Input: <b style="color:var(--text)">' + (tu.input_tokens || 0).toLocaleString() + '</b></div>' +
|
|
8104
|
+
'<div style="' + statCell + '">Output: <b style="color:var(--text)">' + (tu.output_tokens || 0).toLocaleString() + '</b></div>' +
|
|
8105
|
+
'<div style="' + statCell + '">Cache: <b style="color:var(--text)">' + ((tu.cache_creation_tokens || 0) + (tu.cache_read_tokens || 0)).toLocaleString() + '</b></div>' +
|
|
8106
|
+
'<div style="background:var(--accent-dim);color:var(--accent);padding:7px 10px;border-radius:6px;border:1px solid var(--accent);font-weight:700">Cost: $' + (tu.estimated_cost_usd || 0).toFixed(2) + '</div>';
|
|
8624
8107
|
var el = document.getElementById('pe-stats-container');
|
|
8625
8108
|
if (el) el.innerHTML += tokenHtml;
|
|
8626
8109
|
}).catch(function() {});
|
|
8627
8110
|
|
|
8628
|
-
// Open the panel
|
|
8629
8111
|
document.getElementById('char-designer').classList.add('open');
|
|
8630
8112
|
document.getElementById('cd-backdrop').classList.add('open');
|
|
8631
|
-
|
|
8632
|
-
// Update hex displays and init 3D preview
|
|
8633
|
-
cdOnChange();
|
|
8634
|
-
if (window._cdInitPreview) window._cdInitPreview();
|
|
8635
8113
|
}
|
|
8636
8114
|
|
|
8637
8115
|
function closeProfileEditor() {
|
|
8638
8116
|
document.getElementById('char-designer').classList.remove('open');
|
|
8639
8117
|
document.getElementById('cd-backdrop').classList.remove('open');
|
|
8640
|
-
if (window._cdDisposePreview) window._cdDisposePreview();
|
|
8641
8118
|
}
|
|
8642
8119
|
|
|
8643
8120
|
function selectAvatar(idx) {
|
|
@@ -8665,31 +8142,12 @@ function handleAvatarUpload(input) {
|
|
|
8665
8142
|
function saveProfile() {
|
|
8666
8143
|
var avatarUrl = document.getElementById('pe-avatar-url').value.trim();
|
|
8667
8144
|
var avatar = avatarUrl || selectedAvatar;
|
|
8668
|
-
var app = cdGetAppearance();
|
|
8669
8145
|
|
|
8670
8146
|
var body = {
|
|
8671
8147
|
agent: editingAgent,
|
|
8672
8148
|
display_name: document.getElementById('pe-display-name').value.trim() || editingAgent,
|
|
8673
8149
|
role: document.getElementById('pe-role').value.trim(),
|
|
8674
|
-
bio: document.getElementById('pe-bio').value.trim()
|
|
8675
|
-
appearance: {
|
|
8676
|
-
head_color: app.head_color,
|
|
8677
|
-
shirt_color: app.shirt_color,
|
|
8678
|
-
hair_style: app.hair_style,
|
|
8679
|
-
hair_color: app.hair_color,
|
|
8680
|
-
eye_style: app.eye_style,
|
|
8681
|
-
mouth_style: app.mouth_style,
|
|
8682
|
-
pants_color: app.pants_color,
|
|
8683
|
-
shoe_color: app.shoe_color,
|
|
8684
|
-
glasses: app.glasses,
|
|
8685
|
-
glasses_color: app.glasses_color,
|
|
8686
|
-
headwear: app.headwear,
|
|
8687
|
-
headwear_color: app.headwear_color,
|
|
8688
|
-
neckwear: app.neckwear,
|
|
8689
|
-
neckwear_color: app.neckwear_color,
|
|
8690
|
-
outfit: app.outfit,
|
|
8691
|
-
body_type: app.body_type
|
|
8692
|
-
}
|
|
8150
|
+
bio: document.getElementById('pe-bio').value.trim()
|
|
8693
8151
|
};
|
|
8694
8152
|
if (avatar) body.avatar = avatar;
|
|
8695
8153
|
|