@luckydraw/cumulus 0.31.49 → 0.31.50

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.31.50
4
+
5
+ - Redesigned the model controls: the header model label now opens a compact popover for picking provider / model / effort, instead of a full-panel modal.
6
+ - New ⚙ Settings button opens a clean, centered modal for managing the available Claude models and provider credentials.
7
+ - Saving a model change refreshes the thread's model dropdown live, no reload needed.
8
+
3
9
  ## v0.31.49
4
10
 
5
11
  - Add, remove, and set the default Claude model — and set the HuggingFace API key — directly from the in-app config panel. Changes take effect on the next turn with no restart.
@@ -1153,13 +1153,102 @@
1153
1153
  '}',
1154
1154
  '.cumulus-config-breadcrumb:hover { color: #ddd; background: #353535; }',
1155
1155
  '.cumulus-config-breadcrumb .sep { color: #555; margin: 0 0.3em; }',
1156
- /* config modal: reuses .cumulus-overlay family; stack the relocated selects */
1157
- '.cumulus-config-modal-row {',
1156
+ '.cumulus-config-breadcrumb::after { content: " \\25BE"; color: #666; font-size: 0.85em; }',
1157
+
1158
+ /* ── Quick model popover (per-thread Provider / Model / Effort) ── */
1159
+ '.cumulus-model-picker { position: relative; display: inline-flex; align-items: center; }',
1160
+ '.cumulus-model-popover {',
1161
+ ' position: absolute; top: calc(100% + 6px); left: 0; z-index: 40;',
1162
+ ' min-width: 236px; background: #262626; border: 1px solid #3d3d3d;',
1163
+ ' border-radius: 8px; box-shadow: 0 10px 30px rgba(0,0,0,0.55); padding: 4px 12px 8px;',
1164
+ '}',
1165
+ '.cumulus-model-popover-row {',
1158
1166
  ' display: flex; align-items: center; justify-content: space-between;',
1159
- ' gap: 10px; padding: 0.6em 0; border-bottom: 1px solid #2f2f2f;',
1167
+ ' gap: 14px; padding: 8px 0; border-bottom: 1px solid #313131;',
1168
+ '}',
1169
+ '.cumulus-model-popover-row:last-child { border-bottom: none; }',
1170
+ '.cumulus-model-popover-label {',
1171
+ ' color: #8c8c8c; font-size: 10px; font-weight: 600;',
1172
+ ' text-transform: uppercase; letter-spacing: 0.06em;',
1160
1173
  '}',
