openclacky 1.5.12 → 1.5.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -0
  3. data/lib/clacky/access_key.rb +59 -0
  4. data/lib/clacky/agent/message_compressor_helper.rb +52 -1
  5. data/lib/clacky/agent/session_serializer.rb +35 -2
  6. data/lib/clacky/agent/time_machine.rb +9 -1
  7. data/lib/clacky/agent.rb +11 -7
  8. data/lib/clacky/agent_config.rb +40 -0
  9. data/lib/clacky/agent_profile.rb +5 -5
  10. data/lib/clacky/billing/platform_billing.rb +84 -1
  11. data/lib/clacky/brand_config.rb +4 -3
  12. data/lib/clacky/cli.rb +4 -2
  13. data/lib/clacky/client.rb +107 -0
  14. data/lib/clacky/default_extensions/ext-studio/api/handler.rb +3 -0
  15. data/lib/clacky/default_extensions/ext-studio/panels/studio/view.js +40 -21
  16. data/lib/clacky/default_extensions/git/ext.yml +1 -1
  17. data/lib/clacky/default_extensions/git/panels/git/view.js +483 -77
  18. data/lib/clacky/default_extensions/meeting/ext.yml +2 -1
  19. data/lib/clacky/default_extensions/time_machine/ext.yml +1 -1
  20. data/lib/clacky/default_extensions/time_machine/panels/time_machine/view.js +186 -208
  21. data/lib/clacky/extension/packager.rb +4 -2
  22. data/lib/clacky/extension/verifier.rb +14 -1
  23. data/lib/clacky/message_format/open_ai.rb +5 -1
  24. data/lib/clacky/message_format/open_ai_responses.rb +409 -0
  25. data/lib/clacky/message_history.rb +6 -2
  26. data/lib/clacky/openai_responses_stream_aggregator.rb +294 -0
  27. data/lib/clacky/providers.rb +18 -6
  28. data/lib/clacky/server/dir_picker.rb +154 -0
  29. data/lib/clacky/server/git_panel.rb +61 -9
  30. data/lib/clacky/server/http_server.rb +147 -103
  31. data/lib/clacky/tools/terminal.rb +27 -3
  32. data/lib/clacky/ui2/markdown_renderer.rb +15 -12
  33. data/lib/clacky/ui2/strings_cjk_patch.rb +132 -0
  34. data/lib/clacky/ui2/themes/hacker_theme.rb +1 -1
  35. data/lib/clacky/ui2/themes/minimal_theme.rb +1 -1
  36. data/lib/clacky/utils/model_pricing.rb +70 -4
  37. data/lib/clacky/version.rb +1 -1
  38. data/lib/clacky/web/app.css +412 -108
  39. data/lib/clacky/web/components/composer.js +45 -7
  40. data/lib/clacky/web/components/custom-select.js +136 -0
  41. data/lib/clacky/web/components/mentions.js +58 -2
  42. data/lib/clacky/web/components/model-picker.js +527 -0
  43. data/lib/clacky/web/components/onboard.js +29 -55
  44. data/lib/clacky/web/core/ext.js +38 -0
  45. data/lib/clacky/web/features/billing/view.js +20 -6
  46. data/lib/clacky/web/features/extensions/view.js +22 -10
  47. data/lib/clacky/web/features/new-session/store.js +15 -1
  48. data/lib/clacky/web/features/new-session/view.js +31 -22
  49. data/lib/clacky/web/features/trash/view.js +31 -19
  50. data/lib/clacky/web/features/workspace/store.js +1 -0
  51. data/lib/clacky/web/features/workspace/view.js +54 -3
  52. data/lib/clacky/web/i18n.js +73 -11
  53. data/lib/clacky/web/index.html +92 -37
  54. data/lib/clacky/web/sessions.js +550 -592
  55. data/lib/clacky/web/settings.js +163 -190
  56. data/lib/clacky.rb +3 -0
  57. metadata +8 -1
