hmgr 0.0.53 → 0.0.54

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.
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "fassung": 1,
3
3
  "versionen": {
4
+ "0.0.54": [
5
+ "Der Dialog „Einhängen“ eines MCP-Servers hat jetzt ein Suchfeld. Tippen filtert die Orte nach Name und Pfad, so findest du ein Arbeitsverzeichnis ohne langes Scrollen."
6
+ ],
4
7
  "0.0.53": [
5
8
  "MCP-Server stehen an der Ordnerkarte jetzt in derselben Tabelle wie die Skills, mit dem Zeichen des Harness davor. Ein Tooltip erklärt, warum ein Server für Hermes fehlt: Hermes liest MCP-Server nur im Home oder in einem Profil, nicht pro Ordner. `hmgr mcp list` sagt das am Ende ebenfalls."
6
9
  ],
package/dist/gui/main.js CHANGED
@@ -1046,6 +1046,17 @@ function fensterOeffnen() {
1046
1046
  var mcpWahlTextFrei = null;
1047
1047
  // E91: die Wahlzeile des Unterordners im Repo ist deaktiviert und trägt die Notiz.
1048
1048
  var mcpUnterordnerGesperrt = null;
1049
+ var mcpSucheVorhanden = false;
1050
+ var mcpSucheLeerBeimOeffnen = false;
1051
+ var mcpSucheFokus = false;
1052
+ var mcpSucheZeilenGesamt = 0;
1053
+ var mcpSucheNurTreffer = false;
1054
+ var mcpSucheAndereVersteckt = false;
1055
+ var mcpSucheLeerhinweis = null;
1056
+ var mcpSucheLeerhinweisWeg = false;
1057
+ var mcpSucheAbgehakt = false;
1058
+ var mcpSucheEnterOffen = false;
1059
+ var mcpSucheNachNeuOeffnen = false;
1049
1060
  try {
1050
1061
  var mcpEinKnoepfe = Array.from(document.querySelectorAll('#mcpliste .mcpkopf button'))
1051
1062
  .filter((b) => (b.textContent || '').indexOf('Einhängen') === 0);
@@ -1063,6 +1074,44 @@ function fensterOeffnen() {
1063
1074
  mcpUnterordnerGesperrt = Array.from(document.querySelectorAll('#dm-orte .wahlzeile'))
1064
1075
  .filter((z) => (z.textContent || '').indexOf('unterordner') > -1)
1065
1076
  .map((z) => z.querySelector('input')?.disabled === true);
1077
+ // E122: Suchfeld im Dialog. Fokus, Filter, Leerhinweis, Abhaken beim Ausblenden,
1078
+ // Enter ohne Auswahl, Zustand nach erneutem Öffnen.
1079
+ var dmSuche = document.getElementById('dm-suche');
1080
+ mcpSucheVorhanden = dmSuche !== null;
1081
+ mcpSucheLeerBeimOeffnen = dmSuche?.value === '';
1082
+ mcpSucheFokus = document.activeElement?.id === 'dm-suche';
1083
+ var dmSetze = (wert) => {
1084
+ dmSuche.value = wert;
1085
+ dmSuche.dispatchEvent(new Event('input', { bubbles: true }));
1086
+ };
1087
+ var dmZeilen = () => Array.from(document.querySelectorAll('#dm-orte .wahlzeile'));
1088
+ mcpSucheZeilenGesamt = dmZeilen().length;
1089
+ dmSetze('unterordner');
1090
+ var dmSichtbar = dmZeilen().filter((z) => !z.hidden);
1091
+ mcpSucheNurTreffer = dmSichtbar.length > 0
1092
+ && dmSichtbar.every((z) => (z.textContent || '').indexOf('unterordner') > -1);
1093
+ mcpSucheAndereVersteckt = dmZeilen().some((z) => z.hidden);
1094
+ dmSetze('zzzkeintreffer');
1095
+ mcpSucheLeerhinweis = document.querySelector('#dm-orte .leerhinweis')?.textContent ?? null;
1096
+ dmSetze('');
1097
+ mcpSucheLeerhinweisWeg = document.querySelector('#dm-orte .leerhinweis') === null
1098
+ && dmZeilen().every((z) => !z.hidden);
1099
+ var dmFrei = dmZeilen().find((z) => z.querySelector('input')?.disabled === false);
1100
+ var dmFreiRadio = dmFrei?.querySelector('input');
1101
+ if (dmFreiRadio) {
1102
+ dmFreiRadio.checked = true;
1103
+ dmSetze('unterordner');
1104
+ mcpSucheAbgehakt = dmFrei.hidden === true && dmFreiRadio.checked === false;
1105
+ }
1106
+ dmSetze('');
1107
+ dmSuche.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
1108
+ await new Promise((r) => setTimeout(r, 100));
1109
+ mcpSucheEnterOffen = document.getElementById('d-mcp')?.open === true;
1110
+ dmSetze('unterordner');
1111
+ document.querySelector('#d-mcp button[value="abbruch"]')?.click();
1112
+ await mcpWahlOeffnen(mcpEinKnoepfe[1]);
1113
+ mcpSucheNachNeuOeffnen = document.getElementById('dm-suche')?.value === ''
1114
+ && dmZeilen().length > 0 && dmZeilen().every((z) => !z.hidden);
1066
1115
  document.querySelector('#d-mcp button[value="abbruch"]')?.click();
1067
1116
  } catch (fehler) {
1068
1117
  mcpFehler = String(fehler);
@@ -1367,6 +1416,17 @@ function fensterOeffnen() {
1367
1416
  mcpWahlText,
1368
1417
  mcpWahlTextFrei,
1369
1418
  mcpUnterordnerGesperrt,
1419
+ mcpSucheVorhanden,
1420
+ mcpSucheLeerBeimOeffnen,
1421
+ mcpSucheFokus,
1422
+ mcpSucheZeilenGesamt,
1423
+ mcpSucheNurTreffer,
1424
+ mcpSucheAndereVersteckt,
1425
+ mcpSucheLeerhinweis,
1426
+ mcpSucheLeerhinweisWeg,
1427
+ mcpSucheAbgehakt,
1428
+ mcpSucheEnterOffen,
1429
+ mcpSucheNachNeuOeffnen,
1370
1430
  mcpFehler,
1371
1431
  dMcpAusOffenNachOeffnen,
1372
1432
  dMcpAusOffenNachAbbrechen,
@@ -573,7 +573,13 @@
573
573
  <h3>Wohin soll <span id="dm-name">der Server</span>?</h3>
574
574
  <p id="dm-text">Ein Ort je Einhängen. agents kennt keine MCP-Server und steht deshalb nicht zur Wahl.</p>
575
575
  </div>
576
- <div class="dkoerper"><div class="wahl" id="dm-orte"></div></div>
576
+ <div class="dkoerper">
577
+ <div class="suche">
578
+ <svg viewBox="0 0 16 16" stroke-width="1.6" aria-hidden="true"><circle cx="7" cy="7" r="4.5"/><path d="M10.5 10.5 14.5 14.5"/></svg>
579
+ <input type="search" id="dm-suche" placeholder="Ort oder Pfad suchen" aria-label="Orte durchsuchen" spellcheck="false" autocomplete="off">
580
+ </div>
581
+ <div class="wahl" id="dm-orte"></div>
582
+ </div>
577
583
  <div class="dfuss">
578
584
  <button class="knopf leise" value="abbruch">Abbrechen</button>
579
585
  <button class="knopf signal" value="los" id="dm-los">Einhängen</button>
@@ -3697,6 +3697,7 @@
3697
3697
  $('dm-text').textContent = 'Ein Ort je Einhängen. agents kennt keine MCP-Server und steht deshalb nicht zur Wahl.';
3698
3698
  var box = $('dm-orte');
3699
3699
  box.textContent = '';
3700
+ $('dm-suche').value = '';
3700
3701
  // Die Plätze kommen aus dem Kern (F42, E16): die Fähigkeit hängt am Adapter, nicht am
3701
3702
  // Harness-Namen, hier wird nicht selbst entschieden, wer welche Ebene kennt.
3702
3703
  var plaetze = await rufe(function () { return window.hmgr.mcpPlaetze(); });
@@ -3711,6 +3712,7 @@
3711
3712
  var schon = k.eingehaengt.some(function (z) { return zielKey(z) === zielKey(ziel); });
3712
3713
  var aktiv = harnessAktiv(ziel.harness);
3713
3714
  var label = e('label', 'wahlzeile');
3715
+ label.dataset.index = i;
3714
3716
  var input = document.createElement('input');
3715
3717
  input.type = 'radio';
3716
3718
  input.name = 'mcport';
@@ -3742,7 +3744,41 @@
3742
3744
  box.appendChild(label);
3743
3745
  });
3744
3746
  zeige($('d-mcp'));
3747
+ $('dm-suche').focus();
3748
+ }
3749
+
3750
+ /** E122: filtert die Wahlzeilen des Einhängen-Dialogs live. Die Zeilen bleiben stehen (der
3751
+ Radio-Wert ist der Index in mcpPlaetzeAuswahl), nicht passende werden nur ausgeblendet. Eine
3752
+ angehakte Zeile, die verschwindet, wird abgehakt: sonst ginge „Einhängen" an einen Ort, den
3753
+ niemand mehr sieht. */
3754
+ function filtereMcpOrte() {
3755
+ var begriff = $('dm-suche').value.trim();
3756
+ var suche = suchform(begriff);
3757
+ var box = $('dm-orte');
3758
+ var gezeigt = 0;
3759
+ box.querySelectorAll('.wahlzeile').forEach(function (label) {
3760
+ var ziel = mcpPlaetzeAuswahl[+label.dataset.index];
3761
+ var passt = true;
3762
+ if (suche) {
3763
+ var pfad = ziel.ort.art === 'arbeitsverzeichnis' ? ziel.ort.pfad : '';
3764
+ var text = suchform(zielTitel({ ziel: ziel }) + ' ' + mcpOrtSpur(ziel) + ' ' + pfad + ' ' + pfadKurz(pfad));
3765
+ passt = text.indexOf(suche) > -1;
3766
+ }
3767
+ label.hidden = !passt;
3768
+ if (passt) gezeigt++;
3769
+ else {
3770
+ var radio = label.querySelector('input');
3771
+ if (radio) radio.checked = false;
3772
+ }
3773
+ });
3774
+ var alt = box.querySelector('.leerhinweis');
3775
+ if (alt) alt.remove();
3776
+ if (suche && gezeigt === 0) {
3777
+ box.appendChild(e('p', 'leerhinweis', 'Kein Ort passt zu „' + begriff + '".'));
3778
+ }
3745
3779
  }
3780
+ $('dm-suche').addEventListener('input', filtereMcpOrte);
3781
+ enterBestaetigt($('dm-suche'), $('dm-los'));
3746
3782
 
3747
3783
  $('d-mcp').addEventListener('submit', function (ev) {
3748
3784
  if (ev.submitter && ev.submitter.value === 'los') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hmgr",
3
- "version": "0.0.53",
3
+ "version": "0.0.54",
4
4
  "description": "Harness Manager: Skills und Plugins für AI-Harnesses verwalten",
5
5
  "license": "MIT",
6
6
  "author": "Tim Kaufmann",