1161
- '.cumulus-config-modal-row:last-child { border-bottom: none; }',
1162
- '.cumulus-config-modal-label { color: #bbb; font-size: 0.9em; }',
1174
+ '.cumulus-model-popover select { max-width: 152px; margin: 0; }',
1175
+
1176
+ /* ── Settings modal (gateway Claude model catalog + provider creds) ── */
1177
+ '.cumulus-settings-backdrop {',
1178
+ ' position: fixed; inset: 0; z-index: 1000; background: rgba(0,0,0,0.55);',
1179
+ ' display: flex; align-items: center; justify-content: center; padding: 20px;',
1180
+ '}',
1181
+ '.cumulus-settings-modal {',
1182
+ ' background: #232323; border: 1px solid #3d3d3d; border-radius: 10px;',
1183
+ ' width: min(520px, 100%); max-height: 82vh; display: flex; flex-direction: column;',
1184
+ ' box-shadow: 0 16px 48px rgba(0,0,0,0.6); overflow: hidden;',
1185
+ '}',
1186
+ '.cumulus-settings-header {',
1187
+ ' display: flex; align-items: flex-start; justify-content: space-between;',
1188
+ ' padding: 14px 18px; border-bottom: 1px solid #333; flex-shrink: 0;',
1189
+ '}',
1190
+ '.cumulus-settings-title { font-weight: 600; font-size: 15px; color: #ededed; }',
1191
+ '.cumulus-settings-subtitle { font-size: 12px; color: #888; margin-top: 3px; }',
1192
+ '.cumulus-settings-body { padding: 6px 18px 10px; overflow-y: auto; flex: 1; }',
1193
+ '.cumulus-settings-footer {',
1194
+ ' display: flex; align-items: center; gap: 12px; padding: 13px 18px;',
1195
+ ' border-top: 1px solid #333; flex-shrink: 0;',
1196
+ '}',
1197
+ '.cumulus-settings-section-label {',
1198
+ ' font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;',
1199
+ ' color: #777; margin: 16px 0 8px;',
1200
+ '}',
1201
+ '.cumulus-settings-body > .cumulus-settings-section-label:first-child { margin-top: 6px; }',
1202
+ '.cumulus-settings-model-row {',
1203
+ ' display: flex; align-items: center; gap: 11px; padding: 9px 11px;',
1204
+ ' border: 1px solid #333; border-radius: 8px; margin-bottom: 7px; background: #1d1d1d;',
1205
+ '}',
1206
+ '.cumulus-settings-model-row.is-default { border-color: #3b5b8c; background: rgba(59,91,140,0.12); }',
1207
+ '.cumulus-settings-default-toggle { display: flex; align-items: center; cursor: pointer; flex-shrink: 0; }',
1208
+ '.cumulus-settings-default-toggle input { cursor: pointer; accent-color: #3b82f6; margin: 0; }',
1209
+ '.cumulus-settings-model-name { flex: 1; min-width: 0; }',
1210
+ '.cumulus-settings-model-label {',
1211
+ ' color: #e6e6e6; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;',
1212
+ '}',
1213
+ '.cumulus-settings-model-id {',
1214
+ ' color: #777; font-size: 11px; font-family: "SF Mono", Consolas, monospace;',
1215
+ ' overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 1px;',
1216
+ '}',
1217
+ '.cumulus-settings-default-badge {',
1218
+ ' display: none; font-size: 10px; font-weight: 600; color: #8ab4f8;',
1219
+ ' background: rgba(59,130,246,0.14); border: 1px solid rgba(59,130,246,0.35);',
1220
+ ' border-radius: 10px; padding: 1px 8px; flex-shrink: 0;',
1221
+ '}',
1222
+ '.cumulus-settings-model-row.is-default .cumulus-settings-default-badge { display: inline-block; }',
1223
+ '.cumulus-settings-model-remove {',
1224
+ ' background: none; border: none; color: #666; cursor: pointer; font-size: 17px;',
1225
+ ' line-height: 1; padding: 0 2px; flex-shrink: 0;',
1226
+ '}',
1227
+ '.cumulus-settings-model-remove:hover { color: #ef4444; }',
1228
+ '.cumulus-settings-add-row { display: flex; gap: 7px; align-items: center; margin-top: 4px; }',
1229
+ '.cumulus-settings-input {',
1230
+ ' background: #1a1a1a; border: 1px solid #3a3a3a; color: #e0e0e0;',
1231
+ ' padding: 7px 9px; border-radius: 6px; font-size: 12px; font-family: inherit; outline: none;',
1232
+ '}',
1233
+ '.cumulus-settings-input:focus { border-color: #3b82f6; }',
1234
+ '.cumulus-settings-input::placeholder { color: #5a5a5a; }',
1235
+ '.cumulus-settings-cred-row { display: flex; align-items: center; gap: 12px; }',
1236
+ '.cumulus-settings-cred-row label { font-size: 12px; color: #bbb; flex-shrink: 0; }',
1237
+ '.cumulus-settings-btn {',
1238
+ ' background: #2a6acf; border: none; color: #fff; font-weight: 600;',
1239
+ ' padding: 8px 18px; border-radius: 6px; font-size: 13px; cursor: pointer; font-family: inherit;',
1240
+ '}',
1241
+ '.cumulus-settings-btn:hover { background: #3a7ae0; }',
1242
+ '.cumulus-settings-btn:disabled { background: #333; color: #777; cursor: not-allowed; }',
1243
+ '.cumulus-settings-add-btn {',
1244
+ ' background: #2f2f2f; border: 1px solid #454545; color: #ddd;',
1245
+ ' padding: 7px 12px; border-radius: 6px; font-size: 12px; cursor: pointer;',
1246
+ ' font-family: inherit; white-space: nowrap;',
1247
+ '}',
1248
+ '.cumulus-settings-add-btn:hover { background: #3a3a3a; border-color: #555; }',
1249
+ '.cumulus-settings-status { font-size: 12px; color: #999; }',
1250
+ '.cumulus-settings-status.success { color: #22c55e; }',
1251
+ '.cumulus-settings-status.error { color: #ef4444; }',
1163
1252
 
