@luckydraw/cumulus 0.31.49 → 0.31.51

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