@luckydraw/cumulus 0.31.48 → 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.
@@ -1145,7 +1145,7 @@
1145
1145
  '.cumulus-effort-select option { background: #2a2a2a; color: #ccc; }',
1146
1146
  '.cumulus-panel-action-btn.active { color: #e0e0e0; border-color: #0066cc; background: rgba(0,102,204,0.12); }',
1147
1147
 
1148
- /* ── Config breadcrumb (replaces the 3 selects) + disposition picker ── */
1148
+ /* ── Config breadcrumb (replaces the 3 selects) ── */
1149
1149
  '.cumulus-config-breadcrumb {',
1150
1150
  ' background: none; border: none; cursor: pointer;',
1151
1151
  ' color: #aaa; font-size: 0.8em; padding: 0.2em 0.4em; border-radius: 4px;',
@@ -1153,21 +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
- '.cumulus-disposition-select {',
1157
- ' background: #2a2a2a; border: 1px solid #3a3a3a; color: #aaa;',
1158
- ' padding: 0.25em 0.4em; border-radius: 4px; cursor: pointer;',
1159
- ' font-size: 0.78em; outline: none;',
1160
- '}',
1161
- '.cumulus-disposition-select:hover { border-color: #666; color: #ddd; }',
1162
- '.cumulus-disposition-select:focus { border-color: #0066cc; }',
1163
- '.cumulus-disposition-select option { background: #2a2a2a; color: #ccc; }',
1164
- /* config modal: reuses .cumulus-overlay family; stack the relocated selects */
1165
- '.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 {',
1166
1166
  ' display: flex; align-items: center; justify-content: space-between;',
1167
- ' 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;',
1168
1173
  '}',
1169
- '.cumulus-config-modal-row:last-child { border-bottom: none; }',
1170
- '.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; }',
1171
1252
 
1172
1253
  /* ── Context menu (right-click on thread) ── */
1173
1254
  '.cumulus-context-menu {',
@@ -5525,35 +5606,6 @@
5525
5606
  }
5526
5607
  populateClaudeModels(null);
5527
5608
 
5528
- // Disposition picker ("mind" — creative update). UI scaffold (task 085):
5529
- // persists the `mind` config field but injects nothing into prompts yet.
5530
- var MIND_OPTIONS = [
5531
- { id: 'neutral', label: 'Neutral' },
5532
- { id: 'expansive', label: 'Brainstorm' },
5533
- { id: 'restrictive', label: 'Focus' },
5534
- { id: 'conservative', label: 'Step-back' },
5535
- { id: 'blase', label: 'Trade-offs' },
5536
- ];
5537
- var dispositionSelect = document.createElement('select');
5538
- dispositionSelect.className = 'cumulus-disposition-select';
5539
- dispositionSelect.setAttribute('data-testid', 'webchat-disposition-select');
5540
- dispositionSelect.setAttribute('data-thread-disposition', threadName);
5541
- dispositionSelect.setAttribute('title', 'Thread disposition');
5542
- MIND_OPTIONS.forEach(function (m) {
5543
- var opt = document.createElement('option');
5544
- opt.value = m.id;
5545
- opt.textContent = m.label;
5546
- dispositionSelect.appendChild(opt);
5547
- });
5548
- dispositionSelect.value = 'neutral';
5549
- dispositionSelect.addEventListener('change', function () {
5550
- var xhr = new XMLHttpRequest();
5551
- xhr.open('PUT', '/api/thread/' + encodeURIComponent(threadName) + '/config');
5552
- xhr.setRequestHeader('Content-Type', 'application/json');
5553
- xhr.setRequestHeader('X-API-Key', activeApiKey);
5554
- xhr.send(JSON.stringify({ mind: dispositionSelect.value }));
5555
- });
5556
-
5557
5609
  // Breadcrumb link — reflects the live engine/model/effort as
5558
5610
  // "Provider / Model / effort". Clicking opens the config modal.
5559
5611
  var configBreadcrumb = document.createElement('button');
@@ -5586,14 +5638,11 @@
5586
5638
  var isClaude = modelSelect.value === 'claude';
5587
5639
  effortSelect.style.display = isClaude ? '' : 'none';
5588
5640
  claudeModelSelect.style.display = isClaude ? '' : 'none';
5589
- // If the config modal is open, hide the whole Model/Effort rows for non-Claude.
5590
- var modal = panel.querySelector('.cumulus-overlay[data-config-modal]');
5591
- if (modal) {
5592
- var mr = modal.querySelector('[data-config-row="model"]');
5593
- var er = modal.querySelector('[data-config-row="effort"]');
5594
- if (mr) mr.style.display = isClaude ? '' : 'none';
5595
- if (er) er.style.display = isClaude ? '' : 'none';
5596
- }
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';
5597
5646
  updateBreadcrumb();