1164
1253
  /* ── Context menu (right-click on thread) ── */
1165
1254
  '.cumulus-context-menu {',
@@ -5549,14 +5638,11 @@
5549
5638
  var isClaude = modelSelect.value === 'claude';
5550
5639
  effortSelect.style.display = isClaude ? '' : 'none';
5551
5640
  claudeModelSelect.style.display = isClaude ? '' : 'none';
5552
- // If the config modal is open, hide the whole Model/Effort rows for non-Claude.
5553
- var modal = panel.querySelector('.cumulus-overlay[data-config-modal]');
5554
- if (modal) {
5555
- var mr = modal.querySelector('[data-config-row="model"]');
5556
- var er = modal.querySelector('[data-config-row="effort"]');
5557
- if (mr) mr.style.display = isClaude ? '' : 'none';
5558
- if (er) er.style.display = isClaude ? '' : 'none';
5559
- }
5641
+ // Hide the whole Model/Effort popover rows (label included) for non-Claude providers.
5642
+ var mr = panel.querySelector('[data-config-row="model"]');
5643
+ var er = panel.querySelector('[data-config-row="effort"]');
5644
+ if (mr) mr.style.display = isClaude ? '' : 'none';
5645
+ if (er) er.style.display = isClaude ? '' : 'none';
5560
5646
  updateBreadcrumb();
5561
5647
  }
5562
5648
  updateEffortVisibility();
@@ -5677,114 +5763,161 @@
5677
5763
  xhr.send(JSON.stringify({ claudeModel: newClaudeModel }));
5678
5764
  });
5679
5765
 
