pi-web-ui 0.46.0 → 0.48.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.
@@ -217,6 +217,19 @@ body.panel-resizing {
217
217
  overflow-y: auto;
218
218
  padding: 6px 6px 0;
219
219
  }
220
+ /* Cross-project running conversations: a group header names the workspace
221
+ when the group is NOT the current project (the current project stays bare
222
+ to preserve the old look). */
223
+ .panel-conv-group-title {
224
+ padding: 6px 8px 2px;
225
+ font-size: 10px;
226
+ font-weight: 600;
227
+ color: var(--text-dim);
228
+ letter-spacing: 0.02em;
229
+ white-space: nowrap;
230
+ overflow: hidden;
231
+ text-overflow: ellipsis;
232
+ }
220
233
  .panel-sessions {
221
234
  flex: 1;
222
235
  min-height: 0;
@@ -2872,6 +2885,67 @@ body.panel-resizing {
2872
2885
  overflow-y: auto;
2873
2886
  }
2874
2887
 
2888
+ /* Two-column middle band: provider filter sidebar (left) + model list
2889
+ (right). Only the list columns scroll independently. */
2890
+ .dd-model-body {
2891
+ display: flex;
2892
+ gap: 2px;
2893
+ min-height: 0;
2894
+ flex: 1 1 auto;
2895
+ }
2896
+ .dd-provider-col {
2897
+ .dd-provider-head {
2898
+ padding: 5px 8px 4px;
2899
+ font-size: 10px;
2900
+ font-weight: 700;
2901
+ letter-spacing: 0.6px;
2902
+ text-transform: uppercase;
2903
+ color: var(--text-faint);
2904
+ }
2905
+ flex: none;
2906
+ width: 112px;
2907
+ overflow-y: auto;
2908
+ border-right: 1px solid var(--border-soft);
2909
+ margin: 2px 4px 2px 0;
2910
+ padding-right: 4px;
2911
+ }
2912
+ .dd-provider-item {
2913
+ display: flex;
2914
+ align-items: center;
2915
+ justify-content: space-between;
2916
+ gap: 6px;
2917
+ width: 100%;
2918
+ padding: 6px 8px;
2919
+ border: none;
2920
+ border-radius: 6px;
2921
+ background: transparent;
2922
+ color: var(--text-dim);
2923
+ font-size: 12px;
2924
+ text-align: left;
2925
+ cursor: pointer;
2926
+ white-space: nowrap;
2927
+ }
2928
+ .dd-provider-item:hover {
2929
+ background: var(--bg-elev);
2930
+ color: var(--text);
2931
+ }
2932
+ .dd-provider-item.active {
2933
+ background: var(--accent-soft);
2934
+ color: var(--accent);
2935
+ font-weight: 600;
2936
+ }
2937
+ .dd-provider-name {
2938
+ overflow: hidden;
2939
+ text-overflow: ellipsis;
2940
+ min-width: 0;
2941
+ }
2942
+ .dd-provider-count {
2943
+ flex: none;
2944
+ font-size: 10.5px;
2945
+ color: var(--text-faint);
2946
+ font-family: var(--mono);
2947
+ }
2948
+
2875
2949
  /* Fixed footer (refresh / manage models) — never scrolls away. */
2876
2950
  .dd-footer {
2877
2951
  border-top: 1px solid var(--border-soft);
@@ -2879,12 +2953,15 @@ body.panel-resizing {
2879
2953
  padding-top: 3px;
2880
2954
  }
2881
2955
 
2882
- /* 模型下拉(dd-menu-model):外层菜单本身不滚动,只有中间的模型列表
2883
- (.dd-model-scroll)滚动——顶部搜索行和底部「刷新 / 管理模型」始终可见。 */
2956
+ /* 模型下拉(dd-menu-model):外层菜单本身不滚动,只有中间的两栏区域
2957
+ (.dd-model-body)滚动——顶部搜索行和底部「刷新 / 管理模型」始终可见。 */
2884
2958
  .dd-menu.dd-menu-model {
2885
2959
  display: flex;
2886
2960
  flex-direction: column;
2887
2961
  overflow-y: hidden;
2962
+ /* 加宽以容纳左侧服务商栏 + 右侧模型列表 */
2963
+ min-width: 330px;
2964
+ max-width: 460px;
2888
2965
  }
2889
2966
  .dd-menu.dd-menu-model .dd-model-scroll {
2890
2967
  flex: 1 1 auto;
@@ -4307,24 +4384,48 @@ span.msg-editor-hint svg {
4307
4384
  white-space: nowrap;
4308
4385
  }
4309
4386
 
4310
- .empty-examples {
4311
- margin-top: 34px;
4387
+ /* ---- 提示词模板(空态推荐卡片) ---- */
4388
+ .empty-templates {
4389
+ margin-top: 30px;
4390
+ width: min(720px, 92vw);
4391
+ }
4392
+
4393
+ .empty-templates-head {
4394
+ display: flex;
4395
+ align-items: baseline;
4396
+ justify-content: center;
4397
+ gap: 10px;
4398
+ flex-wrap: wrap;
4399
+ margin-bottom: 12px;
4400
+ }
4401
+
4402
+ .empty-templates-title {
4403
+ font-size: 14px;
4404
+ font-weight: 650;
4405
+ color: var(--text);
4406
+ }
4407
+
4408
+ .empty-templates-hint {
4409
+ font-size: 11.5px;
4410
+ color: var(--text-faint);
4411
+ }
4412
+
4413
+ .empty-templates-grid {
4312
4414
  display: grid;
4313
- grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
4415
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
4314
4416
  gap: 10px;
4315
- width: min(560px, 90vw);
4316
4417
  }
4317
4418
 
4318
- .empty-example {
4419
+ .empty-template {
4319
4420
  display: flex;
4320
- align-items: center;
4421
+ align-items: flex-start;
4321
4422
  gap: 10px;
4322
- padding: 11px 14px;
4423
+ padding: 11px 13px;
4424
+ position: relative; /* 右上角 ✏️ 编辑按钮的定位基准 */
4323
4425
  border: 1px solid var(--border);
4324
4426
  border-radius: 12px;
4325
4427
  background: var(--bg-elev);
4326
4428
  color: var(--text-dim);
4327
- font-size: 13px;
4328
4429
  text-align: left;
4329
4430
  cursor: pointer;
4330
4431
  transition:
@@ -4333,23 +4434,313 @@ span.msg-editor-hint svg {
4333
4434
  transform 0.12s,
4334
4435
  box-shadow 0.15s;
4335
4436
  }
4336
- .empty-example:hover {
4437
+
4438
+ /* 卡片右上角的编辑(✏️)按钮:点卡片 = 填入输入框,点 ✏️ = 编辑/删除。 */
4439
+ .template-card-ops {
4440
+ position: absolute;
4441
+ top: 7px;
4442
+ right: 7px;
4443
+ display: inline-flex;
4444
+ align-items: center;
4445
+ justify-content: center;
4446
+ width: 20px;
4447
+ height: 20px;
4448
+ border-radius: 6px;
4449
+ color: var(--text-faint);
4450
+ cursor: pointer;
4451
+ background: transparent;
4452
+ transition:
4453
+ background 0.15s,
4454
+ color 0.15s;
4455
+ }
4456
+ .template-card-ops:hover {
4457
+ background: var(--accent-soft);
4458
+ color: var(--accent);
4459
+ }
4460
+ .empty-template:hover {
4337
4461
  border-color: rgba(139, 92, 246, 0.5);
4338
4462
  background: var(--accent-soft);
4339
- color: var(--text);
4340
- transform: translateY(-1px);
4341
4463
  box-shadow: 0 8px 22px rgba(139, 92, 246, 0.16);
4342
4464
  }
4465
+ .empty-template.add {
4466
+ border-style: dashed;
4467
+ }
4468
+ .empty-template.add:hover {
4469
+ border-color: rgba(139, 92, 246, 0.6);
4470
+ }
4343
4471
 
4344
- .empty-example-icon {
4472
+ .empty-template-icon {
4345
4473
  font-size: 17px;
4346
4474
  flex-shrink: 0;
4475
+ line-height: 1.5;
4476
+ }
4477
+ .empty-template.add .empty-template-icon {
4478
+ display: inline-flex;
4479
+ align-items: center;
4480
+ justify-content: center;
4481
+ width: 20px;
4482
+ height: 20px;
4483
+ color: var(--text-faint);
4484
+ }
4485
+
4486
+ .empty-template-main {
4487
+ display: flex;
4488
+ flex-direction: column;
4489
+ gap: 2px;
4490
+ min-width: 0;
4491
+ }
4492
+
4493
+ .empty-template-title {
4494
+ font-size: 13px;
4495
+ font-weight: 600;
4496
+ color: var(--text);
4497
+ white-space: nowrap;
4498
+ overflow: hidden;
4499
+ text-overflow: ellipsis;
4500
+ }
4501
+
4502
+ .empty-template-desc {
4503
+ font-size: 11.5px;
4504
+ color: var(--text-faint);
4505
+ line-height: 1.45;
4506
+ display: -webkit-box;
4507
+ -webkit-line-clamp: 2;
4508
+ -webkit-box-orient: vertical;
4509
+ overflow: hidden;
4510
+ }
4511
+
4512
+ .empty-templates-foot {
4513
+ margin-top: 10px;
4514
+ display: flex;
4515
+ justify-content: center;
4516
+ }
4517
+
4518
+ .empty-templates-reset {
4519
+ display: inline-flex;
4520
+ align-items: center;
4521
+ gap: 5px;
4522
+ border: none;
4523
+ background: transparent;
4524
+ color: var(--text-faint);
4525
+ font-size: 11.5px;
4526
+ cursor: pointer;
4527
+ padding: 4px 8px;
4528
+ border-radius: 6px;
4529
+ transition: color 0.15s, background 0.15s;
4530
+ }
4531
+ .empty-templates-reset:hover {
4532
+ color: var(--text-dim);
4533
+ background: var(--bg-elev);
4534
+ }
4535
+
4536
+ /* ---- 提示词模板 modal ---- */
4537
+ .template-modal {
4538
+ max-width: 620px;
4539
+ }
4540
+
4541
+ /* 模板库(选择器)弹窗:列所有模板卡片 */
4542
+ .template-picker {
4543
+ max-width: 720px;
4544
+ }
4545
+
4546
+ .template-picker-head {
4547
+ display: flex;
4548
+ align-items: center;
4549
+ gap: 10px;
4550
+ }
4551
+
4552
+ .template-picker-title {
4553
+ flex: 1;
4554
+ font-size: 15px;
4555
+ font-weight: 650;
4556
+ color: var(--text);
4557
+ }
4558
+
4559
+ .template-picker-hint {
4560
+ font-size: 11.5px;
4561
+ color: var(--text-faint);
4562
+ }
4563
+
4564
+ .template-picker-grid {
4565
+ display: grid;
4566
+ grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
4567
+ gap: 10px;
4568
+ }
4569
+
4570
+ .template-picker-foot {
4571
+ display: flex;
4572
+ justify-content: center;
4573
+ margin-top: 4px;
4574
+ }
4575
+
4576
+ .template-modal-head {
4577
+ display: flex;
4578
+ align-items: center;
4579
+ gap: 10px;
4580
+ }
4581
+
4582
+ .template-modal-icon {
4583
+ font-size: 20px;
4584
+ flex-shrink: 0;
4347
4585
  }
4348
4586
 
4349
- .empty-example-text {
4587
+ .template-modal-badge {
4588
+ flex-shrink: 0;
4589
+ font-size: 11px;
4590
+ font-weight: 700;
4591
+ color: var(--accent);
4592
+ border: 1px solid var(--accent);
4593
+ border-radius: 999px;
4594
+ padding: 1px 8px;
4350
4595
  white-space: nowrap;
4596
+ }
4597
+
4598
+ .template-modal-title {
4599
+ flex: 1;
4600
+ font-size: 15px;
4601
+ font-weight: 650;
4602
+ color: var(--text);
4603
+ min-width: 0;
4351
4604
  overflow: hidden;
4352
4605
  text-overflow: ellipsis;
4606
+ white-space: nowrap;
4607
+ }
4608
+
4609
+ .template-modal-close {
4610
+ width: 30px;
4611
+ height: 30px;
4612
+ padding: 0;
4613
+ border-radius: 50%;
4614
+ flex-shrink: 0;
4615
+ display: inline-flex;
4616
+ align-items: center;
4617
+ justify-content: center;
4618
+ color: var(--text-dim);
4619
+ background: transparent;
4620
+ }
4621
+
4622
+ .template-field {
4623
+ display: flex;
4624
+ flex-direction: column;
4625
+ gap: 5px;
4626
+ }
4627
+
4628
+ .template-field-label {
4629
+ font-size: 11.5px;
4630
+ font-weight: 600;
4631
+ color: var(--text-dim);
4632
+ }
4633
+
4634
+ .template-field-input {
4635
+ border: 1px solid var(--border);
4636
+ border-radius: 8px;
4637
+ background: var(--bg-elev);
4638
+ color: var(--text);
4639
+ font-size: 13px;
4640
+ padding: 7px 10px;
4641
+ outline: none;
4642
+ transition: border-color 0.15s;
4643
+ }
4644
+ .template-field-input:focus {
4645
+ border-color: var(--accent);
4646
+ }
4647
+ .template-field-input.icon {
4648
+ width: 72px;
4649
+ text-align: center;
4650
+ font-size: 16px;
4651
+ }
4652
+
4653
+ .template-field-prompt {
4654
+ border: 1px solid var(--border);
4655
+ border-radius: 8px;
4656
+ background: var(--bg-elev);
4657
+ color: var(--text);
4658
+ font-size: 13px;
4659
+ line-height: 1.6;
4660
+ padding: 9px 10px;
4661
+ resize: none;
4662
+ overflow: hidden;
4663
+ outline: none;
4664
+ min-height: 96px;
4665
+ transition: border-color 0.15s;
4666
+ }
4667
+ .template-field-prompt:focus {
4668
+ border-color: var(--accent);
4669
+ }
4670
+
4671
+ .template-error {
4672
+ font-size: 12px;
4673
+ color: var(--red);
4674
+ }
4675
+
4676
+ .template-modal-actions {
4677
+ display: flex;
4678
+ align-items: center;
4679
+ justify-content: space-between;
4680
+ gap: 8px;
4681
+ flex-wrap: wrap;
4682
+ }
4683
+
4684
+ .template-modal-actions-left,
4685
+ .template-modal-actions-right {
4686
+ display: flex;
4687
+ align-items: center;
4688
+ gap: 8px;
4689
+ flex-wrap: wrap;
4690
+ }
4691
+
4692
+ .template-btn {
4693
+ font-size: 12.5px;
4694
+ padding: 6px 12px;
4695
+ border-radius: 8px;
4696
+ /* 显式主题背景,避免浏览器默认按钮灰(紫晕等主题下与文字对比度差) */
4697
+ background: var(--bg-elev);
4698
+ border-color: var(--border);
4699
+ color: var(--text-dim);
4700
+ }
4701
+ .template-btn:hover {
4702
+ border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
4703
+ color: var(--text);
4704
+ }
4705
+ .template-btn.ghost {
4706
+ background: transparent;
4707
+ }
4708
+ .template-btn.ghost.danger {
4709
+ color: var(--red);
4710
+ border-color: color-mix(in srgb, var(--red) 45%, var(--border));
4711
+ }
4712
+ .template-btn.fill,
4713
+ .template-btn.send {
4714
+ font-weight: 600;
4715
+ }
4716
+ .template-btn.fill {
4717
+ background: var(--accent-soft);
4718
+ border-color: color-mix(in srgb, var(--accent) 60%, var(--border));
4719
+ color: var(--accent);
4720
+ }
4721
+ .template-btn.fill:hover {
4722
+ background: var(--accent-soft);
4723
+ color: var(--accent);
4724
+ filter: brightness(1.12);
4725
+ }
4726
+ .template-btn.send {
4727
+ background: var(--accent);
4728
+ border-color: var(--accent);
4729
+ color: #fff;
4730
+ }
4731
+ .template-btn.send:hover {
4732
+ filter: brightness(1.08);
4733
+ }
4734
+
4735
+ /* 模板弹窗右上角关闭钮:同样显式主题背景 */
4736
+ .template-modal-close {
4737
+ background: var(--bg-elev);
4738
+ border-color: var(--border);
4739
+ color: var(--text-dim);
4740
+ }
4741
+ .template-modal-close:hover {
4742
+ background: var(--accent-soft);
4743
+ color: var(--accent);
4353
4744
  }
4354
4745
 
4355
4746
  .streaming-wait,
@@ -4972,16 +5363,27 @@ span.msg-editor-hint svg {
4972
5363
  inset 0 1px 0 rgba(255, 255, 255, 0.04),
4973
5364
  0 4px 18px rgba(0, 0, 0, 0.28);
4974
5365
  }
4975
- .inputbox-row {
5366
+ /* 底部工具条(ChatGPT 风格,整合进输入框):左 = 附件 / 模型 / 思考强度,
5367
+ 右 = 发送 / 停止。与输入区之间用一条细分隔线划开。 */
5368
+ .composer-tools {
4976
5369
  display: flex;
4977
- align-items: flex-end;
4978
- gap: 10px;
5370
+ align-items: center;
5371
+ justify-content: space-between;
5372
+ gap: 8px;
5373
+ padding-top: 8px;
5374
+ border-top: 1px solid var(--border-soft);
5375
+ }
5376
+ .composer-tools-left {
5377
+ display: flex;
5378
+ align-items: center;
5379
+ gap: 6px;
4979
5380
  min-width: 0;
5381
+ flex-wrap: wrap;
4980
5382
  }
4981
- /* Mobile tools row (file / model / thinking / send) — desktop hides it,
4982
- phones show it under the textarea (see the ≤768px block). */
4983
- .input-tools {
4984
- display: none;
5383
+ .composer-tools-right {
5384
+ display: flex;
5385
+ align-items: center;
5386
+ flex-shrink: 0;
4985
5387
  }
4986
5388
  .inputbox:focus-within {
4987
5389
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
@@ -4992,7 +5394,8 @@ span.msg-editor-hint svg {
4992
5394
  }
4993
5395
 
4994
5396
  .inputbox textarea {
4995
- flex: 1;
5397
+ flex: none; /* 不能用 flex:1 —— flex-basis:0% 会覆盖 JS 设置的 inline height,
5398
+ * 导致自适应高度失效(输入多行也不长高、不出现滚动条) */
4996
5399
  resize: none;
4997
5400
  border: none;
4998
5401
  outline: none;
@@ -5071,11 +5474,13 @@ span.msg-editor-hint svg {
5071
5474
  }
5072
5475
 
5073
5476
  /* Paperclip: quiet until hovered. */
5074
- .inputbox .btn.attach-img {
5477
+ .inputbox .btn.attach-img,
5478
+ .inputbox .btn.tpl-open {
5075
5479
  border: none;
5076
5480
  color: var(--text-faint);
5077
5481
  }
5078
- .inputbox .btn.attach-img:hover:not(:disabled) {
5482
+ .inputbox .btn.attach-img:hover:not(:disabled),
5483
+ .inputbox .btn.tpl-open:hover {
5079
5484
  background: var(--accent-soft);
5080
5485
  color: var(--accent);
5081
5486
  }
@@ -7047,49 +7452,35 @@ span.msg-editor-hint svg {
7047
7452
  display: none;
7048
7453
  }
7049
7454
 
7050
- /* ---- input becomes two lines: textarea, then tools below ---- */
7051
- .input-tools {
7052
- display: flex;
7053
- align-items: center;
7054
- justify-content: space-between;
7055
- gap: 6px;
7056
- flex-wrap: nowrap;
7057
- }
7058
- .input-tools-left,
7059
- .input-tools-right {
7060
- display: flex;
7061
- align-items: center;
7062
- gap: 6px;
7063
- min-width: 0;
7064
- }
7065
- .input-tools-right {
7066
- flex-shrink: 0;
7067
- }
7068
- .inputbox-row .attach-img,
7069
- .inputbox-row .inputbox-actions {
7070
- display: none;
7071
- }
7072
- /* Keep labels readable in the input tools row (the global chip rule
7073
- above hides them) and give the model name room to truncate. */
7074
- .input-tools .chip > span:not(.update-dot) {
7455
+ /* ---- composer: 输入框内底部工具条(模型/思考/附件 左,发送/停止 右)。
7456
+ 恢复 chip 标签显示(上面的全局规则会隐藏它们),并让模型名可截断。 ---- */
7457
+ .composer-tools .chip > span:not(.update-dot) {
7075
7458
  display: inline;
7076
7459
  }
7077
- .input-tools .chip-model {
7078
- max-width: 80px;
7460
+ .composer-tools .chip-model {
7461
+ max-width: 96px;
7079
7462
  }
7080
- /* Compress chips so model + thinking + attach + send fit one line on
7081
- narrow phones: allow shrinking with ellipsis instead of wrapping. */
7082
- .input-tools .chip {
7463
+ .composer-tools .chip {
7083
7464
  padding: 5px 8px;
7084
7465
  flex-shrink: 1;
7085
7466
  min-width: 0;
7086
7467
  }
7087
- .input-tools .chip .chip-sub,
7088
- .input-tools .chip .chip-model {
7468
+ .composer-tools .chip .chip-sub,
7469
+ .composer-tools .chip .chip-model {
7089
7470
  overflow: hidden;
7090
7471
  text-overflow: ellipsis;
7091
7472
  min-width: 0;
7092
7473
  }
7474
+ /* 超窄屏下工具条可换行,避免挤压发送按钮。 */
7475
+ .composer-tools {
7476
+ flex-wrap: wrap;
7477
+ }
7478
+ .composer-tools-left {
7479
+ flex: 1 1 auto;
7480
+ }
7481
+ .composer-tools-right {
7482
+ flex-shrink: 0;
7483
+ }
7093
7484
  .topbar-actions {
7094
7485
  gap: 6px;
7095
7486
  flex-wrap: wrap;