5598
5647
  }
5599
5648
  updateEffortVisibility();
@@ -5669,15 +5718,6 @@
5669
5718
  }
5670
5719
  }
5671
5720
  }
5672
- // Load saved disposition (defaults to 'neutral' if absent)
5673
- if (
5674
- cfg.mind &&
5675
- MIND_OPTIONS.some(function (m) {
5676
- return m.id === cfg.mind;
5677
- })
5678
- ) {
5679
- dispositionSelect.value = cfg.mind;
5680
- }
5681
5721
  updateEffortVisibility();
5682
5722
  } catch (e) {
5683
5723
  /* ignore */
@@ -5723,64 +5763,333 @@
5723
5763
  xhr.send(JSON.stringify({ claudeModel: newClaudeModel }));
5724
5764
  });
5725
5765
 
5726
- // 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
+ }
5727
5799
  configBreadcrumb.addEventListener('click', function () {
5728
- var existing = panel.querySelector('.cumulus-overlay[data-config-modal]');
5729
- if (existing) {
5730
- existing.remove();
5800
+ if (modelPopover.style.display !== 'none') {
5801
+ closeModelPopover();
5731
5802
  return;
5732
5803
  }
5733
- var overlay = document.createElement('div');
5734
- overlay.className = 'cumulus-overlay';
5735
- overlay.setAttribute('data-config-modal', '1');
5736
- 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
+ });
5737
5811
 
5738
- var header = document.createElement('div');
5739
- header.className = 'cumulus-overlay-header';
5740
- var title = document.createElement('span');
5741
- title.className = 'cumulus-overlay-title';
5742
- title.textContent = 'Engine';
5743
- header.appendChild(title);
5744
- var closeBtn = document.createElement('button');
5745
- closeBtn.className = 'cumulus-overlay-close';
5746
- closeBtn.textContent = '\xD7';
5747
- closeBtn.addEventListener('click', function () {
5748
- 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();
5749
5843
  });
5750
- header.appendChild(closeBtn);
5751
- overlay.appendChild(header);
5844
+ mHeader.appendChild(mHeaderText);
5845
+ mHeader.appendChild(mClose);
5846
+ modal.appendChild(mHeader);
5752
5847
 
5753
5848
  var body = document.createElement('div');
5754
- body.className = 'cumulus-overlay-body';
5755
- function addRow(labelText, control) {
5756
- var row = document.createElement('div');
5757
- row.className = 'cumulus-config-modal-row';
5758
- var lab = document.createElement('span');
5759
- lab.className = 'cumulus-config-modal-label';
5760
- lab.textContent = labelText;
5761
- row.appendChild(lab);
5762
- control.style.display = '';
5763
- row.appendChild(control);
5764
- body.appendChild(row);
5765
- return row;
5766
- }
5767
- addRow('Provider', modelSelect);
5768
- addRow('Model', claudeModelSelect).setAttribute('data-config-row', 'model');
5769
- addRow('Effort', effortSelect).setAttribute('data-config-row', 'effort');
5770
- overlay.appendChild(body);
5771
-
5772
- panel.appendChild(overlay);
5773
- // Reflect Claude-only row visibility now that the rows exist in the DOM.
5774
- updateEffortVisibility();
5775
- });
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);
5855
+
5856
+ var gwList = document.createElement('div');
5857
+ gwList.setAttribute('data-testid', 'webchat-gateway-models');
5858
+ body.appendChild(gwList);
5859
+
5860
+ var addWrap = document.createElement('div');
5861
+ addWrap.className = 'cumulus-settings-add-row';
5862
+ var addId = document.createElement('input');
5863
+ addId.type = 'text';
5864
+ addId.className = 'cumulus-settings-input';
5865
+ addId.placeholder = 'model id (e.g. claude-opus-5[1m])';
5866
+ addId.setAttribute('data-testid', 'webchat-gw-add-id');
5867
+ addId.style.cssText = 'flex:1;min-width:0;';
5868
+ var addLabel = document.createElement('input');
5869
+ addLabel.type = 'text';
5870
+ addLabel.className = 'cumulus-settings-input';
5871
+ addLabel.placeholder = 'label';
5872
+ addLabel.setAttribute('data-testid', 'webchat-gw-add-label');
5873
+ addLabel.style.cssText = 'width:96px;';
5874
+ var addBtn = document.createElement('button');
5875
+ addBtn.textContent = '+ Add';
5876
+ addBtn.className = 'cumulus-settings-add-btn';
5877
+ addBtn.setAttribute('data-testid', 'webchat-gw-add-btn');
5878
+ addWrap.appendChild(addId);
5879
+ addWrap.appendChild(addLabel);
5880
+ addWrap.appendChild(addBtn);
5881
+ body.appendChild(addWrap);
5882
+
5883
+ var credLabel = document.createElement('div');
5884
+ credLabel.className = 'cumulus-settings-section-label';
5885
+ credLabel.textContent = 'Provider credentials';
5886
+ body.appendChild(credLabel);
5887
+
5888
+ var credRow = document.createElement('div');
5889
+ credRow.className = 'cumulus-settings-cred-row';
5890
+ var credLab = document.createElement('label');
5891
+ credLab.textContent = 'HuggingFace key';
5892
+ var credInput = document.createElement('input');
5893
+ credInput.type = 'text';
5894
+ credInput.className = 'cumulus-settings-input';
5895
+ credInput.placeholder = '(unset)';
5896
+ credInput.setAttribute('data-testid', 'webchat-gw-hfkey');
5897
+ credInput.style.cssText = 'flex:1;min-width:0;';
5898
+ credRow.appendChild(credLab);
5899
+ credRow.appendChild(credInput);
5900
+ body.appendChild(credRow);
5901
+
5902
+ modal.appendChild(body);
5903
+
5904
+ var footer = document.createElement('div');
5905
+ footer.className = 'cumulus-settings-footer';
5906
+ var saveBtn = document.createElement('button');
5907
+ saveBtn.textContent = 'Save';
5908
+ saveBtn.className = 'cumulus-settings-btn';
5909
+ saveBtn.setAttribute('data-testid', 'webchat-gw-save');
5910
+ var gwStatus = document.createElement('span');
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);
5921
+
5922
+ var gwModels = []; // [{id,label,default}]
5923
+ function renderGwModels() {
5924
+ gwList.innerHTML = '';
5925
+ if (!gwModels.length) {
5926
+ var empty = document.createElement('div');
5927
+ empty.className = 'cumulus-overlay-empty';
5928
+ empty.textContent = 'No models configured — add one below.';
5929
+ gwList.appendChild(empty);
5930
+ return;
5931
+ }
5932
+ gwModels.forEach(function (m, idx) {
5933
+ var row = document.createElement('div');
5934
+ row.className = 'cumulus-settings-model-row' + (m.default ? ' is-default' : '');
5935
+ row.setAttribute('data-gw-model', m.id);
5936
+
5937
+ var defWrap = document.createElement('label');
5938
+ defWrap.className = 'cumulus-settings-default-toggle';
5939
+ defWrap.title = 'Set as default';
5940
+ var def = document.createElement('input');
5941
+ def.type = 'radio';
5942
+ def.name = 'gw-default';
5943
+ def.checked = !!m.default;
5944
+ def.setAttribute('data-testid', 'webchat-gw-default-' + idx);
5945
+ def.addEventListener('change', function () {
5946
+ gwModels.forEach(function (x) {
5947
+ x.default = false;
5948
+ });
5949
+ m.default = true;
5950
+ renderGwModels();
5951
+ });
5952
+ defWrap.appendChild(def);
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
+
5969
+ var rm = document.createElement('button');
5970
+ rm.className = 'cumulus-settings-model-remove';
5971
+ rm.textContent = '\xD7';
5972
+ rm.title = 'Remove';
5973
+ rm.setAttribute('data-testid', 'webchat-gw-remove-' + idx);
5974
+ rm.addEventListener('click', function () {
5975
+ var wasDefault = m.default;
5976
+ gwModels.splice(idx, 1);
5977
+ if (wasDefault && gwModels.length) gwModels[0].default = true;
5978
+ renderGwModels();
5979
+ });
5776
5980
 
5777
- panelHeader.appendChild(configBreadcrumb);
5778
- panelHeader.appendChild(dispositionSelect);
5981
+ row.appendChild(defWrap);
5982
+ row.appendChild(name);
5983
+ row.appendChild(badge);
5984
+ row.appendChild(rm);
5985
+ gwList.appendChild(row);
5986
+ });
5987
+ }
5988
+ addBtn.addEventListener('click', function () {
5989
+ var id = (addId.value || '').trim();
5990
+ if (!id) return;
5991
+ var label = (addLabel.value || '').trim() || id;
5992
+ if (
5993
+ gwModels.some(function (x) {
5994
+ return x.id === id;
5995
+ })
5996
+ ) {
5997
+ gwStatus.textContent = 'Already in the list';
5998
+ gwStatus.className = 'cumulus-settings-status error';
5999
+ return;
6000
+ }
6001
+ gwModels.push({ id: id, label: label, default: gwModels.length === 0 });
6002
+ addId.value = '';
6003
+ addLabel.value = '';
6004
+ gwStatus.textContent = '';
6005
+ gwStatus.className = 'cumulus-settings-status';
6006
+ renderGwModels();
6007
+ });
6008
+ saveBtn.addEventListener('click', function () {
6009
+ saveBtn.disabled = true;
6010
+ gwStatus.textContent = 'Saving…';
6011
+ gwStatus.className = 'cumulus-settings-status';
6012
+ var payload = {
6013
+ claudeModels: gwModels.map(function (m) {
6014
+ return { id: m.id, label: m.label, default: !!m.default };
6015
+ }),
6016
+ };
6017
+ // Only send a REAL key — a masked value (bullets) means "unchanged".
6018
+ var cred = (credInput.value || '').trim();
6019
+ if (cred && cred.indexOf('•') === -1) payload.hfApiKey = cred;
6020
+ var sx = new XMLHttpRequest();
6021
+ sx.open('PUT', '/api/config');
6022
+ sx.setRequestHeader('Content-Type', 'application/json');
6023
+ sx.setRequestHeader('X-API-Key', activeApiKey);
6024
+ sx.onreadystatechange = function () {
6025
+ if (sx.readyState !== 4) return;
6026
+ saveBtn.disabled = false;
6027
+ if (sx.status === 200) {
6028
+ gwStatus.textContent = 'Saved — applies to new turns immediately';
6029
+ gwStatus.className = 'cumulus-settings-status success';
6030
+ try {
6031
+ var r = JSON.parse(sx.responseText);
6032
+ if (r && r.hfApiKey !== undefined) credInput.value = r.hfApiKey;
6033
+ } catch (e) {
6034
+ /* ignore */
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();
6046
+ } else {
6047
+ gwStatus.textContent = 'Error ' + sx.status;
6048
+ gwStatus.className = 'cumulus-settings-status error';
6049
+ }
6050
+ };
6051
+ sx.send(JSON.stringify(payload));
6052
+ });
6053
+ (function loadGatewayConfig() {
6054
+ var gx = new XMLHttpRequest();
6055
+ gx.open('GET', '/api/config');
6056
+ gx.setRequestHeader('X-API-Key', activeApiKey);
6057
+ gx.onreadystatechange = function () {
6058
+ if (gx.readyState !== 4) return;
6059
+ if (gx.status === 200) {
6060
+ try {
6061
+ var r = JSON.parse(gx.responseText);
6062
+ gwModels = (r.claudeModels || []).map(function (m) {
6063
+ return { id: m.id, label: m.label, default: !!m.default };
6064
+ });
6065
+ credInput.value = r.hfApiKey || '';
6066
+ renderGwModels();
6067
+ } catch (e) {
6068
+ /* ignore */
6069
+ }
6070
+ } else {
6071
+ gwStatus.textContent = 'Load failed (' + gx.status + ')';
6072
+ gwStatus.className = 'cumulus-settings-status error';
6073
+ }
6074
+ };
6075
+ gx.send();
6076
+ })();
6077
+ }
6078
+
6079
+ panelHeader.appendChild(modelPicker);
5779
6080
 