5680
- // Breadcrumb opens a modal holding the (relocated) three selects.
5766
+ // ── Quick model popover (per-thread Provider / Model / Effort) ──
5767
+ // Anchored under the breadcrumb; lightweight, not a full-panel modal.
5768
+ var modelPicker = document.createElement('div');
5769
+ modelPicker.className = 'cumulus-model-picker';
5770
+
5771
+ var modelPopover = document.createElement('div');
5772
+ modelPopover.className = 'cumulus-model-popover';
5773
+ modelPopover.setAttribute('data-testid', 'webchat-model-popover');
5774
+ modelPopover.style.display = 'none';
5775
+ function popoverRow(labelText, control, rowKey) {
5776
+ var row = document.createElement('div');
5777
+ row.className = 'cumulus-model-popover-row';
5778
+ if (rowKey) row.setAttribute('data-config-row', rowKey);
5779
+ var lab = document.createElement('span');
5780
+ lab.className = 'cumulus-model-popover-label';
5781
+ lab.textContent = labelText;
5782
+ control.style.display = '';
5783
+ row.appendChild(lab);
5784
+ row.appendChild(control);
5785
+ modelPopover.appendChild(row);
5786
+ return row;
5787
+ }
5788
+ popoverRow('Provider', modelSelect);
5789
+ popoverRow('Model', claudeModelSelect, 'model');
5790
+ popoverRow('Effort', effortSelect, 'effort');
5791
+
5792
+ function closeModelPopover() {
5793
+ modelPopover.style.display = 'none';
5794
+ document.removeEventListener('mousedown', modelPopoverOutside, true);
5795
+ }
5796
+ function modelPopoverOutside(ev) {
5797
+ if (!modelPicker.contains(ev.target)) closeModelPopover();
5798
+ }
5681
5799
  configBreadcrumb.addEventListener('click', function () {
5682
- var existing = panel.querySelector('.cumulus-overlay[data-config-modal]');
5683
- if (existing) {
5684
- existing.remove();
5800
+ if (modelPopover.style.display !== 'none') {
5801
+ closeModelPopover();
5685
5802
  return;
5686
5803
  }
5687
- var overlay = document.createElement('div');
5688
- overlay.className = 'cumulus-overlay';
5689
- overlay.setAttribute('data-config-modal', '1');
5690
- overlay.setAttribute('data-testid', 'webchat-config-modal');
5804
+ modelPopover.style.display = '';
5805
+ updateEffortVisibility();
5806
+ // Defer binding so this opening click doesn't immediately close it.
5807
+ setTimeout(function () {
5808
+ document.addEventListener('mousedown', modelPopoverOutside, true);
5809
+ }, 0);
5810
+ });
5691
5811
 
5692
- var header = document.createElement('div');
5693
- header.className = 'cumulus-overlay-header';
5694
- var title = document.createElement('span');
5695
- title.className = 'cumulus-overlay-title';
5696
- title.textContent = 'Engine';
5697
- header.appendChild(title);
5698
- var closeBtn = document.createElement('button');
5699
- closeBtn.className = 'cumulus-overlay-close';
5700
- closeBtn.textContent = '\xD7';
5701
- closeBtn.addEventListener('click', function () {
5702
- overlay.remove();
5812
+ modelPicker.appendChild(configBreadcrumb);
5813
+ modelPicker.appendChild(modelPopover);
5814
+
5815
+ // ── Settings modal (gateway Claude model catalog + provider credentials) ──
5816
+ // Live-editable via PUT /api/config (task 104) — takes effect on the NEXT turn
5817
+ // with no restart, no JSON edit, no republish. Any valid gateway key.
5818
+ function openSettingsModal() {
5819
+ var backdrop = document.createElement('div');
5820
+ backdrop.className = 'cumulus-settings-backdrop';
5821
+ backdrop.setAttribute('data-testid', 'webchat-settings-modal');
5822
+ var modal = document.createElement('div');
5823
+ modal.className = 'cumulus-settings-modal';
5824
+
5825
+ var mHeader = document.createElement('div');
5826
+ mHeader.className = 'cumulus-settings-header';
5827
+ var mHeaderText = document.createElement('div');
5828
+ var mTitle = document.createElement('div');
5829
+ mTitle.className = 'cumulus-settings-title';
5830
+ mTitle.textContent = 'Gateway settings';
5831
+ var mSub = document.createElement('div');
5832
+ mSub.className = 'cumulus-settings-subtitle';
5833
+ mSub.textContent =
5834
+ 'Available Claude models & provider credentials — applied instantly, no restart';
5835
+ mHeaderText.appendChild(mTitle);
5836
+ mHeaderText.appendChild(mSub);
5837
+ var mClose = document.createElement('button');
5838
+ mClose.className = 'cumulus-overlay-close';
5839
+ mClose.textContent = '\xD7';
5840
+ mClose.setAttribute('data-testid', 'webchat-settings-close');
5841
+ mClose.addEventListener('click', function () {
5842
+ backdrop.remove();
5703
5843
  });
5704
- header.appendChild(closeBtn);
5705
- overlay.appendChild(header);
5844
+ mHeader.appendChild(mHeaderText);
5845
+ mHeader.appendChild(mClose);
5846
+ modal.appendChild(mHeader);
5706
5847
 
5707
5848
  var body = document.createElement('div');
5708
- body.className = 'cumulus-overlay-body';
5709
- function addRow(labelText, control) {
5710
- var row = document.createElement('div');
5711
- row.className = 'cumulus-config-modal-row';
5712
- var lab = document.createElement('span');
5713
- lab.className = 'cumulus-config-modal-label';
5714
- lab.textContent = labelText;
5715
- row.appendChild(lab);
5716
- control.style.display = '';
5717
- row.appendChild(control);
5718
- body.appendChild(row);
5719
- return row;
5720
- }
5721
- addRow('Provider', modelSelect);
5722
- addRow('Model', claudeModelSelect).setAttribute('data-config-row', 'model');
5723
- addRow('Effort', effortSelect).setAttribute('data-config-row', 'effort');
5724
-
5725
- // ── Gateway Claude model catalog + provider credential (task 104) ──
5726
- // Live-editable via PUT /api/config — takes effect on the NEXT turn with
5727
- // no restart, no JSON edit, no republish. Any valid gateway key.
5728
- var inputCss =
5729
- 'background:#2a2a2a;border:1px solid #3a3a3a;color:#ddd;' +
5730
- 'padding:0.25em 0.4em;border-radius:4px;font-size:0.78em;outline:none;';
5731
- var gwTitle = document.createElement('div');
5732
- gwTitle.className = 'cumulus-config-modal-label';
5733
- gwTitle.style.cssText =
5734
- 'margin-top:14px;padding-top:10px;border-top:1px solid #333;font-weight:600;color:#ddd;';
5735
- gwTitle.textContent = 'Gateway Claude models';
5736
- body.appendChild(gwTitle);
5849
+ body.className = 'cumulus-settings-body';
5850
+
5851
+ var modelsLabel = document.createElement('div');
5852
+ modelsLabel.className = 'cumulus-settings-section-label';
5853
+ modelsLabel.textContent = 'Claude models';
5854
+ body.appendChild(modelsLabel);
5737
5855
 
5738
5856
  var gwList = document.createElement('div');
5739
5857
  gwList.setAttribute('data-testid', 'webchat-gateway-models');
5740
5858
  body.appendChild(gwList);
5741
5859
 
5742
5860
  var addWrap = document.createElement('div');
5743
- addWrap.className = 'cumulus-config-modal-row';
5861
+ addWrap.className = 'cumulus-settings-add-row';
5744
5862
  var addId = document.createElement('input');
5745
5863
  addId.type = 'text';
5864
+ addId.className = 'cumulus-settings-input';
5746
5865
  addId.placeholder = 'model id (e.g. claude-opus-5[1m])';
5747
5866
  addId.setAttribute('data-testid', 'webchat-gw-add-id');
5748
- addId.style.cssText = 'flex:1;min-width:0;' + inputCss;
5867
+ addId.style.cssText = 'flex:1;min-width:0;';
5749
5868
  var addLabel = document.createElement('input');
5750
5869
  addLabel.type = 'text';
5870
+ addLabel.className = 'cumulus-settings-input';
5751
5871
  addLabel.placeholder = 'label';
5752
5872
  addLabel.setAttribute('data-testid', 'webchat-gw-add-label');
5753
- addLabel.style.cssText = 'width:84px;' + inputCss;
5873
+ addLabel.style.cssText = 'width:96px;';
5754
5874
  var addBtn = document.createElement('button');
5755
- addBtn.textContent = 'Add';
5756
- addBtn.className = 'cumulus-panel-action-btn';
5875
+ addBtn.textContent = '+ Add';
5876
+ addBtn.className = 'cumulus-settings-add-btn';
5757
5877
  addBtn.setAttribute('data-testid', 'webchat-gw-add-btn');
5758
5878
  addWrap.appendChild(addId);
5759
5879
  addWrap.appendChild(addLabel);
5760
5880
  addWrap.appendChild(addBtn);
5761
5881
  body.appendChild(addWrap);
5762
5882
 
5883
+ var credLabel = document.createElement('div');
5884
+ credLabel.className = 'cumulus-settings-section-label';
5885
+ credLabel.textContent = 'Provider credentials';
5886
+ body.appendChild(credLabel);
5887
+
5763
5888
  var credRow = document.createElement('div');
5764
- credRow.className = 'cumulus-config-modal-row';
5765
- var credLab = document.createElement('span');
5766
- credLab.className = 'cumulus-config-modal-label';
5889
+ credRow.className = 'cumulus-settings-cred-row';
5890
+ var credLab = document.createElement('label');
5767
5891
  credLab.textContent = 'HuggingFace key';
5768
5892
  var credInput = document.createElement('input');
5769
5893
  credInput.type = 'text';
5894
+ credInput.className = 'cumulus-settings-input';
5770
5895
  credInput.placeholder = '(unset)';
5771
5896
  credInput.setAttribute('data-testid', 'webchat-gw-hfkey');
5772
- credInput.style.cssText = 'width:150px;' + inputCss;
5897
+ credInput.style.cssText = 'flex:1;min-width:0;';
5773
5898
  credRow.appendChild(credLab);
5774
5899
  credRow.appendChild(credInput);
5775
5900
  body.appendChild(credRow);
5776
5901
 
5777
- var gwFooter = document.createElement('div');
5778
- gwFooter.className = 'cumulus-overlay-footer';
5902
+ modal.appendChild(body);
5903
+
5904
+ var footer = document.createElement('div');
5905
+ footer.className = 'cumulus-settings-footer';
5779
5906
  var saveBtn = document.createElement('button');
5780
- saveBtn.textContent = 'Save gateway config';
5781
- saveBtn.className = 'cumulus-panel-action-btn';
5907
+ saveBtn.textContent = 'Save';
5908
+ saveBtn.className = 'cumulus-settings-btn';
5782
5909
  saveBtn.setAttribute('data-testid', 'webchat-gw-save');
5783
5910
  var gwStatus = document.createElement('span');
5784
- gwStatus.className = 'cumulus-overlay-status';
5785
- gwFooter.appendChild(saveBtn);
5786
- gwFooter.appendChild(gwStatus);
5787
- body.appendChild(gwFooter);
5911
+ gwStatus.className = 'cumulus-settings-status';
5912
+ footer.appendChild(saveBtn);
5913
+ footer.appendChild(gwStatus);
5914
+ modal.appendChild(footer);
5915
+
5916
+ backdrop.appendChild(modal);
5917
+ backdrop.addEventListener('click', function (e) {
5918
+ if (e.target === backdrop) backdrop.remove();
5919
+ });
5920
+ document.body.appendChild(backdrop);
5788
5921
 
5789
5922
  var gwModels = []; // [{id,label,default}]
5790
5923
  function renderGwModels() {
@@ -5798,15 +5931,12 @@
5798
5931
  }
5799
5932
  gwModels.forEach(function (m, idx) {
5800
5933
  var row = document.createElement('div');
5801
- row.className = 'cumulus-config-modal-row';
5934
+ row.className = 'cumulus-settings-model-row' + (m.default ? ' is-default' : '');
5802
5935
  row.setAttribute('data-gw-model', m.id);
5803
- var name = document.createElement('span');
5804
- name.className = 'cumulus-config-modal-label';
5805
- name.textContent = (m.label || m.id) + ' (' + m.id + ')';
5806
- name.style.cssText = 'flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;';
5936
+
5807
5937
  var defWrap = document.createElement('label');
5808
- defWrap.style.cssText =
5809
- 'font-size:0.75em;color:#aaa;display:flex;align-items:center;gap:3px;white-space:nowrap;';
5938
+ defWrap.className = 'cumulus-settings-default-toggle';
5939
+ defWrap.title = 'Set as default';
5810
5940
  var def = document.createElement('input');
5811
5941
  def.type = 'radio';
5812
5942
  def.name = 'gw-default';
@@ -5817,12 +5947,28 @@
5817
5947
  x.default = false;
5818
5948
  });
5819
5949
  m.default = true;
5950
+ renderGwModels();
5820
5951
  });
5821
5952
  defWrap.appendChild(def);
5822
- defWrap.appendChild(document.createTextNode('default'));
5953
+
5954
+ var name = document.createElement('div');
5955
+ name.className = 'cumulus-settings-model-name';
5956
+ var nameLabel = document.createElement('div');
5957
+ nameLabel.className = 'cumulus-settings-model-label';
5958
+ nameLabel.textContent = m.label || m.id;
5959
+ var nameId = document.createElement('div');
5960
+ nameId.className = 'cumulus-settings-model-id';
5961
+ nameId.textContent = m.id;
5962
+ name.appendChild(nameLabel);
5963
+ name.appendChild(nameId);
5964
+
5965
+ var badge = document.createElement('span');
5966
+ badge.className = 'cumulus-settings-default-badge';
5967
+ badge.textContent = 'default';
5968
+
5823
5969
  var rm = document.createElement('button');
5970
+ rm.className = 'cumulus-settings-model-remove';
5824
5971
  rm.textContent = '\xD7';
5825
- rm.className = 'cumulus-overlay-close';
5826
5972
  rm.title = 'Remove';
5827
5973
  rm.setAttribute('data-testid', 'webchat-gw-remove-' + idx);
5828
5974
  rm.addEventListener('click', function () {
@@ -5831,8 +5977,10 @@
5831
5977
  if (wasDefault && gwModels.length) gwModels[0].default = true;
5832
5978
  renderGwModels();
5833
5979
  });
5834
- row.appendChild(name);
5980
+
5835
5981
  row.appendChild(defWrap);
5982
+ row.appendChild(name);
5983
+ row.appendChild(badge);
5836
5984
  row.appendChild(rm);
5837
5985
  gwList.appendChild(row);
5838
5986
  });