@@ -1270,15 +1270,8 @@ body {
1270
1270
  .search-select {
1271
1271
  flex: 0 0 5rem;
1272
1272
  min-width: 0;
1273
- padding: 0 2px 0 0.25rem;
1274
1273
  height: 100%;
1275
- font-size: 0.6875rem;
1276
- border: none;
1277
1274
  border-right: 1px solid var(--color-border-primary);
1278
- background: transparent;
1279
- color: var(--color-text-secondary);
1280
- outline: none;
1281
- cursor: pointer;
1282
1275
  }
1283
1276
 
1284
1277
  /* date wrapper: half width, position:relative for the icon overlay */
@@ -1318,7 +1311,6 @@ body {
1318
1311
  }
1319
1312
 
1320
1313
  /* Active filter highlight */
1321
- .search-select[data-active="true"],
1322
1314
  .search-date[data-active="true"] {
1323
1315
  color: var(--color-accent-primary);
1324
1316
  font-weight: 500;
@@ -1775,6 +1767,9 @@ body {
1775
1767
  .session-actions-submenu-item:hover .session-actions-submenu-icon {
1776
1768
  color: var(--color-text-primary);
1777
1769
  }
1770
+ .session-actions-submenu-item.selected {
1771
+ background: var(--color-bg-hover);
1772
+ }
1778
1773
  .session-actions-submenu-divider {
1779
1774
  height: 1px;
1780
1775
  background: var(--color-border-secondary);
@@ -3099,13 +3094,32 @@ body {
3099
3094
  /* ── Workspace viewer (file tree + tabbed preview, inside the Files tab) ── */
3100
3095
  .wv-root { flex: 1; min-height: 0; display: flex; }
3101
3096
  .wv-tree-pane {
3102
- flex: 0 0 38%;
3097
+ flex: 0 0 auto;
3098
+ width: var(--wv-tree-width, 38%);
3103
3099
  min-width: 168px;
3104
- max-width: 300px;
3100
+ max-width: 460px;
3105
3101
  display: flex;
3106
3102
  flex-direction: column;
3107
3103
  min-height: 0;
3108
- border-right: 1px solid var(--color-border-primary);
3104
+ }
3105
+ .wv-tree-resize {
3106
+ flex: none;
3107
+ width: 6px;
3108
+ cursor: col-resize;
3109
+ position: relative;
3110
+ z-index: 2;
3111
+ background: transparent;
3112
+ display: none;
3113
+ }
3114
+ .wv-root.has-open-files .wv-tree-resize { display: block; }
3115
+ .wv-tree-resize::after {
3116
+ content: "";
3117
+ position: absolute;
3118
+ top: 0;
3119
+ bottom: 0;
3120
+ left: 2px;
3121
+ width: 1px;
3122
+ background: var(--color-border-primary);
3109
3123
  }
3110
3124
  .wv-viewer { flex: 1; min-width: 0; display: none; flex-direction: column; min-height: 0; }
3111
3125
  .wv-root.has-open-files .wv-viewer { display: flex; }
@@ -4868,7 +4882,7 @@ body {
4868
4882
  position: fixed;
4869
4883
  /* Position will be calculated dynamically via JavaScript */
4870
4884
  min-width: 12.5rem;
4871
- max-width: min(17.5rem, calc(100vw - 1.5rem));
4885
+ max-width: min(20rem, calc(100vw - 1.5rem));
4872
4886
  background: var(--color-bg-secondary);
4873
4887
  border: 1px solid var(--color-border-primary);
4874
4888
  border-radius: 8px;
@@ -4927,25 +4941,33 @@ body {
4927
4941
 
4928
4942
  .sib-submodel-toggle {
4929
4943
  margin-left: 0.375rem;
4930
- width: 1.125rem;
4931
- height: 1.125rem;
4944
+ width: 1.25rem;
4945
+ height: 1.25rem;
4932
4946
  padding: 0;
4933
- border: none;
4934
- border-radius: 4px;
4935
- background: transparent;
4947
+ border: 1px solid var(--color-border-primary);
4948
+ border-radius: 5px;
4949
+ background: var(--color-bg-primary);
4936
4950
  color: var(--color-text-secondary);
4937
4951
  cursor: pointer;
4938
4952
  display: inline-flex;
4939
4953
  align-items: center;
4940
4954
  justify-content: center;
4941
- transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
4955
+ transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
4942
4956
  }
4943
4957
  .sib-submodel-toggle:hover {
4944
4958
  background: color-mix(in srgb, var(--color-accent-primary) 15%, transparent);
4959
+ border-color: color-mix(in srgb, var(--color-accent-primary) 45%, transparent);
4945
4960
  color: var(--color-accent-primary);
4946
4961
  }
4947
4962
  .sib-submodel-toggle[aria-expanded="true"] {
4948
4963
  background: color-mix(in srgb, var(--color-accent-primary) 18%, transparent);
4964
+ border-color: color-mix(in srgb, var(--color-accent-primary) 50%, transparent);
4965
+ color: var(--color-accent-primary);
4966
+ }
4967
+ /* Keep the chevron visible when its row is hovered or selected. */
4968
+ .sib-model-option:hover .sib-submodel-toggle,
4969
+ .sib-model-option.current .sib-submodel-toggle {
4970
+ border-color: color-mix(in srgb, var(--color-accent-primary) 45%, transparent);
4949
4971
  color: var(--color-accent-primary);
4950
4972
  }
4951
4973
  .sib-submodel-toggle[aria-expanded="true"] svg {
@@ -4961,8 +4983,8 @@ body {
4961
4983
 
4962
4984
  .sib-submodel-panel {
4963
4985
  position: fixed;
4964
- min-width: 11rem;
4965
- max-width: 16rem;
4986
+ min-width: 12rem;
4987
+ max-width: 18rem;
4966
4988
  background: var(--color-bg-secondary);
4967
4989
  border: 1px solid var(--color-border-primary);
4968
4990
  border-radius: 8px;
@@ -4973,6 +4995,9 @@ body {
4973
4995
  padding: 0.25rem 0;
4974
4996
  }
4975
4997
  .sib-submodel-panel-header {
4998
+ display: flex;
4999
+ align-items: baseline;
5000
+ gap: 0.375rem;
4976
5001
  padding: 0.375rem 0.875rem 0.4375rem;
4977
5002
  font-size: 0.625rem;
4978
5003
  text-transform: uppercase;
@@ -4981,6 +5006,17 @@ body {
4981
5006
  border-bottom: 1px solid var(--color-border-primary);
4982
5007
  margin-bottom: 0.25rem;
4983
5008
  }
5009
+ .sib-submodel-panel-model {
5010
+ font-family: var(--font-mono, monospace);
5011
+ font-size: 0.625rem;
5012
+ text-transform: none;
5013
+ letter-spacing: 0;
5014
+ color: var(--color-text-tertiary);
5015
+ overflow: hidden;
5016
+ text-overflow: ellipsis;
5017
+ white-space: nowrap;
5018
+ min-width: 0;
5019
+ }
4984
5020
  .sib-submodel-row {
4985
5021
  padding: 0.5rem 0.875rem;
4986
5022
  font-size: 0.7rem;
@@ -5003,6 +5039,13 @@ body {
5003
5039
  color: var(--color-accent-primary);
5004
5040
  }
5005
5041
  .sib-submodel-row-name {
5042
+ display: inline-flex;
5043
+ align-items: center;
5044
+ gap: 0.375rem;
5045
+ overflow: hidden;
5046
+ min-width: 0;
5047
+ }
5048
+ .sib-submodel-row-text {
5006
5049
  overflow: hidden;
5007
5050
  text-overflow: ellipsis;
5008
5051
  white-space: nowrap;
@@ -5070,7 +5113,6 @@ body {
5070
5113
  display: inline-flex;
5071
5114
  align-items: center;
5072
5115
  flex: 0 0 auto;
5073
- margin-left: 0.375rem;
5074
5116
  padding: 1px 0.375rem;
5075
5117
  font-size: 0.5625rem;
5076
5118
  line-height: 1.4;
@@ -5166,15 +5208,58 @@ body {
5166
5208
  .sib-model-option .sib-model-name.has-sub {
5167
5209
  flex-direction: column;
5168
5210
  align-items: flex-start;
5169
- gap: 0.125rem;
5211
+ gap: 0.325rem;
5170
5212
  }
5171
5213
  .sib-model-option .sib-model-name-main {
5214
+ display: inline-flex;
5215
+ align-items: center;
5216
+ gap: 0.375rem;
5217
+ overflow: hidden;
5218
+ flex: 0 1 auto;
5219
+ min-width: 0;
5220
+ }
5221
+ .sib-model-option .sib-model-name-text {
5172
5222
  overflow: hidden;
5173
5223
  text-overflow: ellipsis;
5174
5224
  white-space: nowrap;
5175
- flex: 0 1 auto;
5176
5225
  min-width: 0;
5177
5226
  }
5227
+ .sib-model-option.current .sib-model-name-text {
5228
+ color: var(--color-accent-primary);
5229
+ }
5230
+ .sib-model-check {
5231
+ display: inline-flex;
5232
+ align-items: center;
5233
+ flex: 0 0 auto;
5234
+ color: var(--color-success, #2da44e);
5235
+ }
5236
+
5237
+ /* Brand-colored tile (provider initial) shown before each model name.
5238
+ Solid brand color + white letter stays legible in both light and dark
5239
+ themes; the neutral hairline keeps dark tiles from melting into the bg. */
5240
+ .sib-vendor-badge {
5241
+ flex: 0 0 auto;
5242
+ width: 1.125rem;
5243
+ height: 1.125rem;
5244
+ border-radius: 5px;
5245
+ display: inline-flex;
5246
+ align-items: center;
5247
+ justify-content: center;
5248
+ font-size: 0.5625rem;
5249
+ font-weight: 700;
5250
+ letter-spacing: 0.02em;
5251
+ line-height: 1;
5252
+ color: #fff;
5253
+ background: var(--vendor-color, #7A8B99);
5254
+ border: 1px solid rgba(127, 127, 127, 0.25);
5255
+ user-select: none;
5256
+ }
5257
+ .sib-vendor-badge svg {
5258
+ width: 0.6875rem;
5259
+ height: 0.6875rem;
5260
+ fill: currentColor;
5261
+ display: block;
5262
+ }
5178
5263
  .sib-model-option .sib-model-name-sub {
5179
5264
  font-size: 0.6875rem;
5180
5265
  color: var(--color-text-secondary);
@@ -6073,11 +6158,13 @@ body {
6073
6158
  align-items: center;
6074
6159
  justify-content: space-between;
6075
6160
  font-size: 1.125rem;
6076
- font-weight: 700;
6077
6161
  color: var(--color-text-primary);
6078
6162
  letter-spacing: -0.3px;
6079
6163
  padding-bottom: 0.5rem;
6080
6164
  }
6165
+ .settings-section-title > span {
6166
+ font-weight: 700;
6167
+ }
6081
6168
  .btn-settings-add {
6082
6169
  display: flex;
6083
6170
  align-items: center;
@@ -6481,6 +6568,7 @@ body {
6481
6568
  cursor: pointer;
6482
6569
  display: flex;
6483
6570
  align-items: center;
6571
+ gap: 0.375rem;
6484
6572
  justify-content: space-between;
6485
6573
  transition: border-color 0.15s ease;
6486
6574
  }
@@ -6501,6 +6589,24 @@ body {
6501
6589
  .custom-select-trigger .placeholder {
6502
6590
  color: var(--color-text-secondary);
6503
6591
  }
6592
+ .custom-select-value {
6593
+ overflow: hidden;
6594
+ text-overflow: ellipsis;
6595
+ white-space: nowrap;
6596
+ }
6597
+ .custom-select-trigger--bare {
6598
+ border: none;
6599
+ background: transparent;
6600
+ border-radius: 0;
6601
+ padding: 0 0.25rem;
6602
+ font-size: 0.6875rem;
6603
+ height: 100%;
6604
+ color: var(--color-text-secondary);
6605
+ }
6606
+ .custom-select-trigger--bare .custom-select-value:not(.placeholder) {
6607
+ color: var(--color-accent-primary);
6608
+ font-weight: 500;
6609
+ }
6504
6610
  .custom-select-arrow {
6505
6611
  width: 0.75rem;
6506
6612
  height: 0.75rem;
@@ -6508,6 +6614,9 @@ body {
6508
6614
  transition: transform 0.2s ease;
6509
6615
  flex-shrink: 0;
6510
6616
  }
6617
+ .custom-select-arrow path {
6618
+ stroke-width: 2.5;
6619
+ }
6511
6620
  .custom-select-trigger.open .custom-select-arrow {
6512
6621
  transform: rotate(180deg);
6513
6622
  }
@@ -6515,7 +6624,9 @@ body {
6515
6624
  position: absolute;
6516
6625
  top: calc(100% + 0.25rem);
6517
6626
  left: 0;
6518
- right: 0;
6627
+ min-width: 100%;
6628
+ width: max-content;
6629
+ max-width: 24rem;
6519
6630
  background: var(--color-bg-secondary);
6520
6631
  border: 1px solid var(--color-border-primary);
6521
6632
  border-radius: 8px;
@@ -6524,16 +6635,22 @@ body {
6524
6635
  overflow-y: auto;
6525
6636
  z-index: 1000;
6526
6637
  display: none;
6638
+ padding: 0.375rem 0;
6527
6639
  }
6528
6640
  .custom-select-dropdown.open {
6529
6641
  display: block;
6530
6642
  }
6531
6643
  .custom-select-option {
6532
6644
  padding: 0.5rem 0.75rem;
6645
+ margin: 0 0.375rem;
6533
6646
  font-size: 0.8125rem;
6534
6647
  color: var(--color-text-primary);
6535
6648
  cursor: pointer;
6649
+ border-radius: 6px;
6536
6650
  transition: background-color 0.15s ease;
6651
+ white-space: nowrap;
6652
+ overflow: hidden;
6653
+ text-overflow: ellipsis;
6537
6654
  }
6538
6655
  .custom-select-option:hover {
6539
6656
  background: var(--color-bg-hover);
@@ -6542,6 +6659,55 @@ body {
6542
6659
  background: var(--color-bg-hover);
6543
6660
  color: var(--color-accent-primary);
6544
6661
  }
6662
+ /* "Custom" entry lives in a fixed footer area outside the panel's own
6663
+ scroll region, so it stays visible without ever scrolling with the list. */
6664
+ .custom-select-dropdown--footer {
6665
+ display: none;
6666
+ flex-direction: column;
6667
+ overflow: hidden;
6668
+ padding: 0.375rem 0 0;
6669
+ }
6670
+ .custom-select-dropdown--footer.open {
6671
+ display: flex;
6672
+ }
6673
+ .custom-select-list {
6674
+ flex: 1 1 auto;
6675
+ min-height: 0;
6676
+ overflow-y: auto;
6677
+ }
6678
+ .custom-select-option-custom {
6679
+ position: relative;
6680
+ flex-shrink: 0;
6681
+ display: flex;
6682
+ align-items: center;
6683
+ gap: 0.5rem;
6684
+ /* Override .custom-select-option's overflow:hidden (ellipsis) so the
6685
+ ::before divider can extend above this row. */
6686
+ overflow: visible;
6687
+ margin: 0.375rem;
6688
+ padding: 0.5rem 0.75rem;
6689
+ border-radius: 6px;
6690
+ background: var(--color-bg-secondary);
6691
+ color: var(--color-text-secondary);
6692
+ }
6693
+ .custom-select-option-custom::before {
6694
+ content: "";
6695
+ position: absolute;
6696
+ top: -0.1875rem;
6697
+ left: 0;
6698
+ right: 0;
6699
+ height: 1px;
6700
+ background: var(--color-border-primary);
6701
+ }
6702
+ .custom-select-option-custom:hover {
6703
+ color: var(--color-text-primary);
6704
+ }
6705
+ .custom-select-option-custom svg {
6706
+ flex-shrink: 0;
6707
+ }
6708
+ .custom-select-option-custom:hover {
6709
+ color: var(--color-text-primary);
6710
+ }
6545
6711
 
6546
6712
  /* Provider recommended badge (inside dropdown option) */
6547
6713
  .provider-badge-recommended {
@@ -6645,25 +6811,13 @@ body {
6645
6811
  color: var(--color-text-tertiary);
6646
6812
  }
6647
6813
  .model-provider-filter {
6648
- height: 2.25rem;
6649
- padding: 0 1.75rem 0 0.625rem;
6650
- border: 1px solid var(--color-border-primary);
6651
- border-radius: 6px;
6652
- background: var(--color-bg-primary);
6653
- color: var(--color-text-primary);
6654
- font-size: 0.8125rem;
6655
- outline: none;
6656
- cursor: pointer;
6657
- transition: border-color 0.15s;
6814
+ width: auto;
6658
6815
  max-width: 12rem;
6659
6816
  min-width: 0;
6660
- appearance: none;
6661
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238b949e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 9l-7 7-7-7'/%3E%3C/svg%3E");
6662
- background-repeat: no-repeat;
6663
- background-position: right 0.625rem center;
6817
+ height: 2.25rem;
6664
6818
  }
6665
- .model-provider-filter:focus {
6666
- border-color: var(--color-accent-primary);
6819
+ .model-provider-filter .custom-select-trigger {
6820
+ height: 100%;
6667
6821
  }
6668
6822
 
6669
6823
  /* ── Grid Model Card ────────────────────────────────────────────────────────── */
@@ -7008,7 +7162,8 @@ body {
7008
7162
  .dp-modal {
7009
7163
  max-width: 820px;
7010
7164
  width: 820px;
7011
- max-height: 85vh;
7165
+ height: min(640px, calc(100vh - 2rem));
7166
+ max-height: none;
7012
7167
  display: flex;
7013
7168
  flex-direction: row;
7014
7169
  padding: 0;
@@ -7061,10 +7216,56 @@ body {
7061
7216
  color: var(--color-text-secondary);
7062
7217
  }
7063
7218
  .dp-sidebar-name {
7219
+ flex: 1;
7220
+ min-width: 0;
7064
7221
  white-space: nowrap;
7065
7222
  overflow: hidden;
7066
7223
  text-overflow: ellipsis;
7067
7224
  }
7225
+ .dp-sidebar-favorite {
7226
+ display: flex;
7227
+ align-items: center;
7228
+ border-radius: 6px;
7229
+ transition: background 0.08s;
7230
+ }
7231
+ .dp-sidebar-favorite:hover,
7232
+ .dp-sidebar-favorite:focus-within {
7233
+ background: var(--color-bg-hover);
7234
+ }
7235
+ .dp-sidebar-favorite-open {
7236
+ min-width: 0;
7237
+ padding-right: 0.25rem;
7238
+ }
7239
+ .dp-sidebar-favorite-open:hover {
7240
+ background: transparent;
7241
+ }
7242
+ .dp-sidebar-favorite-remove {
7243
+ display: inline-flex;
7244
+ align-items: center;
7245
+ justify-content: center;
7246
+ width: 24px;
7247
+ height: 24px;
7248
+ margin-right: 2px;
7249
+ padding: 0;
7250
+ flex-shrink: 0;
7251
+ border: 0;
7252
+ border-radius: 4px;
7253
+ background: transparent;
7254
+ color: var(--color-text-tertiary);
7255
+ cursor: pointer;
7256
+ opacity: 0;
7257
+ pointer-events: none;
7258
+ transition: opacity 0.1s, background 0.1s, color 0.1s;
7259
+ }
7260
+ .dp-sidebar-favorite:hover .dp-sidebar-favorite-remove,
7261
+ .dp-sidebar-favorite:focus-within .dp-sidebar-favorite-remove {
7262
+ opacity: 1;
7263
+ pointer-events: auto;
7264
+ }
7265
+ .dp-sidebar-favorite-remove:hover {
7266
+ background: var(--color-bg-active);
7267
+ color: var(--color-text-primary);
7268
+ }
7068
7269
 
7069
7270
  /* Main column — toolbar + list + footer */
7070
7271
  .dp-main {
@@ -7072,6 +7273,7 @@ body {
7072
7273
  flex-direction: column;
7073
7274
  flex: 1;
7074
7275
  min-width: 0;
7276
+ min-height: 0;
7075
7277
  }
7076
7278
 
7077
7279
  /* Toolbar */
@@ -7092,47 +7294,71 @@ body {
7092
7294
  display: inline-flex;
7093
7295
  align-items: center;
7094
7296
  justify-content: center;
7095
- width: 26px;
7096
- height: 26px;
7297
+ width: 32px;
7298
+ height: 32px;
7097
7299
  padding: 0;
7098
- border: 1px solid rgba(0,0,0,0.18);
7300
+ border: 0;
7099
7301
  border-radius: 5px;
7100
- background: var(--color-bg-primary);
7101
- color: var(--color-text-primary);
7302
+ background: transparent;
7303
+ color: var(--color-text-secondary);
7102
7304
  cursor: pointer;
7103
- transition: background 0.1s;
7305
+ transition: background 0.1s, color 0.1s;
7104
7306
  }
7105
7307
  .dp-nav-btn:hover:not(:disabled) {
7106
7308
  background: var(--color-bg-hover);
7309
+ color: var(--color-text-primary);
7107
7310
  }
7108
7311
  .dp-nav-btn:disabled {
7109
7312
  opacity: 0.3;
7110
7313
  cursor: not-allowed;
7111
7314
  }
7315
+ .dp-favorite-btn {
7316
+ flex-shrink: 0;
7317
+ }
7318
+ .dp-favorite-btn.active {
7319
+ color: var(--color-accent-primary);
7320
+ }
7112
7321
  /* Breadcrumb */
7113
7322
  .dp-breadcrumb {
7114
7323
  display: flex;
7115
7324
  align-items: center;
7116
7325
  gap: 0;
7117
7326
  flex: 1;
7327
+ height: 28px;
7118
7328
  min-width: 0;
7329
+ padding: 1px 4px;
7119
7330
  overflow-x: auto;
7120
7331
  overflow-y: hidden;
7332
+ border: 1px solid transparent;
7333
+ border-radius: 5px;
7334
+ background: var(--color-bg-primary);
7335
+ cursor: text;
7336
+ transition: border-color 0.12s, background 0.12s;
7121
7337
  scrollbar-width: none; /* Firefox */
7122
7338
  -ms-overflow-style: none; /* IE */
7123
7339
  }
7340
+ .dp-breadcrumb.editing {
7341
+ padding: 0;
7342
+ overflow: hidden;
7343
+ border-color: var(--color-accent-primary);
7344
+ background: var(--color-bg-secondary);
7345
+ }
7124
7346
  .dp-breadcrumb::-webkit-scrollbar {
7125
7347
  display: none;
7126
7348
  }
7127
7349
  .dp-bc-seg {
7128
7350
  display: inline-flex;
7129
7351
  align-items: center;
7352
+ height: 22px;
7130
7353
  font-size: 0.8125rem;
7354
+ font-family: inherit;
7131
7355
  color: var(--color-text-secondary);
7132
7356
  cursor: pointer;
7133
7357
  white-space: nowrap;
7134
7358
  padding: 3px 6px;
7359
+ border: 0;
7135
7360
  border-radius: 4px;
7361
+ background: transparent;
7136
7362
  transition: background 0.1s, color 0.1s;
7137
7363
  }
7138
7364
  .dp-bc-seg:hover {
@@ -7142,23 +7368,101 @@ body {
7142
7368
  .dp-bc-current {
7143
7369
  color: var(--color-text-primary);
7144
7370
  font-weight: 500;
7145
- cursor: default;
7146
- }
7147
- .dp-bc-current:hover {
7148
- background: transparent;
7149
7371
  }
7150
7372
  .dp-bc-sep {
7151
7373
  display: inline-flex;
7152
7374
  align-items: center;
7375
+ justify-content: center;
7376
+ width: 22px;
7377
+ height: 22px;
7378
+ padding: 0;
7379
+ border: 0;
7380
+ border-radius: 4px;
7381
+ background: transparent;
7153
7382
  color: var(--color-text-tertiary);
7383
+ cursor: pointer;
7154
7384
  flex-shrink: 0;
7155
7385
  }
7156
- .dp-bc-folder-icon {
7157
- display: inline-flex;
7386
+ .dp-bc-sep svg {
7387
+ width: 12px;
7388
+ height: 12px;
7389
+ transform-origin: center;
7390
+ transition: transform 0.16s ease;
7391
+ }
7392
+ .dp-bc-sep.open svg {
7393
+ transform: rotate(90deg);
7394
+ }
7395
+ .dp-bc-sep:hover,
7396
+ .dp-bc-sep.open {
7397
+ color: var(--color-text-primary);
7398
+ background: var(--color-bg-hover);
7399
+ }
7400
+ @media (prefers-reduced-motion: reduce) {
7401
+ .dp-bc-sep svg {
7402
+ transition: none;
7403
+ }
7404
+ }
7405
+ .dp-address-input {
7406
+ width: 100%;
7407
+ height: 100%;
7408
+ padding: 0 8px;
7409
+ border: 0;
7410
+ outline: 0;
7411
+ background: transparent;
7412
+ color: var(--color-text-primary);
7413
+ font-family: var(--font-mono);
7414
+ font-size: 0.8125rem;
7415
+ }
7416
+ .dp-address-input.invalid {
7417
+ box-shadow: inset 0 0 0 1px var(--color-text-danger, #ef4444);
7418
+ }
7419
+ .dp-bc-menu {
7420
+ position: fixed;
7421
+ z-index: 1100;
7422
+ min-width: 180px;
7423
+ max-width: min(320px, calc(100vw - 16px));
7424
+ max-height: 280px;
7425
+ padding: 4px;
7426
+ overflow-y: auto;
7427
+ border: 1px solid var(--color-border-primary);
7428
+ border-radius: 7px;
7429
+ background: var(--color-bg-primary);
7430
+ box-shadow: var(--shadow-lg);
7431
+ }
7432
+ .dp-bc-menu-item {
7433
+ display: flex;
7158
7434
  align-items: center;
7159
- color: var(--color-text-secondary);
7160
- margin-right: 3px;
7435
+ gap: 0.5rem;
7436
+ width: 100%;
7437
+ padding: 0.4rem 0.5rem;
7438
+ border: 0;
7439
+ border-radius: 5px;
7440
+ background: transparent;
7441
+ color: var(--color-text-primary);
7442
+ cursor: pointer;
7443
+ font: inherit;
7444
+ text-align: left;
7445
+ }
7446
+ .dp-bc-menu-item:hover {
7447
+ background: var(--color-bg-hover);
7448
+ }
7449
+ .dp-bc-menu-icon {
7450
+ display: inline-flex;
7161
7451
  flex-shrink: 0;
7452
+ color: var(--color-text-secondary);
7453
+ }
7454
+ .dp-bc-menu-name {
7455
+ overflow: hidden;
7456
+ text-overflow: ellipsis;
7457
+ white-space: nowrap;
7458
+ }
7459
+ .dp-bc-menu-state {
7460
+ padding: 0.6rem 0.75rem;
7461
+ color: var(--color-text-tertiary);
7462
+ font-size: 0.8125rem;
7463
+ }
7464
+ .dp-bc-menu-error {
7465
+ color: var(--color-text-danger, #ef4444);
7162
7466
  }
7163
7467
 
7164
7468
  /* Column header */
@@ -7198,7 +7502,7 @@ body {
7198
7502
  .dp-list {
7199
7503
  flex: 1;
7200
7504
  overflow-y: auto;
7201
- min-height: 320px;
7505
+ min-height: 0;
7202
7506
  padding-top: 0.35rem;
7203
7507
  background: var(--color-bg-primary);
7204
7508
  }
@@ -8717,29 +9021,14 @@ body {
8717
9021
  flex: 1;
8718
9022
  min-width: 15rem;
8719
9023
  font-size: 0.8125rem;
8720
- padding: 0.4375rem 0.75rem;
8721
- border-radius: 6px;
8722
- border: 1px solid var(--color-border-primary);
8723
- background: var(--color-bg-secondary);
8724
- color: var(--color-text-primary);
8725
- }
8726
- .extensions-sort {
8727
- flex-shrink: 0;
8728
- font-size: 0.8125rem;
8729
- padding: 0.4375rem 2rem 0.4375rem 0.75rem;
9024
+ padding: 0.5375rem 0.75rem;
8730
9025
  border-radius: 6px;
8731
9026
  border: 1px solid var(--color-border-primary);
8732
9027
  background: var(--color-bg-secondary);
8733
9028
  color: var(--color-text-primary);
8734
- cursor: pointer;
8735
- appearance: none;
8736
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23888' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
8737
- background-repeat: no-repeat;
8738
- background-position: right 0.625rem center;
8739
9029
  }
8740
- .extensions-sort:focus {
8741
- outline: none;
8742
- border-color: var(--color-accent, #6366f1);
9030
+ .extensions-select {
9031
+ width: auto;
8743
9032
  }
8744
9033
  #extensions-list {
8745
9034
  display: flex;
@@ -12292,6 +12581,7 @@ body.setup-mode[data-theme="dark"] {
12292
12581
  }
12293
12582
  /* Project filter dropdown */
12294
12583
  .trash-filter-project-wrap {
12584
+ position: relative;
12295
12585
  display: inline-flex;
12296
12586
  align-items: center;
12297
12587
  gap: 0.3rem;
@@ -12311,16 +12601,12 @@ body.setup-mode[data-theme="dark"] {
12311
12601
  flex-shrink: 0;
12312
12602
  pointer-events: none;
12313
12603
  }
12314
- .trash-filter-project-select {
12315
- font-size: 0.6875rem;
12316
- color: inherit;
12317
- background: transparent;
12318
- border: none;
12319
- outline: none;
12320
- cursor: pointer;
12321
- padding: 0;
12604
+ .trash-filter-project-wrap .custom-select-wrapper {
12605
+ /* dropdown anchors to the wrap (icon + trigger) instead, so the panel
12606
+ aligns with the whole control's left edge rather than the icon's right */
12607
+ position: static;
12608
+ min-width: 0;
12322
12609
  max-width: 130px;
12323
- appearance: auto;
12324
12610
  }
12325
12611
  .trash-actions {
12326
12612
  display: flex;
@@ -12574,25 +12860,29 @@ body.setup-mode[data-theme="dark"] {
12574
12860
  }
12575
12861
  .billing-top-bar {
12576
12862
  display: flex;
12577
- justify-content: space-between;
12578
- align-items: center;
12579
- flex-wrap: wrap;
12863
+ flex-direction: column;
12864
+ align-items: stretch;
12580
12865
  gap: 1rem;
12581
12866
  }
12582
12867
  .billing-title-row {
12583
12868
  display: flex;
12584
12869
  align-items: baseline;
12870
+ flex-wrap: wrap;
12585
12871
  gap: 0.75rem;
12872
+ min-width: 0;
12586
12873
  }
12587
12874
  .billing-title-row h2 {
12588
12875
  font-size: 1.5rem;
12589
12876
  font-weight: 500;
12590
12877
  color: var(--color-text-primary);
12591
12878
  margin: 0;
12879
+ flex-shrink: 0;
12592
12880
  }
12593
12881
  .billing-subtitle {
12594
12882
  font-size: 0.875rem;
12595
12883
  color: var(--color-text-secondary);
12884
+ min-width: 0;
12885
+ overflow-wrap: anywhere;
12596
12886
  }
12597
12887
  .billing-controls {
12598
12888
  display: flex;
@@ -12600,6 +12890,14 @@ body.setup-mode[data-theme="dark"] {
12600
12890
  gap: 0.625rem;
12601
12891
  flex-wrap: wrap;
12602
12892
  }
12893
+ .billing-controls .segmented-control {
12894
+ flex: 0 0 auto;
12895
+ }
12896
+ .billing-controls .segmented-control,
12897
+ .billing-model-filter,
12898
+ .billing-share-btn {
12899
+ height: 2rem;
12900
+ }
12603
12901
 
12604
12902
  /* ── Disclaimer notice ──────────────────────────────────────────────── */
12605
12903
  .billing-disclaimer {
@@ -12616,34 +12914,20 @@ body.setup-mode[data-theme="dark"] {
12616
12914
 
12617
12915
  /* ── Model Filter ────────────────────────────────────────────────────── */
12618
12916
  .billing-model-filter {
12619
- padding: 0.5375rem 1.75rem 0.5375rem 0.75rem;
12620
- border: 1px solid var(--color-border-primary);
12621
- border-radius: 8px;
12622
- background: var(--color-bg-secondary);
12623
- color: var(--color-text-primary);
12624
- font-size: 0.8125rem;
12625
- cursor: pointer;
12626
- min-width: 130px;
12627
- appearance: none;
12628
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23888' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
12629
- background-repeat: no-repeat;
12630
- background-position: right 0.625rem center;
12631
- transition: border-color 0.15s ease;
12632
- }
12633
- .billing-model-filter:focus {
12634
- outline: none;
12635
- border-color: var(--color-accent-primary);
12636
- box-shadow: 0 0 0 3px var(--color-accent-soft);
12917
+ width: 16rem;
12918
+ flex: 0 0 16rem;
12919
+ min-width: 0;
12637
12920
  }
12638
- .billing-model-filter option {
12639
- background: var(--color-bg-secondary);
12640
- color: var(--color-text-primary);
12921
+ .billing-model-filter .custom-select-trigger {
12922
+ height: 100%;
12641
12923
  }
12642
12924
 
12643
12925
  /* ── Action Buttons ──────────────────────────────────────────────────── */
12644
12926
  .billing-share-btn {
12645
12927
  display: inline-flex;
12646
12928
  align-items: center;
12929
+ justify-content: center;
12930
+ margin-left: auto;
12647
12931
  gap: 0.375rem;
12648
12932
  padding: 0.4375rem 0.75rem;
12649
12933
  border: 1px solid var(--color-border-primary);
@@ -14747,6 +15031,26 @@ body.setup-mode[data-theme="dark"] {
14747
15031
  #billing-body { padding: 1rem 1rem 1rem; }
14748
15032
  #trash-body { padding: 1rem 1rem 1rem; }
14749
15033
 
15034
+ .billing-controls .segmented-control {
15035
+ flex: 1 0 100%;
15036
+ }
15037
+ .billing-controls .segmented-control__btn {
15038
+ flex: 1 1 0;
15039
+ min-width: 0;
15040
+ }
15041
+ .billing-model-filter {
15042
+ width: auto;
15043
+ flex: 1 1 0;
15044
+ }
15045
+ @media (max-width: 500px) {
15046
+ .billing-controls .segmented-control {
15047
+ overflow-x: auto;
15048
+ }
15049
+ .billing-controls .segmented-control__btn {
15050
+ flex: 1 0 auto;
15051
+ padding-inline: 0.5rem;
15052
+ }
15053
+ }
14750
15054
  .billing-heatmap-row { grid-template-columns: 1fr; }
14751
15055
 
14752
15056
  /* ── MCP page ── */