@co0ontty/wand 1.31.3 → 1.32.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/dist/auth.d.ts +20 -0
- package/dist/auth.js +31 -0
- package/dist/cert.d.ts +17 -2
- package/dist/cert.js +124 -68
- package/dist/config.js +12 -0
- package/dist/server.js +60 -51
- package/dist/tui/commands.js +51 -5
- package/dist/types.d.ts +9 -0
- package/dist/web-ui/content/scripts.js +181 -242
- package/dist/web-ui/content/styles.css +153 -316
- package/dist/ws-broadcast.d.ts +2 -2
- package/dist/ws-broadcast.js +5 -10
- package/package.json +1 -1
|
@@ -3846,6 +3846,7 @@
|
|
|
3846
3846
|
横向溢出都不应该冒到聊天容器,由它们各自的内部滚动负责。 */
|
|
3847
3847
|
.chat-messages {
|
|
3848
3848
|
flex: 1;
|
|
3849
|
+
min-width: 0;
|
|
3849
3850
|
overflow-y: auto;
|
|
3850
3851
|
overflow-x: hidden;
|
|
3851
3852
|
display: flex;
|
|
@@ -6358,19 +6359,18 @@
|
|
|
6358
6359
|
}
|
|
6359
6360
|
|
|
6360
6361
|
/* ─────────────────────────────────────────────────────────────────────
|
|
6361
|
-
排队消息条(.queue-bar)—— 浮在
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
展开时给 .queue-bar 加 .expanded class,CSS 控制 panel 显形 + chevron 翻转。
|
|
6362
|
+
排队消息条(.queue-bar)—— 浮在 "回复中" 状态条上方,垂直堆叠。
|
|
6363
|
+
交互参考 iOS 通讯录右侧字母选择条:
|
|
6364
|
+
· 默认只展开队首 chip(橙色完整气泡,显示编号 + 文本 + × 删除)
|
|
6365
|
+
· 其他 chip 收成一根小横杠(橙色细线,宽 32px 高 4px)
|
|
6366
|
+
· 鼠标悬到任一横杠 → 该条展开、原本展开的收回横杠
|
|
6367
|
+
· 悬停期间可按住任意位置上下拖拽换序,整条 chip 都是拖拽起手区
|
|
6368
|
+
末尾是独立的 ⚡ 立即按钮:中断当前回复,把队首作为新输入插队发出去。
|
|
6369
6369
|
───────────────────────────────────────────────────────────────────── */
|
|
6370
6370
|
.queue-bar-host {
|
|
6371
6371
|
display: flex;
|
|
6372
6372
|
justify-content: flex-end;
|
|
6373
|
-
padding:
|
|
6373
|
+
padding: 4px 8px 0;
|
|
6374
6374
|
position: relative;
|
|
6375
6375
|
z-index: 2;
|
|
6376
6376
|
pointer-events: none; /* host 自身不挡点击,bar 内子节点 auto */
|
|
@@ -6380,358 +6380,199 @@
|
|
|
6380
6380
|
.queue-bar {
|
|
6381
6381
|
pointer-events: auto;
|
|
6382
6382
|
position: relative;
|
|
6383
|
-
display:
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
max-width: calc(
|
|
6388
|
-
height: 38px;
|
|
6389
|
-
padding: 0;
|
|
6390
|
-
border-radius: 999px;
|
|
6391
|
-
background: linear-gradient(180deg, #fffaf2 0%, #f6ead8 100%);
|
|
6392
|
-
box-shadow:
|
|
6393
|
-
0 0 0 1.2px rgba(197, 101, 61, 0.42),
|
|
6394
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.85),
|
|
6395
|
-
var(--shadow-sm);
|
|
6396
|
-
transition: box-shadow var(--transition-fast), transform var(--transition-fast);
|
|
6383
|
+
display: flex;
|
|
6384
|
+
flex-direction: column;
|
|
6385
|
+
align-items: flex-end;
|
|
6386
|
+
gap: 4px;
|
|
6387
|
+
max-width: min(360px, calc(100vw - 24px));
|
|
6397
6388
|
animation: queueBarEnter 220ms ease-out both;
|
|
6398
6389
|
}
|
|
6399
|
-
.queue-bar:hover {
|
|
6400
|
-
transform: translateY(-1px);
|
|
6401
|
-
box-shadow:
|
|
6402
|
-
0 0 0 1.2px rgba(197, 101, 61, 0.55),
|
|
6403
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.9),
|
|
6404
|
-
var(--shadow-md);
|
|
6405
|
-
}
|
|
6406
|
-
.queue-bar.queue-bar-capacity {
|
|
6407
|
-
box-shadow:
|
|
6408
|
-
0 0 0 1.4px rgba(169, 106, 47, 0.6),
|
|
6409
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.85),
|
|
6410
|
-
var(--shadow-sm);
|
|
6411
|
-
}
|
|
6412
|
-
.queue-bar.queue-bar-inflight {
|
|
6413
|
-
animation: queueBarEnter 220ms ease-out both, queuePulse 1.6s ease-in-out 220ms infinite;
|
|
6414
|
-
}
|
|
6415
6390
|
@keyframes queueBarEnter {
|
|
6416
|
-
from { opacity: 0; transform: translateY(4px) scale(0.
|
|
6391
|
+
from { opacity: 0; transform: translateY(4px) scale(0.96); }
|
|
6417
6392
|
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
6418
6393
|
}
|
|
6419
6394
|
|
|
6420
|
-
.queue-bar-toggle {
|
|
6421
|
-
flex: 1 1 auto;
|
|
6422
|
-
min-width: 0;
|
|
6423
|
-
display: inline-flex;
|
|
6424
|
-
align-items: center;
|
|
6425
|
-
gap: 7px;
|
|
6426
|
-
padding: 0 10px 0 14px;
|
|
6427
|
-
border: none;
|
|
6428
|
-
background: transparent;
|
|
6429
|
-
cursor: pointer;
|
|
6430
|
-
font: inherit;
|
|
6431
|
-
color: var(--text-primary);
|
|
6432
|
-
border-radius: 999px 0 0 999px;
|
|
6433
|
-
text-align: left;
|
|
6434
|
-
}
|
|
6435
|
-
.queue-bar-toggle:focus-visible {
|
|
6436
|
-
outline: 2px solid var(--border-focus);
|
|
6437
|
-
outline-offset: -2px;
|
|
6438
|
-
}
|
|
6439
|
-
.queue-bar-dot {
|
|
6440
|
-
width: 8px;
|
|
6441
|
-
height: 8px;
|
|
6442
|
-
border-radius: 50%;
|
|
6443
|
-
background: var(--accent);
|
|
6444
|
-
flex-shrink: 0;
|
|
6445
|
-
box-shadow: 0 0 0 2px rgba(197, 101, 61, 0.18);
|
|
6446
|
-
}
|
|
6447
|
-
.queue-bar-dot.queue-bar-dot-pulse {
|
|
6448
|
-
animation: queueDotPulse 1.0s ease-in-out infinite;
|
|
6449
|
-
}
|
|
6450
|
-
.queue-bar-count {
|
|
6451
|
-
font-size: 0.75rem;
|
|
6452
|
-
font-weight: 600;
|
|
6453
|
-
color: var(--accent);
|
|
6454
|
-
letter-spacing: 0.02em;
|
|
6455
|
-
flex-shrink: 0;
|
|
6456
|
-
line-height: 1;
|
|
6457
|
-
}
|
|
6458
|
-
.queue-bar-sep {
|
|
6459
|
-
color: var(--text-muted);
|
|
6460
|
-
opacity: 0.55;
|
|
6461
|
-
font-size: 0.7rem;
|
|
6462
|
-
flex-shrink: 0;
|
|
6463
|
-
}
|
|
6464
|
-
.queue-bar-preview {
|
|
6465
|
-
font-size: 0.75rem;
|
|
6466
|
-
color: var(--text-secondary);
|
|
6467
|
-
flex: 1 1 auto;
|
|
6468
|
-
min-width: 0;
|
|
6469
|
-
overflow: hidden;
|
|
6470
|
-
text-overflow: ellipsis;
|
|
6471
|
-
white-space: nowrap;
|
|
6472
|
-
line-height: 1;
|
|
6473
|
-
}
|
|
6474
|
-
.queue-bar-chevron {
|
|
6475
|
-
color: var(--text-tertiary);
|
|
6476
|
-
flex-shrink: 0;
|
|
6477
|
-
transition: transform 180ms ease-out;
|
|
6478
|
-
}
|
|
6479
|
-
.queue-bar.expanded .queue-bar-chevron {
|
|
6480
|
-
transform: rotate(180deg);
|
|
6481
|
-
color: var(--accent);
|
|
6482
|
-
}
|
|
6483
|
-
|
|
6484
|
-
.queue-bar-divider {
|
|
6485
|
-
width: 1px;
|
|
6486
|
-
background: rgba(197, 101, 61, 0.28);
|
|
6487
|
-
margin: 7px 0;
|
|
6488
|
-
flex-shrink: 0;
|
|
6489
|
-
}
|
|
6490
|
-
|
|
6491
|
-
.queue-bar-promote {
|
|
6492
|
-
flex-shrink: 0;
|
|
6493
|
-
display: inline-flex;
|
|
6494
|
-
align-items: center;
|
|
6495
|
-
gap: 5px;
|
|
6496
|
-
padding: 0 14px 0 12px;
|
|
6497
|
-
border: none;
|
|
6498
|
-
cursor: pointer;
|
|
6499
|
-
font: inherit;
|
|
6500
|
-
font-size: 0.75rem;
|
|
6501
|
-
font-weight: 600;
|
|
6502
|
-
color: #fff;
|
|
6503
|
-
background: linear-gradient(180deg, var(--accent) 0%, var(--accent-active) 100%);
|
|
6504
|
-
border-radius: 0 999px 999px 0;
|
|
6505
|
-
letter-spacing: 0.04em;
|
|
6506
|
-
transition: filter var(--transition-fast), transform var(--transition-fast);
|
|
6507
|
-
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22);
|
|
6508
|
-
}
|
|
6509
|
-
.queue-bar-promote:hover { filter: brightness(1.06); }
|
|
6510
|
-
.queue-bar-promote:active { transform: scale(0.97); }
|
|
6511
|
-
.queue-bar-promote:focus-visible {
|
|
6512
|
-
outline: 2px solid var(--border-focus);
|
|
6513
|
-
outline-offset: 2px;
|
|
6514
|
-
}
|
|
6515
|
-
.queue-bar-promote svg { flex-shrink: 0; }
|
|
6516
|
-
.queue-bar-promote-label { line-height: 1; }
|
|
6517
|
-
|
|
6518
|
-
/* 展开面板:默认折叠(不可见 + 不占空间),加 .expanded 时滑出 */
|
|
6519
|
-
.queue-bar-panel {
|
|
6520
|
-
position: absolute;
|
|
6521
|
-
right: 0;
|
|
6522
|
-
bottom: calc(100% + 8px);
|
|
6523
|
-
width: min(380px, calc(100vw - 24px));
|
|
6524
|
-
max-height: 280px;
|
|
6525
|
-
display: flex;
|
|
6526
|
-
flex-direction: column;
|
|
6527
|
-
background: var(--bg-elevated);
|
|
6528
|
-
border-radius: 14px;
|
|
6529
|
-
box-shadow:
|
|
6530
|
-
0 0 0 1px var(--border-default),
|
|
6531
|
-
var(--shadow-lg);
|
|
6532
|
-
overflow: hidden;
|
|
6533
|
-
opacity: 0;
|
|
6534
|
-
transform: scale(0.96) translateY(4px);
|
|
6535
|
-
transform-origin: bottom right;
|
|
6536
|
-
pointer-events: none;
|
|
6537
|
-
transition: opacity 180ms ease-out, transform 180ms ease-out;
|
|
6538
|
-
}
|
|
6539
|
-
.queue-bar.expanded .queue-bar-panel {
|
|
6540
|
-
opacity: 1;
|
|
6541
|
-
transform: scale(1) translateY(0);
|
|
6542
|
-
pointer-events: auto;
|
|
6543
|
-
}
|
|
6544
|
-
|
|
6545
|
-
.queue-bar-panel-header {
|
|
6546
|
-
display: flex;
|
|
6547
|
-
align-items: center;
|
|
6548
|
-
gap: 8px;
|
|
6549
|
-
padding: 9px 12px;
|
|
6550
|
-
border-bottom: 1px solid var(--border-subtle);
|
|
6551
|
-
background: linear-gradient(180deg, rgba(246, 234, 216, 0.55) 0%, transparent 100%);
|
|
6552
|
-
}
|
|
6553
|
-
.queue-bar-panel-title {
|
|
6554
|
-
font-size: 0.78rem;
|
|
6555
|
-
font-weight: 600;
|
|
6556
|
-
color: var(--text-primary);
|
|
6557
|
-
flex: 1 1 auto;
|
|
6558
|
-
min-width: 0;
|
|
6559
|
-
}
|
|
6560
|
-
.queue-bar-clear,
|
|
6561
|
-
.queue-bar-collapse {
|
|
6562
|
-
display: inline-flex;
|
|
6563
|
-
align-items: center;
|
|
6564
|
-
gap: 3px;
|
|
6565
|
-
padding: 3px 9px;
|
|
6566
|
-
border: 1px solid transparent;
|
|
6567
|
-
background: transparent;
|
|
6568
|
-
cursor: pointer;
|
|
6569
|
-
font: inherit;
|
|
6570
|
-
font-size: 0.7rem;
|
|
6571
|
-
color: var(--text-tertiary);
|
|
6572
|
-
border-radius: 8px;
|
|
6573
|
-
transition: all var(--transition-fast);
|
|
6574
|
-
line-height: 1;
|
|
6575
|
-
}
|
|
6576
|
-
.queue-bar-clear:hover:not([disabled]) {
|
|
6577
|
-
color: var(--danger);
|
|
6578
|
-
background: var(--danger-muted);
|
|
6579
|
-
border-color: rgba(178, 79, 69, 0.25);
|
|
6580
|
-
}
|
|
6581
|
-
.queue-bar-clear[disabled] {
|
|
6582
|
-
opacity: 0.4;
|
|
6583
|
-
cursor: not-allowed;
|
|
6584
|
-
}
|
|
6585
|
-
.queue-bar-collapse:hover {
|
|
6586
|
-
color: var(--accent);
|
|
6587
|
-
background: var(--accent-muted);
|
|
6588
|
-
}
|
|
6589
|
-
.queue-bar-collapse svg { flex-shrink: 0; }
|
|
6590
|
-
|
|
6591
6395
|
.queue-bar-list {
|
|
6592
6396
|
list-style: none;
|
|
6593
6397
|
margin: 0;
|
|
6594
|
-
padding:
|
|
6398
|
+
padding: 0;
|
|
6595
6399
|
display: flex;
|
|
6596
6400
|
flex-direction: column;
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
flex: 1 1 auto;
|
|
6601
|
-
min-height: 0;
|
|
6401
|
+
align-items: flex-end;
|
|
6402
|
+
gap: 3px;
|
|
6403
|
+
width: 100%;
|
|
6602
6404
|
}
|
|
6603
6405
|
|
|
6406
|
+
/* 折叠态 chip:一根小横杠(橙色细线,cursor 提示"可指") */
|
|
6604
6407
|
.queue-bar-item {
|
|
6605
6408
|
display: flex;
|
|
6606
|
-
align-items:
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6409
|
+
align-items: center;
|
|
6410
|
+
justify-content: flex-end;
|
|
6411
|
+
gap: 0;
|
|
6412
|
+
height: 5px;
|
|
6413
|
+
width: 32px;
|
|
6414
|
+
padding: 0;
|
|
6415
|
+
border: none;
|
|
6416
|
+
border-radius: 999px;
|
|
6417
|
+
background: linear-gradient(180deg, var(--accent) 0%, #a8522f 100%);
|
|
6418
|
+
box-shadow: 0 1px 2px rgba(197, 101, 61, 0.25);
|
|
6419
|
+
color: #fff;
|
|
6420
|
+
cursor: pointer;
|
|
6421
|
+
overflow: hidden;
|
|
6612
6422
|
position: relative;
|
|
6613
|
-
transition:
|
|
6614
|
-
|
|
6423
|
+
transition: width 200ms cubic-bezier(0.2, 0.7, 0.2, 1),
|
|
6424
|
+
height 200ms cubic-bezier(0.2, 0.7, 0.2, 1),
|
|
6425
|
+
padding 200ms cubic-bezier(0.2, 0.7, 0.2, 1),
|
|
6426
|
+
gap 200ms cubic-bezier(0.2, 0.7, 0.2, 1),
|
|
6427
|
+
box-shadow var(--transition-fast),
|
|
6428
|
+
transform 140ms ease-out;
|
|
6615
6429
|
will-change: transform;
|
|
6430
|
+
touch-action: none; /* 防止触屏滚动抢拖拽手势 */
|
|
6616
6431
|
}
|
|
6617
6432
|
.queue-bar-item:hover {
|
|
6618
|
-
|
|
6619
|
-
|
|
6433
|
+
box-shadow: 0 2px 6px rgba(197, 101, 61, 0.42);
|
|
6434
|
+
}
|
|
6435
|
+
|
|
6436
|
+
/* 展开态:完整气泡(橙色填充 + 编号 + 文本 + × 删除) */
|
|
6437
|
+
.queue-bar-item.expanded,
|
|
6438
|
+
.queue-bar-item.dragging {
|
|
6439
|
+
width: auto;
|
|
6440
|
+
max-width: 100%;
|
|
6441
|
+
height: 24px;
|
|
6442
|
+
padding: 0 4px 0 5px;
|
|
6443
|
+
gap: 5px;
|
|
6444
|
+
box-shadow: 0 2px 6px rgba(197, 101, 61, 0.34);
|
|
6445
|
+
cursor: grab;
|
|
6620
6446
|
}
|
|
6621
6447
|
.queue-bar-item.dragging {
|
|
6622
6448
|
z-index: 5;
|
|
6623
|
-
box-shadow:
|
|
6624
|
-
background: var(--bg-elevated);
|
|
6449
|
+
box-shadow: 0 6px 16px rgba(197, 101, 61, 0.45), 0 0 0 1.5px rgba(255, 255, 255, 0.4);
|
|
6625
6450
|
transition: box-shadow var(--transition-fast); /* dragging 期间禁用 transform 过渡 */
|
|
6626
6451
|
cursor: grabbing;
|
|
6627
6452
|
}
|
|
6628
|
-
.queue-bar-item
|
|
6629
|
-
transition: transform 140ms ease-out;
|
|
6630
|
-
}
|
|
6453
|
+
.queue-bar-item.expanded:active { cursor: grabbing; }
|
|
6631
6454
|
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
color: var(--text-muted);
|
|
6640
|
-
padding: 0;
|
|
6641
|
-
display: inline-flex;
|
|
6642
|
-
align-items: center;
|
|
6643
|
-
justify-content: center;
|
|
6644
|
-
border-radius: 4px;
|
|
6645
|
-
touch-action: none; /* 不让浏览器抢走拖拽手势用作滚动 */
|
|
6646
|
-
transition: color var(--transition-fast), background var(--transition-fast);
|
|
6647
|
-
}
|
|
6648
|
-
.queue-bar-item-drag:hover { color: var(--accent); background: var(--accent-muted); }
|
|
6649
|
-
.queue-bar-item-drag:active { cursor: grabbing; }
|
|
6650
|
-
.queue-bar-item-drag[disabled] {
|
|
6651
|
-
opacity: 0.35;
|
|
6652
|
-
cursor: default;
|
|
6653
|
-
}
|
|
6654
|
-
.queue-bar-item-drag[disabled]:hover {
|
|
6655
|
-
color: var(--text-muted);
|
|
6656
|
-
background: transparent;
|
|
6657
|
-
}
|
|
6455
|
+
/* 单条排队时不必拖动 */
|
|
6456
|
+
.queue-bar-item-single { cursor: default; }
|
|
6457
|
+
.queue-bar-item-single.expanded { cursor: default; }
|
|
6458
|
+
.queue-bar-item-single.expanded:active { cursor: default; }
|
|
6459
|
+
|
|
6460
|
+
/* sibling 在被拖期间平滑回位 */
|
|
6461
|
+
.queue-bar-item-sliding { transition: transform 160ms cubic-bezier(0.2, 0.7, 0.2, 1); }
|
|
6658
6462
|
|
|
6463
|
+
/* chip 内部三件:编号 + 文本 + 删除按钮。默认折叠态全部隐起来。 */
|
|
6659
6464
|
.queue-bar-item-index {
|
|
6660
6465
|
flex-shrink: 0;
|
|
6661
|
-
font-
|
|
6662
|
-
font-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
min-width: 26px;
|
|
6466
|
+
font-size: 0.6rem;
|
|
6467
|
+
font-weight: 700;
|
|
6468
|
+
color: rgba(255, 255, 255, 0.95);
|
|
6469
|
+
background: rgba(255, 255, 255, 0.22);
|
|
6470
|
+
padding: 0 5px;
|
|
6471
|
+
height: 15px;
|
|
6472
|
+
min-width: 15px;
|
|
6473
|
+
border-radius: 999px;
|
|
6474
|
+
line-height: 15px;
|
|
6671
6475
|
text-align: center;
|
|
6476
|
+
letter-spacing: 0.02em;
|
|
6477
|
+
opacity: 0;
|
|
6478
|
+
transform: scale(0.4);
|
|
6479
|
+
transition: opacity 150ms ease, transform 180ms cubic-bezier(0.2, 0.7, 0.2, 1);
|
|
6480
|
+
pointer-events: none;
|
|
6481
|
+
}
|
|
6482
|
+
.queue-bar-item.expanded .queue-bar-item-index,
|
|
6483
|
+
.queue-bar-item.dragging .queue-bar-item-index {
|
|
6484
|
+
opacity: 1;
|
|
6485
|
+
transform: scale(1);
|
|
6672
6486
|
}
|
|
6673
6487
|
|
|
6674
6488
|
.queue-bar-item-text {
|
|
6675
6489
|
flex: 1 1 auto;
|
|
6676
6490
|
min-width: 0;
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
font-size: 0.78rem;
|
|
6682
|
-
color: var(--text-primary);
|
|
6683
|
-
text-align: left;
|
|
6684
|
-
padding: 1px 0;
|
|
6685
|
-
line-height: 1.4;
|
|
6686
|
-
display: -webkit-box;
|
|
6687
|
-
-webkit-line-clamp: 2;
|
|
6688
|
-
-webkit-box-orient: vertical;
|
|
6491
|
+
font-size: 0.7rem;
|
|
6492
|
+
color: #fff;
|
|
6493
|
+
line-height: 1;
|
|
6494
|
+
white-space: nowrap;
|
|
6689
6495
|
overflow: hidden;
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6496
|
+
text-overflow: ellipsis;
|
|
6497
|
+
letter-spacing: 0.02em;
|
|
6498
|
+
opacity: 0;
|
|
6499
|
+
transition: opacity 120ms ease 50ms;
|
|
6500
|
+
pointer-events: none;
|
|
6693
6501
|
}
|
|
6694
|
-
.queue-bar-item.expanded .queue-bar-item-text
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
max-height: 200px;
|
|
6698
|
-
overflow-y: auto;
|
|
6502
|
+
.queue-bar-item.expanded .queue-bar-item-text,
|
|
6503
|
+
.queue-bar-item.dragging .queue-bar-item-text {
|
|
6504
|
+
opacity: 1;
|
|
6699
6505
|
}
|
|
6700
|
-
.queue-bar-item-text:hover { color: var(--accent); }
|
|
6701
6506
|
|
|
6702
6507
|
.queue-bar-item-delete {
|
|
6703
6508
|
flex-shrink: 0;
|
|
6704
|
-
width:
|
|
6705
|
-
height:
|
|
6509
|
+
width: 16px;
|
|
6510
|
+
height: 16px;
|
|
6706
6511
|
border: none;
|
|
6707
|
-
background:
|
|
6512
|
+
background: rgba(255, 255, 255, 0.16);
|
|
6513
|
+
color: #fff;
|
|
6708
6514
|
cursor: pointer;
|
|
6709
|
-
|
|
6710
|
-
border-radius: 6px;
|
|
6515
|
+
border-radius: 999px;
|
|
6711
6516
|
display: inline-flex;
|
|
6712
6517
|
align-items: center;
|
|
6713
6518
|
justify-content: center;
|
|
6519
|
+
padding: 0;
|
|
6714
6520
|
opacity: 0;
|
|
6715
|
-
|
|
6716
|
-
|
|
6521
|
+
pointer-events: none;
|
|
6522
|
+
transition: opacity 120ms ease 70ms, background var(--transition-fast);
|
|
6717
6523
|
}
|
|
6718
|
-
.queue-bar-item
|
|
6719
|
-
.queue-bar-item
|
|
6524
|
+
.queue-bar-item.expanded .queue-bar-item-delete,
|
|
6525
|
+
.queue-bar-item.dragging .queue-bar-item-delete {
|
|
6720
6526
|
opacity: 1;
|
|
6527
|
+
pointer-events: auto;
|
|
6721
6528
|
}
|
|
6722
6529
|
.queue-bar-item-delete:hover {
|
|
6723
|
-
|
|
6724
|
-
|
|
6530
|
+
background: rgba(255, 255, 255, 0.34);
|
|
6531
|
+
}
|
|
6532
|
+
.queue-bar-item-delete svg { flex-shrink: 0; }
|
|
6533
|
+
|
|
6534
|
+
/* ⚡ 立即按钮 —— 独立小圆按钮,跟在列表末尾 */
|
|
6535
|
+
.queue-bar-promote {
|
|
6536
|
+
flex-shrink: 0;
|
|
6537
|
+
width: 24px;
|
|
6538
|
+
height: 24px;
|
|
6539
|
+
padding: 0;
|
|
6540
|
+
border: none;
|
|
6541
|
+
cursor: pointer;
|
|
6542
|
+
color: #fff;
|
|
6543
|
+
background: linear-gradient(180deg, var(--accent) 0%, #a8522f 100%);
|
|
6544
|
+
border-radius: 999px;
|
|
6545
|
+
display: inline-flex;
|
|
6546
|
+
align-items: center;
|
|
6547
|
+
justify-content: center;
|
|
6548
|
+
box-shadow: 0 2px 6px rgba(197, 101, 61, 0.30);
|
|
6549
|
+
transition: transform var(--transition-fast), box-shadow var(--transition-fast),
|
|
6550
|
+
background var(--transition-fast);
|
|
6551
|
+
animation: queuePulse 1.5s ease-in-out infinite;
|
|
6552
|
+
}
|
|
6553
|
+
.queue-bar-promote:hover {
|
|
6554
|
+
transform: translateY(-1px);
|
|
6555
|
+
box-shadow: 0 3px 10px rgba(197, 101, 61, 0.45);
|
|
6556
|
+
}
|
|
6557
|
+
.queue-bar-promote:active { transform: scale(0.94); }
|
|
6558
|
+
.queue-bar-promote:focus-visible {
|
|
6559
|
+
outline: 2px solid var(--border-focus);
|
|
6560
|
+
outline-offset: 2px;
|
|
6561
|
+
}
|
|
6562
|
+
.queue-bar-promote svg { flex-shrink: 0; }
|
|
6563
|
+
.queue-bar-promote-label { display: none; } /* label 留作 aria,视觉不展示 */
|
|
6564
|
+
|
|
6565
|
+
/* 容量满了的视觉提示 —— 整组颜色稍暗 */
|
|
6566
|
+
.queue-bar.queue-bar-capacity .queue-bar-item,
|
|
6567
|
+
.queue-bar.queue-bar-capacity .queue-bar-promote {
|
|
6568
|
+
background: linear-gradient(180deg, #a8522f 0%, #8e4426 100%);
|
|
6725
6569
|
}
|
|
6726
6570
|
|
|
6727
|
-
/* 窄屏:
|
|
6571
|
+
/* 窄屏:max-width 适配视口;横杠加宽方便指 */
|
|
6728
6572
|
@media (max-width: 560px) {
|
|
6729
|
-
.queue-bar-host { padding:
|
|
6730
|
-
.queue-bar { width:
|
|
6731
|
-
.queue-bar-
|
|
6732
|
-
.queue-bar-sep { display: none; }
|
|
6733
|
-
.queue-bar-item-delete { opacity: 1; }
|
|
6734
|
-
.queue-bar-panel { width: calc(100vw - 16px); right: -2px; }
|
|
6573
|
+
.queue-bar-host { padding: 4px 6px 0; }
|
|
6574
|
+
.queue-bar { max-width: calc(100vw - 20px); }
|
|
6575
|
+
.queue-bar-item { width: 40px; height: 6px; }
|
|
6735
6576
|
}
|
|
6736
6577
|
|
|
6737
6578
|
/* Queued message in chat view:用户最容易"觉得排队没生效"是因为旧版徽章太小。
|
|
@@ -10353,7 +10194,11 @@
|
|
|
10353
10194
|
.chat-container {
|
|
10354
10195
|
min-height: 0;
|
|
10355
10196
|
flex: 1 1 auto;
|
|
10356
|
-
|
|
10197
|
+
/* 注意:这里必须 hidden,不能 auto——内部的 .inline-terminal /
|
|
10198
|
+
.tool-use-card 默认 max-width: 720px,如果 chat-container 允许
|
|
10199
|
+
横向滚动,这些卡片会把整个容器推宽,结果窄屏看到右边内容被屏幕
|
|
10200
|
+
边缘截掉。垂直滚动由内层 .chat-messages (overflow-y: auto) 负责。 */
|
|
10201
|
+
overflow: hidden;
|
|
10357
10202
|
display: none;
|
|
10358
10203
|
flex-direction: column;
|
|
10359
10204
|
}
|
|
@@ -15753,14 +15598,6 @@
|
|
|
15753
15598
|
/* 附件 pill 缩略图 svg */
|
|
15754
15599
|
.attachment-pill .att-icon > svg { display: block; }
|
|
15755
15600
|
|
|
15756
|
-
/* 排队面板标题 (排队中) —— 现在 icon + text 用 inline-flex 排 */
|
|
15757
|
-
.queue-bar-panel-title {
|
|
15758
|
-
display: inline-flex;
|
|
15759
|
-
align-items: center;
|
|
15760
|
-
gap: 5px;
|
|
15761
|
-
}
|
|
15762
|
-
.queue-bar-panel-title-icon { flex-shrink: 0; }
|
|
15763
|
-
|
|
15764
15601
|
/* 紧凑目录选择器(新建会话时显示的小条)的图标 + 折叠箭头 */
|
|
15765
15602
|
.folder-picker-compact-icon {
|
|
15766
15603
|
display: inline-flex;
|
package/dist/ws-broadcast.d.ts
CHANGED
|
@@ -12,7 +12,8 @@ export declare class WsBroadcastManager {
|
|
|
12
12
|
private eventEmitter;
|
|
13
13
|
private heartbeatTimer?;
|
|
14
14
|
private getCardDefaults;
|
|
15
|
-
|
|
15
|
+
private useHttps;
|
|
16
|
+
constructor(wss: WebSocketServer, getCardDefaults?: () => CardExpandDefaults, useHttps?: boolean);
|
|
16
17
|
/** Set up connection handling. Should be called once during server startup. */
|
|
17
18
|
setup(getSession: (id: string) => SessionSnapshot | null): void;
|
|
18
19
|
/**
|
|
@@ -36,5 +37,4 @@ export declare class WsBroadcastManager {
|
|
|
36
37
|
private sendInit;
|
|
37
38
|
private broadcast;
|
|
38
39
|
private processWsQueue;
|
|
39
|
-
private readSessionCookie;
|
|
40
40
|
}
|
package/dist/ws-broadcast.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { WebSocket } from "ws";
|
|
6
6
|
import { EventEmitter } from "node:events";
|
|
7
|
-
import { validateSession } from "./auth.js";
|
|
7
|
+
import { readSessionCookie, validateSession } from "./auth.js";
|
|
8
8
|
import { truncateMessagesForTransport } from "./message-truncator.js";
|
|
9
9
|
// ── Constants ──
|
|
10
10
|
const MAX_QUEUE_SIZE = 500;
|
|
@@ -28,14 +28,16 @@ export class WsBroadcastManager {
|
|
|
28
28
|
eventEmitter = new EventEmitter();
|
|
29
29
|
heartbeatTimer;
|
|
30
30
|
getCardDefaults;
|
|
31
|
-
|
|
31
|
+
useHttps;
|
|
32
|
+
constructor(wss, getCardDefaults, useHttps = false) {
|
|
32
33
|
this.wss = wss;
|
|
33
34
|
this.getCardDefaults = getCardDefaults ?? (() => ({}));
|
|
35
|
+
this.useHttps = useHttps;
|
|
34
36
|
}
|
|
35
37
|
/** Set up connection handling. Should be called once during server startup. */
|
|
36
38
|
setup(getSession) {
|
|
37
39
|
this.wss.on("connection", (ws, req) => {
|
|
38
|
-
const sessionToken =
|
|
40
|
+
const sessionToken = readSessionCookie(req, this.useHttps);
|
|
39
41
|
if (!sessionToken || !validateSession(sessionToken)) {
|
|
40
42
|
ws.close(1008, "Unauthorized");
|
|
41
43
|
return;
|
|
@@ -308,11 +310,4 @@ export class WsBroadcastManager {
|
|
|
308
310
|
});
|
|
309
311
|
}
|
|
310
312
|
}
|
|
311
|
-
readSessionCookie(req) {
|
|
312
|
-
const cookie = req.headers.cookie;
|
|
313
|
-
if (!cookie)
|
|
314
|
-
return undefined;
|
|
315
|
-
const match = cookie.split(";").map((part) => part.trim()).find((part) => part.startsWith("wand_session="));
|
|
316
|
-
return match?.slice("wand_session=".length);
|
|
317
|
-
}
|
|
318
313
|
}
|