@@ -5847,20 +5995,20 @@
5847
5995
  })
5848
5996
  ) {
5849
5997
  gwStatus.textContent = 'Already in the list';
5850
- gwStatus.className = 'cumulus-overlay-status error';
5998
+ gwStatus.className = 'cumulus-settings-status error';
5851
5999
  return;
5852
6000
  }
5853
6001
  gwModels.push({ id: id, label: label, default: gwModels.length === 0 });
5854
6002
  addId.value = '';
5855
6003
  addLabel.value = '';
5856
6004
  gwStatus.textContent = '';
5857
- gwStatus.className = 'cumulus-overlay-status';
6005
+ gwStatus.className = 'cumulus-settings-status';
5858
6006
  renderGwModels();
5859
6007
  });
5860
6008
  saveBtn.addEventListener('click', function () {
5861
6009
  saveBtn.disabled = true;
5862
6010
  gwStatus.textContent = 'Saving…';
5863
- gwStatus.className = 'cumulus-overlay-status';
6011
+ gwStatus.className = 'cumulus-settings-status';
5864
6012
  var payload = {
5865
6013
  claudeModels: gwModels.map(function (m) {
5866
6014
  return { id: m.id, label: m.label, default: !!m.default };
@@ -5878,16 +6026,26 @@
5878
6026
  saveBtn.disabled = false;
5879
6027
  if (sx.status === 200) {
5880
6028
  gwStatus.textContent = 'Saved — applies to new turns immediately';
5881
- gwStatus.className = 'cumulus-overlay-status success';
6029
+ gwStatus.className = 'cumulus-settings-status success';
5882
6030
  try {
5883
6031
  var r = JSON.parse(sx.responseText);
5884
6032
  if (r && r.hfApiKey !== undefined) credInput.value = r.hfApiKey;
5885
6033
  } catch (e) {
5886
6034
  /* ignore */
5887
6035
  }
6036
+ // Live-refresh this thread's Claude model dropdown without a reload.
6037
+ var prevSel = claudeModelSelect.value;
6038
+ populateClaudeModels(gwModels);
6039
+ for (var pi = 0; pi < claudeModelSelect.options.length; pi++) {
6040
+ if (claudeModelSelect.options[pi].value === prevSel) {
6041
+ claudeModelSelect.value = prevSel;
6042
+ break;
6043
+ }
6044
+ }
6045
+ updateBreadcrumb();
5888
6046
  } else {
5889
6047
  gwStatus.textContent = 'Error ' + sx.status;
5890
- gwStatus.className = 'cumulus-overlay-status error';
6048
+ gwStatus.className = 'cumulus-settings-status error';
5891
6049
  }
5892
6050
  };
5893
6051
  sx.send(JSON.stringify(payload));
@@ -5911,25 +6069,27 @@
5911
6069
  }
5912
6070
  } else {
5913
6071
  gwStatus.textContent = 'Load failed (' + gx.status + ')';
5914
- gwStatus.className = 'cumulus-overlay-status error';
6072
+ gwStatus.className = 'cumulus-settings-status error';
5915
6073
  }
5916
6074
  };
5917
6075
  gx.send();
5918
6076
  })();