5780
- // Action buttons (include + revert)
6081
+ // Action buttons (settings + include + revert)
5781
6082
  var actions = document.createElement('div');
5782
6083
  actions.className = 'cumulus-panel-actions';
5783
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
+
5784
6093
  var includeBtn = document.createElement('button');
5785
6094
  includeBtn.className = 'cumulus-panel-action-btn';
5786
6095
  includeBtn.setAttribute('data-testid', 'webchat-include-btn');
@@ -19,8 +19,6 @@ export interface CumulusConfig {
19
19
  effort?: 'low' | 'medium' | 'high' | 'xhigh' | 'max';
20
20
  /** Claude CLI model id (only applied when model is "claude"), passed as --model. e.g. "claude-opus-5[1m]" | "claude-sonnet-5[1m]" */
21
21
  claudeModel?: string;
22
- /** Thread disposition / "mind" (creative update). UI scaffold (task 085): persisted but NOT yet consumed during prompt assembly. e.g. "neutral" | "expansive" | "restrictive" | "conservative" | "blase" */
23
- mind?: string;
24
22
  /** Prompt capture (task 088): serialize each constructed prompt to the .prompts/ sidecar. Default ON; set false to disable */
25
23
  promptCapture?: boolean;
26
24
  /** Scheduled triggers for this thread */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}