dsh-project-room 0.2.6 → 0.2.8
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/client.js +140 -75
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -303,42 +303,42 @@ window.__ModuleLoader__.load({
|
|
|
303
303
|
flex: 1; min-width: 0; height: 22px; box-sizing: border-box; padding: 0 6px;
|
|
304
304
|
border-radius: 6px; border: 1px solid var(--dsw-alias-border-l1);
|
|
305
305
|
background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary);
|
|
306
|
-
font-size:
|
|
306
|
+
font-size: calc(11px + var(--dsh-content-font-delta, 0px)); outline: none;
|
|
307
307
|
}
|
|
308
308
|
.pr-head { display: flex; align-items: center; gap: 6px; padding: 2px 6px 4px; flex: 0 0 auto; }
|
|
309
|
-
.pr-head-title { font-size:
|
|
310
|
-
.pr-head-count { font-size:
|
|
309
|
+
.pr-head-title { font-size: calc(11.5px + var(--dsh-content-font-delta, 0px)); letter-spacing: 0.04em; font-weight: 600; color: var(--dsw-alias-label-secondary); }
|
|
310
|
+
.pr-head-count { font-size: calc(10px + var(--dsh-content-font-delta, 0px)); color: var(--dsw-alias-label-secondary); opacity: .75; margin-left: auto; }
|
|
311
311
|
/* 「未分组」那一行:折叠按钮 + 清理按钮 */
|
|
312
312
|
.pr-loose-row { display: flex; gap: 4px; align-items: center; padding: 0 6px 6px; flex: 0 0 auto; }
|
|
313
313
|
.pr-loose-toggle {
|
|
314
314
|
padding: 1px 6px;
|
|
315
315
|
border: 1px solid var(--dsw-alias-border-l1); border-radius: 6px;
|
|
316
316
|
background: transparent; color: var(--dsw-alias-label-secondary);
|
|
317
|
-
font-size:
|
|
317
|
+
font-size: calc(10px + var(--dsh-content-font-delta, 0px)); line-height: 1.6; cursor: pointer; flex: 0 0 auto;
|
|
318
318
|
}
|
|
319
319
|
.pr-loose-toggle:hover { background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-primary); }
|
|
320
320
|
.pr-chip-badge {
|
|
321
321
|
flex: 0 0 auto; min-width: 14px; height: 14px; padding: 0 3px; border-radius: 7px;
|
|
322
322
|
display: inline-flex; align-items: center; justify-content: center;
|
|
323
323
|
background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-secondary);
|
|
324
|
-
font-size:
|
|
324
|
+
font-size: calc(9px + var(--dsh-content-font-delta, 0px)); line-height: 1; font-variant-numeric: tabular-nums;
|
|
325
325
|
}
|
|
326
|
-
.pr-chip-elapsed { flex: 0 0 auto; font-size:
|
|
326
|
+
.pr-chip-elapsed { flex: 0 0 auto; font-size: calc(9px + var(--dsh-content-font-delta, 0px)); line-height: 1; font-variant-numeric: tabular-nums; color: var(--dsw-alias-state-success-primary); }
|
|
327
327
|
/* 分身子行:树状(├ / └ 竖线缩进) */
|
|
328
328
|
.pr-chip-clones { display: flex; flex-direction: column; gap: 1px; margin-top: 1px; padding-left: 0; }
|
|
329
329
|
.pr-clone-row {
|
|
330
330
|
display: flex; align-items: center; gap: 3px;
|
|
331
|
-
font-size:
|
|
331
|
+
font-size: calc(9.5px + var(--dsh-content-font-delta, 0px)); line-height: 1.5; color: var(--dsw-alias-label-secondary);
|
|
332
332
|
cursor: pointer; border-radius: 3px; padding: 0;
|
|
333
333
|
}
|
|
334
334
|
.pr-clone-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,0.06)); color: var(--dsw-alias-label-primary); }
|
|
335
|
-
.pr-tree-rail { flex: 0 0 auto; width: 7px; color: var(--dsw-alias-border-l2, #4a4a4a); font-size:
|
|
335
|
+
.pr-tree-rail { flex: 0 0 auto; width: 7px; color: var(--dsw-alias-border-l2, #4a4a4a); font-size: calc(9px + var(--dsh-content-font-delta, 0px)); line-height: 1.5; }
|
|
336
336
|
.pr-clone-dot { flex: 0 0 auto; width: 5px; height: 5px; border-radius: 50%; background: transparent; box-shadow: inset 0 0 0 1px var(--dsw-alias-label-secondary); }
|
|
337
337
|
.pr-clone-dot.on { background: var(--dsw-alias-state-success-primary, #4ade80); box-shadow: none; }
|
|
338
338
|
/* 同理:分身子行名不再 ellipsis,长任务名完整显示(行高会自动撑开)。 */
|
|
339
339
|
.pr-clone-name { min-width: 0; white-space: normal; overflow-wrap: anywhere; word-break: break-word; }
|
|
340
340
|
.pr-clone-elapsed {
|
|
341
|
-
flex: 0 0 auto; margin-left: 3px; font-size:
|
|
341
|
+
flex: 0 0 auto; margin-left: 3px; font-size: calc(9px + var(--dsh-content-font-delta, 0px)); line-height: 1;
|
|
342
342
|
font-variant-numeric: tabular-nums;
|
|
343
343
|
color: var(--dsw-alias-state-success-primary);
|
|
344
344
|
}
|
|
@@ -347,31 +347,31 @@ window.__ModuleLoader__.load({
|
|
|
347
347
|
position: fixed; z-index: 1000; min-width: 168px; padding: 4px;
|
|
348
348
|
border-radius: 8px; border: 1px solid var(--dsw-alias-border-l2);
|
|
349
349
|
background: var(--dsw-alias-bg-layer-2); box-shadow: 0 12px 32px rgba(0,0,0,.45);
|
|
350
|
-
font-size:
|
|
350
|
+
font-size: calc(12px + var(--dsh-content-font-delta, 0px));
|
|
351
351
|
}
|
|
352
352
|
.pr-menu-item {
|
|
353
353
|
display: block; width: 100%; text-align: left; padding: 5px 8px; border: none; border-radius: 5px;
|
|
354
|
-
background: transparent; color: var(--dsw-alias-label-primary); font: inherit; font-size:
|
|
354
|
+
background: transparent; color: var(--dsw-alias-label-primary); font: inherit; font-size: calc(12px + var(--dsh-content-font-delta, 0px)); cursor: pointer;
|
|
355
355
|
}
|
|
356
356
|
.pr-menu-item:hover { background: var(--dsw-alias-bg-layer-1); }
|
|
357
|
-
.pr-menu-msg { padding: 4px 8px; font-size:
|
|
357
|
+
.pr-menu-msg { padding: 4px 8px; font-size: calc(10.5px + var(--dsh-content-font-delta, 0px)); color: var(--dsw-alias-label-secondary); }
|
|
358
358
|
.pr-modal { position: fixed; inset: 0; z-index: 1001; display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,.45); }
|
|
359
|
-
.pr-modal-box { width: min(420px, 88vw); padding: 14px; border-radius: 10px; background: var(--dsw-alias-bg-base); border: 1px solid var(--dsw-alias-border-l2); }
|
|
360
|
-
.pr-modal-title { font-size:
|
|
361
|
-
.pr-modal-input { width: 100%; box-sizing: border-box; height: 30px; padding: 0 8px; border-radius: 6px; border: 1px solid var(--dsw-alias-border-l1); background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); font-size:
|
|
359
|
+
.pr-modal-box { width: min(420px, 88vw); padding: 14px; border-radius: 10px; background-color: #141a1b; background-image: linear-gradient(var(--dsw-alias-bg-base), var(--dsw-alias-bg-base)); border: 1px solid var(--dsw-alias-border-l2); box-shadow: 0 18px 48px rgba(0,0,0,.5); }
|
|
360
|
+
.pr-modal-title { font-size: calc(13px + var(--dsh-content-font-delta, 0px)); font-weight: 600; margin-bottom: 8px; }
|
|
361
|
+
.pr-modal-input { width: 100%; box-sizing: border-box; height: 30px; padding: 0 8px; border-radius: 6px; border: 1px solid var(--dsw-alias-border-l1); background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); font-size: calc(12.5px + var(--dsh-content-font-delta, 0px)); outline: none; }
|
|
362
362
|
.pr-modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
|
|
363
363
|
/* 头部「+ 新项目」按钮 */
|
|
364
364
|
.pr-new-btn {
|
|
365
365
|
flex: 0 0 auto; height: 18px; padding: 0 6px; border-radius: 5px;
|
|
366
366
|
border: 1px solid var(--dsw-alias-border-l1); background: transparent;
|
|
367
|
-
color: var(--dsw-alias-label-secondary); font-size:
|
|
367
|
+
color: var(--dsw-alias-label-secondary); font-size: calc(10px + var(--dsh-content-font-delta, 0px)); line-height: 1; cursor: pointer;
|
|
368
368
|
}
|
|
369
369
|
.pr-new-btn:hover { background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-primary); }
|
|
370
370
|
/* 房间关闭按钮:显式带文字,避免全屏遮罩下只剩一个小图标找不着 */
|
|
371
371
|
.pr-close-btn {
|
|
372
372
|
flex: 0 0 auto; height: 22px; padding: 0 10px; border-radius: 6px;
|
|
373
373
|
border: 1px solid var(--dsw-alias-border-l2); background: var(--dsw-alias-bg-layer-2);
|
|
374
|
-
color: var(--dsw-alias-label-primary); font-size:
|
|
374
|
+
color: var(--dsw-alias-label-primary); font-size: calc(11.5px + var(--dsh-content-font-delta, 0px)); line-height: 1; cursor: pointer;
|
|
375
375
|
}
|
|
376
376
|
.pr-close-btn:hover { border-color: var(--dsw-alias-brand-primary); }
|
|
377
377
|
/* 一页三段布局 */
|
|
@@ -396,11 +396,11 @@ window.__ModuleLoader__.load({
|
|
|
396
396
|
.pr-section { margin-bottom: 16px; }
|
|
397
397
|
.pr-section:last-child { margin-bottom: 4px; }
|
|
398
398
|
.pr-section-title {
|
|
399
|
-
font-size:
|
|
399
|
+
font-size: calc(11px + var(--dsh-content-font-delta, 0px)); font-weight: 700; letter-spacing: .06em;
|
|
400
400
|
color: var(--dsw-alias-label-secondary); text-transform: uppercase;
|
|
401
401
|
margin-bottom: 6px;
|
|
402
402
|
}
|
|
403
|
-
.pr-loose-msg { font-size:
|
|
403
|
+
.pr-loose-msg { font-size: calc(10px + var(--dsh-content-font-delta, 0px)); color: var(--dsw-alias-label-secondary); padding: 0 6px 6px; line-height: 1.5; flex: 0 0 auto; }
|
|
404
404
|
|
|
405
405
|
/* 运行中快捷栏(对齐 AI-Agent-Hub):两段竖排 —— 上「运行中」、下「完成未读」 */
|
|
406
406
|
.pr-runbar { display: flex; flex-direction: column; gap: 4px; padding: 2px 4px 6px; flex: 0 0 auto; min-width: 0; }
|
|
@@ -413,7 +413,7 @@ window.__ModuleLoader__.load({
|
|
|
413
413
|
}
|
|
414
414
|
.pr-runbar-sec-title {
|
|
415
415
|
display: flex; align-items: center; gap: 4px; min-width: 0;
|
|
416
|
-
padding: 0 2px; font-size:
|
|
416
|
+
padding: 0 2px; font-size: calc(9px + var(--dsh-content-font-delta, 0px)); line-height: 1.4;
|
|
417
417
|
color: var(--dsw-alias-label-secondary); letter-spacing: .03em;
|
|
418
418
|
}
|
|
419
419
|
.pr-runbar-sec[data-kind="done"] .pr-runbar-sec-title { color: #d97757; }
|
|
@@ -425,7 +425,7 @@ window.__ModuleLoader__.load({
|
|
|
425
425
|
width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto;
|
|
426
426
|
display: inline-flex; align-items: center; justify-content: center;
|
|
427
427
|
background: #d97757; color: #fff;
|
|
428
|
-
font-size:
|
|
428
|
+
font-size: calc(8px + var(--dsh-content-font-delta, 0px)); font-weight: 700; line-height: 1;
|
|
429
429
|
}
|
|
430
430
|
.pr-runbar-sec-label { flex: 0 0 auto; white-space: nowrap; }
|
|
431
431
|
.pr-runbar-sec-count {
|
|
@@ -436,12 +436,12 @@ window.__ModuleLoader__.load({
|
|
|
436
436
|
子行样式与侧栏芯片的 pr-clone-row / pr-tree-rail 完全一致。 */
|
|
437
437
|
.pr-run-wrap { display: inline-flex; flex-direction: column; gap: 1px; align-items: flex-start; }
|
|
438
438
|
.pr-run-clones { display: flex; flex-direction: column; gap: 1px; padding-left: 6px; margin: 0 0 1px; }
|
|
439
|
-
.pr-run-clones .pr-clone-row { font-size:
|
|
439
|
+
.pr-run-clones .pr-clone-row { font-size: calc(9px + var(--dsh-content-font-delta, 0px)); line-height: 1.4; }
|
|
440
440
|
.pr-readall {
|
|
441
441
|
/* 2026-11-11:一键已读搬进「完成未读」区的小标题里,靠右对齐 */
|
|
442
442
|
flex: 0 0 auto; margin: 0 0 0 auto; padding: 1px 6px; border-radius: 8px;
|
|
443
443
|
border: 1px solid var(--dsw-alias-border-l1); background: transparent;
|
|
444
|
-
color: #d97757; font-size:
|
|
444
|
+
color: #d97757; font-size: calc(9.5px + var(--dsh-content-font-delta, 0px)); line-height: 1.4;
|
|
445
445
|
white-space: nowrap; cursor: pointer;
|
|
446
446
|
}
|
|
447
447
|
.pr-readall:hover { background: var(--dsw-alias-bg-layer-2); }
|
|
@@ -451,7 +451,7 @@ window.__ModuleLoader__.load({
|
|
|
451
451
|
min-height: 20px; padding: 2px 7px 2px 3px; border-radius: 11px;
|
|
452
452
|
border: 1px solid transparent; background: transparent;
|
|
453
453
|
color: var(--dsw-alias-label-secondary);
|
|
454
|
-
font: inherit; font-size:
|
|
454
|
+
font: inherit; font-size: calc(11.5px + var(--dsh-content-font-delta, 0px)); line-height: 1.2; white-space: nowrap; cursor: pointer;
|
|
455
455
|
}
|
|
456
456
|
.pr-run-pill:hover { background: var(--dsw-alias-bg-layer-1); }
|
|
457
457
|
.pr-run-pill[data-active="1"] {
|
|
@@ -462,28 +462,28 @@ window.__ModuleLoader__.load({
|
|
|
462
462
|
.pr-run-avatar { width: 16px; height: 16px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; line-height: 1; }
|
|
463
463
|
.pr-run-project { display: inline-flex; align-items: center; gap: 3px; flex: 0 0 auto; min-width: 0; }
|
|
464
464
|
.pr-run-project-dot { width: 6px; height: 6px; border-radius: 2px; flex: 0 0 auto; }
|
|
465
|
-
.pr-run-project-name { font-size:
|
|
465
|
+
.pr-run-project-name { font-size: calc(9px + var(--dsh-content-font-delta, 0px)); line-height: 1; font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
466
466
|
/* 2026-11-09 用户令「标题要显示全」:快捷栏 pill 名字原来 nowrap+ellipsis 会被吃掉,改为可换行。 */
|
|
467
467
|
.pr-run-name { min-width: 0; flex: 0 1 auto; white-space: normal; overflow-wrap: anywhere; word-break: break-word; }
|
|
468
468
|
.pr-run-badge {
|
|
469
469
|
flex: 0 0 auto; min-width: 14px; height: 14px; padding: 0 3px; border-radius: 7px;
|
|
470
470
|
display: inline-flex; align-items: center; justify-content: center;
|
|
471
471
|
background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-secondary);
|
|
472
|
-
font-size:
|
|
472
|
+
font-size: calc(9px + var(--dsh-content-font-delta, 0px)); line-height: 1; font-variant-numeric: tabular-nums;
|
|
473
473
|
}
|
|
474
|
-
.pr-run-done { display: inline-flex; align-items: center; gap: 3px; flex: 0 0 auto; font-size:
|
|
474
|
+
.pr-run-done { display: inline-flex; align-items: center; gap: 3px; flex: 0 0 auto; font-size: calc(9px + var(--dsh-content-font-delta, 0px)); line-height: 1; color: var(--dsw-alias-brand-primary); }
|
|
475
475
|
.pr-run-check {
|
|
476
476
|
width: 10px; height: 10px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
|
|
477
|
-
background: #d97757; color: #fff; font-size:
|
|
477
|
+
background: #d97757; color: #fff; font-size: calc(8px + var(--dsh-content-font-delta, 0px)); font-weight: 700; line-height: 1;
|
|
478
478
|
}
|
|
479
|
-
.pr-run-elapsed { flex: 0 0 auto; font-size:
|
|
479
|
+
.pr-run-elapsed { flex: 0 0 auto; font-size: calc(9px + var(--dsh-content-font-delta, 0px)); line-height: 1; font-variant-numeric: tabular-nums; color: var(--dsw-alias-state-success-primary); }
|
|
480
480
|
|
|
481
481
|
/* 项目行:22px 紧凑行高 + 顶部细线,读起来像「项目」而不是一行会话 */
|
|
482
482
|
.pr-proj {
|
|
483
483
|
display: flex; align-items: center; gap: 6px;
|
|
484
484
|
height: 22px; min-height: 22px; padding: 0 6px;
|
|
485
485
|
margin-top: 6px; border-radius: 6px;
|
|
486
|
-
font-size:
|
|
486
|
+
font-size: calc(12px + var(--dsh-content-font-delta, 0px)); font-weight: 600;
|
|
487
487
|
box-shadow: inset 0 1px 0 var(--dsw-alias-border-l1);
|
|
488
488
|
cursor: pointer; overflow: hidden;
|
|
489
489
|
}
|
|
@@ -492,11 +492,11 @@ window.__ModuleLoader__.load({
|
|
|
492
492
|
.pr-dot { width: 6px; height: 6px; border-radius: 2px; flex: 0 0 auto; }
|
|
493
493
|
.pr-proj-name { flex: 0 1 auto; max-width: 100%; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
494
494
|
.pr-spacer { flex: 1 1 auto; min-width: 4px; }
|
|
495
|
-
.pr-meta { font-size:
|
|
495
|
+
.pr-meta { font-size: calc(10px + var(--dsh-content-font-delta, 0px)); font-weight: 500; color: var(--dsw-alias-label-secondary); flex: 0 0 auto; font-variant-numeric: tabular-nums; }
|
|
496
496
|
.pr-icon-btn {
|
|
497
497
|
width: 18px; height: 18px; flex: 0 0 auto; border: none; padding: 0; border-radius: 5px;
|
|
498
498
|
background: transparent; color: var(--dsw-alias-label-secondary);
|
|
499
|
-
cursor: pointer; font-size:
|
|
499
|
+
cursor: pointer; font-size: calc(10px + var(--dsh-content-font-delta, 0px)); line-height: 1;
|
|
500
500
|
}
|
|
501
501
|
.pr-icon-btn:hover { background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-primary); }
|
|
502
502
|
/* 图钉:默认隐藏,悬停显形;已置顶常显 */
|
|
@@ -519,7 +519,7 @@ window.__ModuleLoader__.load({
|
|
|
519
519
|
padding: 0; border-radius: 11px;
|
|
520
520
|
border: 1px solid transparent; background: transparent;
|
|
521
521
|
color: var(--dsw-alias-label-secondary);
|
|
522
|
-
font: inherit; font-size:
|
|
522
|
+
font: inherit; font-size: calc(11.5px + var(--dsh-content-font-delta, 0px)); line-height: 1.2;
|
|
523
523
|
cursor: pointer; box-sizing: border-box; overflow-wrap: anywhere;
|
|
524
524
|
}
|
|
525
525
|
/* 本体那一行(头像 + 名字 + badge + 圆点 + 时长):单独成盒,选中背景只作用在它上面 */
|
|
@@ -579,25 +579,25 @@ window.__ModuleLoader__.load({
|
|
|
579
579
|
100% { transform: scale(1); opacity: 1; box-shadow: 0 0 0 0 transparent; }
|
|
580
580
|
}
|
|
581
581
|
.pr-running-dot { width: 6px; height: 6px; border-radius: 50%; flex: 0 0 auto; background: var(--dsw-alias-state-success-primary); animation: pr-pulse 1.4s ease-in-out infinite; }
|
|
582
|
-
.pr-empty { padding: 10px 8px; font-size:
|
|
582
|
+
.pr-empty { padding: 10px 8px; font-size: calc(11px + var(--dsh-content-font-delta, 0px)); color: var(--dsw-alias-label-secondary); text-align: center; }
|
|
583
583
|
|
|
584
584
|
/* 房间浮层 */
|
|
585
585
|
.pr-overlay { position: fixed; z-index: 900; display: flex; flex-direction: column; background: var(--dsw-alias-bg-base); border-left: 1px solid var(--dsw-alias-border-l1); }
|
|
586
586
|
.pr-panel { width: 100%; height: 100%; display: flex; flex-direction: column; background: var(--dsw-alias-bg-base); }
|
|
587
587
|
.pr-panel-head { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-bottom: 1px solid var(--dsw-alias-border-l1); }
|
|
588
|
-
.pr-panel-title { font-size:
|
|
588
|
+
.pr-panel-title { font-size: calc(13px + var(--dsh-content-font-delta, 0px)); font-weight: 700; }/* 2026-11-10 用户令「群聊页字体太大」:14px→13px,与分区标题/正文一起收一档 */
|
|
589
589
|
.pr-tabs { display: flex; gap: 2px; margin-left: 10px; }
|
|
590
|
-
.pr-tab { padding: 3px 10px; border-radius: 6px; border: none; background: transparent; color: var(--dsw-alias-label-secondary); font-size:
|
|
590
|
+
.pr-tab { padding: 3px 10px; border-radius: 6px; border: none; background: transparent; color: var(--dsw-alias-label-secondary); font-size: calc(12px + var(--dsh-content-font-delta, 0px)); cursor: pointer; }
|
|
591
591
|
.pr-tab.on { background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-primary); font-weight: 600; }
|
|
592
592
|
.pr-panel-body { flex: 1; min-height: 0; overflow: hidden; padding: 12px 14px; display: flex; flex-direction: column; }
|
|
593
593
|
.pr-panel-foot { border-top: 1px solid var(--dsw-alias-border-l1); padding: 8px 14px; display: flex; gap: 8px; align-items: flex-end; }
|
|
594
|
-
.pr-textarea { flex: 1; min-height: 34px; max-height: 120px; resize: vertical; padding: 6px 8px; border-radius: 6px; border: 1px solid var(--dsw-alias-border-l1); background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); font-size:
|
|
595
|
-
.pr-btn { padding: 6px 12px; border-radius: 6px; border: 1px solid var(--dsw-alias-border-l2); background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-primary); font-size:
|
|
594
|
+
.pr-textarea { flex: 1; min-height: 34px; max-height: 120px; resize: vertical; padding: 6px 8px; border-radius: 6px; border: 1px solid var(--dsw-alias-border-l1); background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); font-size: calc(12px + var(--dsh-content-font-delta, 0px)); font-family: inherit; outline: none; }
|
|
595
|
+
.pr-btn { padding: 6px 12px; border-radius: 6px; border: 1px solid var(--dsw-alias-border-l2); background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-primary); font-size: calc(12px + var(--dsh-content-font-delta, 0px)); cursor: pointer; white-space: nowrap; }
|
|
596
596
|
.pr-btn:hover { border-color: var(--dsw-alias-brand-primary); }
|
|
597
597
|
.pr-btn.primary { background: var(--dsw-alias-brand-primary); border-color: var(--dsw-alias-brand-primary); color: #08111a; font-weight: 600; }
|
|
598
598
|
.pr-btn:disabled { opacity: .5; cursor: default; }
|
|
599
|
-
.pr-board { width: 100%; min-height: 200px; resize: vertical; padding: 10px; border-radius: 8px; border: 1px solid var(--dsw-alias-border-l1); background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); font-size:
|
|
600
|
-
.pr-todo { display: flex; align-items: center; gap: 8px; padding: 5px 0; border-bottom: 1px dashed var(--dsw-alias-border-l1); font-size:
|
|
599
|
+
.pr-board { width: 100%; min-height: 200px; resize: vertical; padding: 10px; border-radius: 8px; border: 1px solid var(--dsw-alias-border-l1); background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); font-size: calc(12.5px + var(--dsh-content-font-delta, 0px)); line-height: 1.6; font-family: ui-monospace, SFMono-Regular, Consolas, monospace; outline: none; }
|
|
600
|
+
.pr-todo { display: flex; align-items: center; gap: 8px; padding: 5px 0; border-bottom: 1px dashed var(--dsw-alias-border-l1); font-size: calc(12.5px + var(--dsh-content-font-delta, 0px)); }
|
|
601
601
|
.pr-todo input[type=checkbox] { flex: 0 0 auto; }
|
|
602
602
|
.pr-todo-text { flex: 1; min-width: 0; }
|
|
603
603
|
.pr-todo.done .pr-todo-text { text-decoration: line-through; opacity: .55; }
|
|
@@ -619,7 +619,7 @@ window.__ModuleLoader__.load({
|
|
|
619
619
|
display: flex; align-items: flex-start; gap: 5px; padding: 5px 8px;
|
|
620
620
|
border-bottom: 1px solid var(--dsw-alias-border-l1);
|
|
621
621
|
background: var(--dsw-alias-bg-layer-2);
|
|
622
|
-
font-size:
|
|
622
|
+
font-size: calc(11.5px + var(--dsh-content-font-delta, 0px)); font-weight: 600;/* 2026-11-09 用户令:lane 标题完整显示 */
|
|
623
623
|
}
|
|
624
624
|
/* ⚠️ 2026-11-10 补回上面这条规则的收尾花括号:58ca983 改 lane 标题换行时把块尾的 } 弄丢了,
|
|
625
625
|
浏览器(Chrome 120+ 支持 CSS 嵌套)会把 .pr-lane-name 之后的**全部规则**当成
|
|
@@ -629,7 +629,7 @@ window.__ModuleLoader__.load({
|
|
|
629
629
|
.pr-lane-archive {
|
|
630
630
|
margin-left: auto; flex: 0 0 auto; height: 18px; padding: 0 6px; border-radius: 5px;
|
|
631
631
|
border: 1px solid transparent; background: transparent;
|
|
632
|
-
color: var(--dsw-alias-label-secondary); font-size:
|
|
632
|
+
color: var(--dsw-alias-label-secondary); font-size: calc(10px + var(--dsh-content-font-delta, 0px)); line-height: 1; cursor: pointer;
|
|
633
633
|
}
|
|
634
634
|
.pr-lane-archive:hover {
|
|
635
635
|
border-color: var(--dsw-alias-border-l2); background: var(--dsw-alias-bg-layer-1);
|
|
@@ -637,13 +637,13 @@ window.__ModuleLoader__.load({
|
|
|
637
637
|
}
|
|
638
638
|
.pr-lane-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
|
|
639
639
|
.pr-lane-sub {
|
|
640
|
-
padding: 0 8px 4px; font-size:
|
|
640
|
+
padding: 0 8px 4px; font-size: calc(9.5px + var(--dsh-content-font-delta, 0px)); color: var(--dsw-alias-label-secondary);
|
|
641
641
|
border-bottom: 1px solid var(--dsw-alias-border-l1);
|
|
642
642
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
643
643
|
}
|
|
644
644
|
.pr-lane-body { flex: 1; min-height: 90px; max-height: 210px; overflow-y: auto; padding: 6px; display: flex; flex-direction: column; gap: 5px; }
|
|
645
645
|
.pr-lane-msg {
|
|
646
|
-
font-size:
|
|
646
|
+
font-size: calc(11px + var(--dsh-content-font-delta, 0px)); line-height: 1.4; color: var(--dsw-alias-label-primary);
|
|
647
647
|
background: var(--dsw-alias-bg-base); border-radius: 6px; padding: 4px 6px;
|
|
648
648
|
display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
|
|
649
649
|
white-space: pre-wrap; word-break: break-word;
|
|
@@ -656,25 +656,25 @@ window.__ModuleLoader__.load({
|
|
|
656
656
|
/* 看板:渲染视图(纵向滚动)+ 编辑切换 */
|
|
657
657
|
.pr-board-section { display: flex; flex-direction: column; min-height: 0; }
|
|
658
658
|
.pr-section-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
|
|
659
|
-
.pr-board-toggle { height: 22px; padding: 0 9px; font-size:
|
|
659
|
+
.pr-board-toggle { height: 22px; padding: 0 9px; font-size: calc(11px + var(--dsh-content-font-delta, 0px)); }
|
|
660
660
|
.pr-board-count {
|
|
661
|
-
margin-left: auto; font-size:
|
|
661
|
+
margin-left: auto; font-size: calc(10px + var(--dsh-content-font-delta, 0px)); color: var(--dsw-alias-label-secondary);
|
|
662
662
|
font-variant-numeric: tabular-nums; white-space: nowrap;
|
|
663
663
|
}
|
|
664
664
|
.pr-md-view {
|
|
665
665
|
flex: 1; min-height: 120px; max-height: 42vh; overflow-y: auto;
|
|
666
666
|
padding: 8px 10px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 8px;
|
|
667
|
-
background: var(--dsw-alias-bg-layer-1); font-size:
|
|
667
|
+
background: var(--dsw-alias-bg-layer-1); font-size: calc(12px + var(--dsh-content-font-delta, 0px)); line-height: 1.55;
|
|
668
668
|
word-break: break-word;
|
|
669
669
|
}
|
|
670
|
-
.pr-md-h { margin: 6px 0 4px; font-size:
|
|
670
|
+
.pr-md-h { margin: 6px 0 4px; font-size: calc(12.5px + var(--dsh-content-font-delta, 0px)); font-weight: 700; color: var(--dsw-alias-label-primary); }
|
|
671
671
|
.pr-md-h:first-child { margin-top: 0; }
|
|
672
672
|
.pr-md-p { margin: 2px 0; color: var(--dsw-alias-label-primary); white-space: pre-wrap; }
|
|
673
673
|
.pr-md-ul { margin: 3px 0; padding-left: 16px; }
|
|
674
674
|
.pr-md-ul li { margin: 1px 0; }
|
|
675
675
|
.pr-md-code {
|
|
676
676
|
padding: 0 4px; border-radius: 4px; background: var(--dsw-alias-bg-layer-2);
|
|
677
|
-
font-size:
|
|
677
|
+
font-size: calc(11px + var(--dsh-content-font-delta, 0px)); font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
678
678
|
}
|
|
679
679
|
.pr-board-edit { min-height: 200px; max-height: 42vh; }
|
|
680
680
|
.pr-board-actions { display: flex; gap: 8px; margin-top: 6px; align-items: center; }
|
|
@@ -700,10 +700,10 @@ window.__ModuleLoader__.load({
|
|
|
700
700
|
overflow-wrap: anywhere;
|
|
701
701
|
text-overflow: clip;
|
|
702
702
|
}
|
|
703
|
-
.pr-hint { font-size:
|
|
704
|
-
.pr-err { font-size:
|
|
703
|
+
.pr-hint { font-size: calc(11px + var(--dsh-content-font-delta, 0px)); color: var(--dsw-alias-label-secondary); padding: 6px 0; }
|
|
704
|
+
.pr-err { font-size: calc(11.5px + var(--dsh-content-font-delta, 0px)); color: #f87171; padding: 4px 0; }
|
|
705
705
|
.pr-send-row { display: flex; gap: 6px; align-items: center; width: 100%; }
|
|
706
|
-
.pr-select { max-width: 200px; height: 30px; padding: 0 6px; border-radius: 6px; border: 1px solid var(--dsw-alias-border-l1); background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); font-size:
|
|
706
|
+
.pr-select { max-width: 200px; height: 30px; padding: 0 6px; border-radius: 6px; border: 1px solid var(--dsw-alias-border-l1); background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); font-size: calc(12px + var(--dsh-content-font-delta, 0px)); }
|
|
707
707
|
`;
|
|
708
708
|
|
|
709
709
|
function ensureStyle() {
|
|
@@ -924,7 +924,11 @@ function summarizeMessage(raw) {
|
|
|
924
924
|
const groups = React.useMemo(() => {
|
|
925
925
|
const map = new Map();
|
|
926
926
|
for (const [id, session] of Object.entries(byId)) {
|
|
927
|
-
if (!session
|
|
927
|
+
if (!session) continue;
|
|
928
|
+
// 2026-11-12:blank 会话原本一律不显示。但「+ 新项目」刚建出来的会话在首轮对话前
|
|
929
|
+
// 就是 blank,标题已是「项目 · 成员」——一并过滤会让新项目在侧栏彻底看不见
|
|
930
|
+
// (用户报「新项目建不了,没反应」)。所以 blank 只过滤**还没被命名**的空壳。
|
|
931
|
+
if (session.blank && !projectOfTitle(session.displayTitle || session.title)) continue;
|
|
928
932
|
if (archived.has(String(id))) continue;
|
|
929
933
|
// 2026-11-10(用户令):白名单改「事后隐藏」——只跳过**归档失败过**的会话,
|
|
930
934
|
// 不再用磁盘白名单全量过滤(那样会让新建会话因轮询延迟而整段生命期不可见)。
|
|
@@ -1384,27 +1388,67 @@ function summarizeMessage(raw) {
|
|
|
1384
1388
|
/** 设置:项目管理者名称(默认 Yat2,存 localStorage) */
|
|
1385
1389
|
const renderSettings = () => {
|
|
1386
1390
|
if (!settings) return null;
|
|
1387
|
-
|
|
1391
|
+
/**
|
|
1392
|
+
* 改名(2026-11-12 用户令「设置里面重命名之后所有管理者应该都重命名呀」):
|
|
1393
|
+
* 以前只写 localStorage,已有会话标题仍带旧名 → 排序/房间投递按新名匹配不到,
|
|
1394
|
+
* 管理者看着像「消失了」。现在改名后把所有 `<项目> · <旧名>` 的会话一并改成新名。
|
|
1395
|
+
*/
|
|
1396
|
+
const save = async () => {
|
|
1388
1397
|
const name = String(settings.manager || '').trim();
|
|
1389
1398
|
if (!name) { setSettings({ ...settings, msg: '名称不能为空' }); return; }
|
|
1399
|
+
const oldName = managerName();
|
|
1390
1400
|
try { window.localStorage.setItem('projectRoom.managerName', name); } catch { /* 存不了就本次生效 */ }
|
|
1391
|
-
setSettings(null);
|
|
1401
|
+
if (name === oldName) { setSettings(null); return; }
|
|
1402
|
+
|
|
1403
|
+
// 找出所有「某项目 · 旧管理者名」的会话,逐个改标题
|
|
1404
|
+
const targets = [];
|
|
1405
|
+
for (const [id, session] of Object.entries(byId)) {
|
|
1406
|
+
if (!session) continue;
|
|
1407
|
+
const title = String(session.displayTitle || session.title || '');
|
|
1408
|
+
const parsed = projectOfTitle(title);
|
|
1409
|
+
if (!parsed) continue;
|
|
1410
|
+
if (parsed.member !== oldName) continue;
|
|
1411
|
+
targets.push({ id, project: parsed.project });
|
|
1412
|
+
}
|
|
1413
|
+
if (!targets.length) { setSettings(null); return; }
|
|
1414
|
+
|
|
1415
|
+
setSettings({ ...settings, busy: true, msg: `正在把 ${targets.length} 个管理者会话改名为「${name}」…` });
|
|
1416
|
+
let ok = 0;
|
|
1417
|
+
const failed = [];
|
|
1418
|
+
for (const t of targets) {
|
|
1419
|
+
try {
|
|
1420
|
+
const res = await fetch(`${API}/rename`, {
|
|
1421
|
+
method: 'POST', headers: { 'content-type': 'application/json' },
|
|
1422
|
+
body: JSON.stringify({ sessionId: t.id, title: `${t.project}${SEP}${name}` }),
|
|
1423
|
+
});
|
|
1424
|
+
const data = await res.json();
|
|
1425
|
+
// 坑:/project-room/rename 失败也返回 HTTP 200 + {ok:false},只看 res.ok 会漏判
|
|
1426
|
+
if (data && data.ok) ok += 1; else failed.push(`${t.project}(${(data && data.error) || '未知'})`);
|
|
1427
|
+
} catch (error) {
|
|
1428
|
+
failed.push(`${t.project}(${String((error && error.message) || error)})`);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
if (!failed.length) { setSettings(null); return; }
|
|
1432
|
+
setSettings({
|
|
1433
|
+
...settings, busy: false,
|
|
1434
|
+
msg: `已改名 ${ok} 个;失败 ${failed.length} 个:${failed.slice(0, 3).join('、')}${failed.length > 3 ? '…' : ''}`,
|
|
1435
|
+
});
|
|
1392
1436
|
};
|
|
1393
1437
|
return h('div', { className: 'pr-modal', onClick: () => setSettings(null) },
|
|
1394
1438
|
h('div', { className: 'pr-modal-box', onClick: (event) => event.stopPropagation() },
|
|
1395
1439
|
h('div', { className: 'pr-modal-title' }, '设置'),
|
|
1396
|
-
h('div', { className: 'pr-hint' }, '
|
|
1440
|
+
h('div', { className: 'pr-hint' }, '管理者名(每个项目排第一、新建项目的默认成员名;改名会把所有管理者会话一并改名)'),
|
|
1397
1441
|
h('input', {
|
|
1398
1442
|
className: 'pr-modal-input',
|
|
1399
1443
|
value: settings.manager || '',
|
|
1400
1444
|
autoFocus: true,
|
|
1401
1445
|
placeholder: DEFAULT_MANAGER,
|
|
1446
|
+
disabled: Boolean(settings.busy),
|
|
1402
1447
|
onChange: (event) => setSettings({ ...settings, manager: event.target.value, msg: '' }),
|
|
1403
1448
|
onKeyDown: (event) => { if (event.key === 'Enter') save(); if (event.key === 'Escape') setSettings(null); },
|
|
1404
1449
|
}),
|
|
1405
1450
|
h('div', { className: 'pr-hint', style: { marginTop: '6px' } },
|
|
1406
|
-
'
|
|
1407
|
-
+ '还需要改 hub-desktop-ui 里的 MANAGER_NAMES(那是另一个插件的硬编码)。'),
|
|
1451
|
+
'提示:改名只影响侧栏的排序、新建项目默认名与会话标题,DSH 里既有的会话标题会同步改。'),
|
|
1408
1452
|
settings.msg ? h('div', { className: 'pr-err' }, settings.msg) : null,
|
|
1409
1453
|
// 2026-11-10(用户令「事后隐藏」):归档失败过的会话被记进 localStorage 隐藏集,
|
|
1410
1454
|
// 这里提供恢复入口,免得误隐藏之后找不回来。
|
|
@@ -1452,7 +1496,8 @@ function summarizeMessage(raw) {
|
|
|
1452
1496
|
const submit = async () => {
|
|
1453
1497
|
const project = String(newProject.name || '').trim();
|
|
1454
1498
|
const member = String(newProject.member || managerName()).trim() || managerName();
|
|
1455
|
-
|
|
1499
|
+
// 2026-11-12:空项目名原来直接 return,点「创建」毫无反馈(用户报「没反应」)。
|
|
1500
|
+
if (!project) { setNewProject({ ...newProject, msg: '请先填项目名' }); return; }
|
|
1456
1501
|
setNewProject({ ...newProject, busy: true, msg: '创建中…' });
|
|
1457
1502
|
try {
|
|
1458
1503
|
const svc = clientCtx && typeof clientCtx.get === 'function' ? clientCtx.get('uiWorkspace') : null;
|
|
@@ -1464,17 +1509,37 @@ function summarizeMessage(raw) {
|
|
|
1464
1509
|
const raw = await svc.connectWorkspace(workspaceId, { agentPreset: 'cordis' });
|
|
1465
1510
|
sessionId = typeof raw === 'string' ? raw : ((raw && (raw.sessionId || raw.id)) || '');
|
|
1466
1511
|
}
|
|
1467
|
-
|
|
1468
|
-
|
|
1512
|
+
// 2026-11-12:拿不到 id 时改走 `sessions.create`。不能只调 startSession——
|
|
1513
|
+
// 它返回 void,之后 sessionId 仍为空就不改名,弹窗静默关闭、列表毫无变化。
|
|
1514
|
+
if (!sessionId) {
|
|
1515
|
+
const sessionsSvc = clientCtx && typeof clientCtx.get === 'function' ? clientCtx.get('sessions') : null;
|
|
1516
|
+
if (sessionsSvc && typeof sessionsSvc.create === 'function') {
|
|
1517
|
+
sessionId = await sessionsSvc.create(
|
|
1518
|
+
workspaceId !== undefined ? { workspaceId, agentPreset: 'cordis' } : { agentPreset: 'cordis' },
|
|
1519
|
+
);
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
if (!sessionId) {
|
|
1523
|
+
setNewProject({ ...newProject, busy: false, msg: '创建失败:没拿到新会话 id(先切一个工作区再试)' });
|
|
1524
|
+
return;
|
|
1469
1525
|
}
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1526
|
+
const renameRes = await fetch(`${API}/rename`, {
|
|
1527
|
+
method: 'POST', headers: { 'content-type': 'application/json' },
|
|
1528
|
+
body: JSON.stringify({ sessionId, title: `${project} · ${member}` }),
|
|
1529
|
+
});
|
|
1530
|
+
// 宿主这条路由失败时也是 HTTP 200 + {ok:false},只看 res.ok 会漏判。
|
|
1531
|
+
let renameData = null;
|
|
1532
|
+
try { renameData = await renameRes.json(); } catch { renameData = null; }
|
|
1533
|
+
if (!renameRes.ok || !renameData || renameData.ok === false) {
|
|
1534
|
+
const why = (renameData && renameData.error) ? `:${renameData.error}` : '';
|
|
1535
|
+
setNewProject({ ...newProject, busy: false, msg: `会话已建,但改名失败(HTTP ${renameRes.status}${why})` });
|
|
1536
|
+
return;
|
|
1475
1537
|
}
|
|
1476
1538
|
// 初始化房间看板(不存在则建模板)
|
|
1477
1539
|
try { await fetch(`${API}/board?project=${encodeURIComponent(project)}`, { method: 'POST' }); } catch { /* 看板可选 */ }
|
|
1540
|
+
// 2026-11-12:建完立刻打开该会话。此前只建不打开,而侧栏又不显示 blank 会话,
|
|
1541
|
+
// 用户点「创建」后界面上什么都没发生——这就是「新项目建不了,没反应」。
|
|
1542
|
+
openSessionById(sessionId);
|
|
1478
1543
|
setNewProject(null);
|
|
1479
1544
|
} catch (error) {
|
|
1480
1545
|
setNewProject({ ...newProject, busy: false, msg: `失败:${String((error && error.message) || error)}` });
|
|
@@ -1492,15 +1557,15 @@ function summarizeMessage(raw) {
|
|
|
1492
1557
|
onKeyDown: (event) => { if (event.key === 'Enter') submit(); if (event.key === 'Escape') setNewProject(null); },
|
|
1493
1558
|
}),
|
|
1494
1559
|
h('div', { style: { height: '8px' } }),
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
`创建后会话标题为「${String(newProject.name || '项目名').trim()} · ${String(newProject.member ||
|
|
1560
|
+
// 2026-11-12 用户令:新建项目不再让用户填管理者名称,只留项目名;
|
|
1561
|
+
// 管理者名统一取 ⚙ 设置里的值(submit 里 member 为空即回落 managerName())。
|
|
1562
|
+
h('div', {
|
|
1563
|
+
style: {
|
|
1564
|
+
fontSize: 'calc(10.5px + var(--dsh-content-font-delta, 0px))',
|
|
1565
|
+
color: 'var(--dsw-alias-label-secondary)',
|
|
1566
|
+
},
|
|
1567
|
+
},
|
|
1568
|
+
`创建后会话标题为「${String(newProject.name || '项目名').trim()} · ${String(newProject.member || managerName()).trim() || managerName()}」,管理者名可在 ⚙ 设置里改`),
|
|
1504
1569
|
newProject.msg ? h('div', { className: 'pr-hint' }, newProject.msg) : null,
|
|
1505
1570
|
h('div', { className: 'pr-modal-actions' },
|
|
1506
1571
|
h('button', { className: 'pr-btn', onClick: () => setNewProject(null), disabled: newProject.busy }, '取消'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-project-room",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Project rooms for DeepSeek Harness: group sessions into projects, see per-project runtime, and open a room with a shared board, task list, todo queue and message delivery to member sessions.",
|
|
6
6
|
"main": "index.js",
|