6077
+ }
5919
6078
 
5920
- overlay.appendChild(body);
5921
-
5922
- panel.appendChild(overlay);
5923
- // Reflect Claude-only row visibility now that the rows exist in the DOM.
5924
- updateEffortVisibility();
5925
- });
5926
-
5927
- panelHeader.appendChild(configBreadcrumb);
6079
+ panelHeader.appendChild(modelPicker);
5928
6080
 
5929
- // Action buttons (include + revert)
6081
+ // Action buttons (settings + include + revert)
5930
6082
  var actions = document.createElement('div');
5931
6083
  actions.className = 'cumulus-panel-actions';
5932
6084
 
6085
+ var settingsBtn = document.createElement('button');
6086
+ settingsBtn.className = 'cumulus-panel-action-btn';
6087
+ settingsBtn.setAttribute('data-testid', 'webchat-settings-btn');
6088
+ settingsBtn.setAttribute('title', 'Settings — configure available models');
6089
+ settingsBtn.textContent = '⚙'; // gear
6090
+ settingsBtn.addEventListener('click', openSettingsModal);
6091
+ actions.appendChild(settingsBtn);
6092
+
5933
6093
  var includeBtn = document.createElement('button');
5934
6094
  includeBtn.className = 'cumulus-panel-action-btn';
5935
6095
  includeBtn.setAttribute('data-testid', 'webchat-include-btn');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luckydraw/cumulus",
3
- "version": "0.31.49",
3
+ "version": "0.31.50",
4
4
  "description": "RLM-based CLI chat wrapper for Claude with external history context management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",