hmgr 0.0.37 → 0.0.39
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/dist/gui/main.js +5 -2
- package/dist/gui/mcp-ansicht.js +4 -13
- package/dist/gui/renderer/renderer.js +33 -12
- package/dist/kern/anwendungsfaelle.js +65 -11
- package/package.json +1 -1
package/dist/gui/main.js
CHANGED
|
@@ -416,8 +416,11 @@ function registriereIpc() {
|
|
|
416
416
|
}));
|
|
417
417
|
// MCP-Ansicht (E61-Folgerunde): Whitelisting und der F39-Vermerk je Karte stehen in mcp-ansicht.ts
|
|
418
418
|
// (rein, ohne Electron, wie oeffnen.ts und icons.ts), damit sie testbar sind. Der Main-Prozess
|
|
419
|
-
// ruft nur noch auf
|
|
420
|
-
ipcMain.handle('hmgr:mcpUebersicht', async () => auffangen(async () =>
|
|
419
|
+
// ruft nur noch auf; die F39-Lage je Welt (lokal, WSL-Distro) kommt aus dem Kern (E107).
|
|
420
|
+
ipcMain.handle('hmgr:mcpUebersicht', async () => auffangen(async () => {
|
|
421
|
+
const uebersicht = await anwendungsfaelle.mcpUebersicht();
|
|
422
|
+
return mcpUebersichtSerialisieren(uebersicht, await anwendungsfaelle.mcpVariablenLage(uebersicht));
|
|
423
|
+
}));
|
|
421
424
|
// Plätze für den Einhängen-Dialog (F42): die Fähigkeit hängt am Adapter, nicht am Namen (E16),
|
|
422
425
|
// deshalb kommt die Liste unverändert aus dem Kern statt aus einer Harness-Fallunterscheidung hier.
|
|
423
426
|
ipcMain.handle('hmgr:mcpPlaetze', async () => auffangen(async () => anwendungsfaelle.mcpPlaetze()));
|
package/dist/gui/mcp-ansicht.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// MCP-Ansicht der GUI (E61-Folgerunde): reine Umformung von Kern-Daten in IPC-taugliche, gewhiteliste
|
|
2
2
|
// Objekte, ohne Electron — testbar wie oeffnen.ts und icons.ts. Der eigentliche IPC-Handler in
|
|
3
3
|
// main.ts ruft diese Funktionen nur noch auf.
|
|
4
|
-
import {
|
|
4
|
+
import {} from "../kern/anwendungsfaelle.js";
|
|
5
5
|
/** Katalog-Eintrag über IPC: die bekannten Felder, nichts ungefiltert durchgereicht (E40 R3). */
|
|
6
6
|
export function mcpEintragSerialisieren(eintrag) {
|
|
7
7
|
return {
|
|
@@ -12,23 +12,14 @@ export function mcpEintragSerialisieren(eintrag) {
|
|
|
12
12
|
konfig: eintrag.konfig,
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
* (`variablenVerweise`), hier aber nur gegen die übergebene Umgebung geprüft — ohne den
|
|
18
|
-
* ortsbezogenen `.env`-Abgleich, der ist ortsspezifisch und bleibt dem eigentlichen Einhängen
|
|
19
|
-
* vorbehalten (kommt von dort als `warnung` zurück).
|
|
20
|
-
*/
|
|
21
|
-
export function mcpFehlendeVariablen(eintrag, umgebung) {
|
|
22
|
-
return variablenVerweise(eintrag.konfig).filter((name) => !(name in umgebung) || umgebung[name] === undefined);
|
|
23
|
-
}
|
|
24
|
-
/** Übersicht über IPC (E61-Folgerunde): Katalog-Einträge whitelisted, dazu der F39-Vermerk je Karte. */
|
|
25
|
-
export function mcpUebersichtSerialisieren(uebersicht, umgebung) {
|
|
15
|
+
/** Übersicht über IPC (E61-Folgerunde): Katalog-Einträge whitelisted, dazu je Karte die F39-Befunde je Welt (E107, `variablenWelten`). */
|
|
16
|
+
export function mcpUebersichtSerialisieren(uebersicht, lage) {
|
|
26
17
|
return {
|
|
27
18
|
katalog: uebersicht.katalog.map((k) => ({
|
|
28
19
|
eintrag: mcpEintragSerialisieren(k.eintrag),
|
|
29
20
|
eingehaengt: k.eingehaengt,
|
|
30
21
|
geteilteFundorte: k.geteilteFundorte,
|
|
31
|
-
|
|
22
|
+
variablenWelten: lage.get(k.eintrag.name) ?? [],
|
|
32
23
|
})),
|
|
33
24
|
unbekannt: uebersicht.unbekannt,
|
|
34
25
|
unbekannteGeteilteFundorte: uebersicht.unbekannteGeteilteFundorte,
|
|
@@ -323,7 +323,7 @@
|
|
|
323
323
|
// Homedirs je Harness (E78): je Eintrag { harness, heime: [{ adresse?, pfad, eingestellt }],
|
|
324
324
|
// kannZusaetzliche }. Grundlage der Homedir-Zeilen in den Einstellungen.
|
|
325
325
|
var HARNESS_HEIME = [];
|
|
326
|
-
// MCP-Katalog (E61-Folgerunde): je Eintrag { eintrag, eingehaengt,
|
|
326
|
+
// MCP-Katalog (E61-Folgerunde): je Eintrag { eintrag, eingehaengt, variablenWelten }, dazu
|
|
327
327
|
// Einträge in Harness-Konfigurationen, die nicht im Katalog stehen (nur genannt). Seit F46 nur
|
|
328
328
|
// noch Grundlage für den MCP-Abschnitt der Ziel-Karten (mcpZeilenFuerZiel), die MCP-Ansicht selbst
|
|
329
329
|
// zeigt keine Fundorte mehr.
|
|
@@ -3071,13 +3071,11 @@
|
|
|
3071
3071
|
return a;
|
|
3072
3072
|
}
|
|
3073
3073
|
|
|
3074
|
-
/** F39:
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
function mcpWarnZeile(
|
|
3079
|
-
var mehrzahl = fehlend.length > 1;
|
|
3080
|
-
var namen = fehlend.map(function (v) { return '${' + v + '}'; }).join(', ');
|
|
3074
|
+
/** F39 (E107): der Main-Prozess liefert je Karte `variablenWelten`, die Befunde je Welt (lokal oder
|
|
3075
|
+
WSL-Distro), geprüft gegen dieselbe Umgebungsquelle wie das Einhängen — ohne den ortsbezogenen
|
|
3076
|
+
.env-Abgleich, der bleibt dem Einhängen selbst vorbehalten und kommt dann als `warnung` zurück.
|
|
3077
|
+
Je Welt mit Befund eine Zeile, Welten ohne Befund keine. Wiederverwendet die .ruhezeile-Optik. */
|
|
3078
|
+
function mcpWarnZeile(text) {
|
|
3081
3079
|
var rz = e('div', 'ruhezeile');
|
|
3082
3080
|
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
3083
3081
|
svg.setAttribute('viewBox', '0 0 16 16');
|
|
@@ -3085,12 +3083,35 @@
|
|
|
3085
3083
|
svg.setAttribute('aria-hidden', 'true');
|
|
3086
3084
|
svg.innerHTML = '<circle cx="8" cy="8" r="6.5"/><path d="M8 4.5v4M8 10.5v.5"/>';
|
|
3087
3085
|
rz.appendChild(svg);
|
|
3088
|
-
rz.appendChild(e('p', null,
|
|
3089
|
-
+ (mehrzahl ? 'die Variablen' : 'die Variable') + ' beim Start des Harness gesetzt ' + (mehrzahl ? 'sind' : 'ist')
|
|
3090
|
-
+ ', kann hmgr nicht wissen.'));
|
|
3086
|
+
rz.appendChild(e('p', null, text));
|
|
3091
3087
|
return rz;
|
|
3092
3088
|
}
|
|
3093
3089
|
|
|
3090
|
+
function mcpWarnZeilen(welten) {
|
|
3091
|
+
var mehrere = welten.some(function (w) { return w.distro !== undefined; });
|
|
3092
|
+
var zeilen = [];
|
|
3093
|
+
welten.forEach(function (w) {
|
|
3094
|
+
if (w.ungeprueft) {
|
|
3095
|
+
zeilen.push(mcpWarnZeile('hmgr konnte die Umgebung von WSL ' + w.distro + ' nicht lesen, die Verweise sind ungeprüft.'));
|
|
3096
|
+
return;
|
|
3097
|
+
}
|
|
3098
|
+
if (w.fehlend.length === 0) return;
|
|
3099
|
+
var mz = w.fehlend.length > 1;
|
|
3100
|
+
var namen = w.fehlend.map(function (v) { return '${' + v + '}'; }).join(', ');
|
|
3101
|
+
var verb = mz ? ' sind' : ' ist';
|
|
3102
|
+
if (w.distro !== undefined) {
|
|
3103
|
+
zeilen.push(mcpWarnZeile(namen + verb + ' in WSL ' + w.distro + ' nicht gesetzt (Login-Shell, interaktiv).'));
|
|
3104
|
+
} else if (mehrere) {
|
|
3105
|
+
zeilen.push(mcpWarnZeile(namen + verb + ' in Windows nicht gesetzt.'));
|
|
3106
|
+
} else {
|
|
3107
|
+
zeilen.push(mcpWarnZeile(namen + verb + ' in der Umgebung von hmgr nicht gesetzt. Ob '
|
|
3108
|
+
+ (mz ? 'die Variablen' : 'die Variable') + ' beim Start des Harness gesetzt ' + (mz ? 'sind' : 'ist')
|
|
3109
|
+
+ ', kann hmgr nicht wissen.'));
|
|
3110
|
+
}
|
|
3111
|
+
});
|
|
3112
|
+
return zeilen;
|
|
3113
|
+
}
|
|
3114
|
+
|
|
3094
3115
|
/** Notizen sind das Langsame am Eintrag (entwurf/gui.html): zugeklappt, öffnen sich nur, wenn
|
|
3095
3116
|
jemand sie sucht. Der Wortlaut bleibt, wie er in der mcp.yaml steht, Zeilenumbrüche
|
|
3096
3117
|
eingeschlossen (weiss-raum: pre-line in styles.css). */
|
|
@@ -3135,7 +3156,7 @@
|
|
|
3135
3156
|
konf.appendChild(e('span', 'mono', mcpKonfigWortlaut(eintrag.konfig)));
|
|
3136
3157
|
kEl.appendChild(konf);
|
|
3137
3158
|
|
|
3138
|
-
|
|
3159
|
+
mcpWarnZeilen(k.variablenWelten).forEach(function (z) { kEl.appendChild(z); });
|
|
3139
3160
|
if (eintrag.notizen) kEl.appendChild(mcpNotizenBlock(eintrag.notizen));
|
|
3140
3161
|
|
|
3141
3162
|
return kEl;
|
|
@@ -394,6 +394,67 @@ export class Anwendungsfaelle {
|
|
|
394
394
|
throw new McpUnbekannt(mcpName);
|
|
395
395
|
return eintrag;
|
|
396
396
|
}
|
|
397
|
+
/**
|
|
398
|
+
* Die Umgebung einer Welt (E107): ohne `distro` die Prozess-Umgebung, sonst die einer im Terminal
|
|
399
|
+
* der Distro gestarteten claude (E104). `undefined`, wenn die Distro-Umgebung nicht lesbar ist.
|
|
400
|
+
* Einzige Stelle dafür, geteilt von Einhängen-Warnung und Kartenhinweis.
|
|
401
|
+
*/
|
|
402
|
+
async mcpUmgebungDerWelt(distro) {
|
|
403
|
+
if (distro === undefined)
|
|
404
|
+
return this.p.umgebung.variablen();
|
|
405
|
+
return await this.p.wsl.variablen(distro).catch(() => undefined);
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* F39 an der Katalog-Karte (E107): je Eintrag mit `${VAR}`-Verweisen die Welten, gegen die zu
|
|
409
|
+
* prüfen ist, jeweils mit Befund. Welten: die der Ziele, an denen der Eintrag eingehängt ist; sonst
|
|
410
|
+
* die der Ziele, an denen er einhängbar wäre (`ortBedienbar`, ohne Git-Wurzel-Ermittlung). Je Distro
|
|
411
|
+
* höchstens ein Aufruf je Lauf; ohne Verweise im Katalog wird nichts befragt. Die `.env`-Zusatzdatei
|
|
412
|
+
* (Hermes) bleibt dem Einhängen vorbehalten. Einträge ohne Verweise fehlen in der Map.
|
|
413
|
+
*/
|
|
414
|
+
async mcpVariablenLage(uebersicht) {
|
|
415
|
+
const ergebnis = new Map();
|
|
416
|
+
const ue = uebersicht ?? (await this.mcpUebersicht());
|
|
417
|
+
const mitVerweisen = ue.katalog.filter((k) => variablenVerweise(k.eintrag.konfig).length > 0);
|
|
418
|
+
if (mitVerweisen.length === 0)
|
|
419
|
+
return ergebnis;
|
|
420
|
+
let moegliche;
|
|
421
|
+
const umgebungen = new Map();
|
|
422
|
+
for (const k of mitVerweisen) {
|
|
423
|
+
let welten = k.eingehaengt.map((z) => wslDistroVonOrt(z.ort));
|
|
424
|
+
if (welten.length === 0) {
|
|
425
|
+
if (moegliche === undefined) {
|
|
426
|
+
moegliche = [];
|
|
427
|
+
for (const ziel of await this.mcpZiele()) {
|
|
428
|
+
const mcp = this.harnessMitMcp(ziel.harness).mcp;
|
|
429
|
+
if (mcp.ortBedienbar !== undefined && !(await mcp.ortBedienbar(ziel.ort)))
|
|
430
|
+
continue;
|
|
431
|
+
moegliche.push(wslDistroVonOrt(ziel.ort));
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
welten = moegliche;
|
|
435
|
+
}
|
|
436
|
+
const verweise = variablenVerweise(k.eintrag.konfig);
|
|
437
|
+
const befunde = [];
|
|
438
|
+
// Lokale Welt zuerst, dann die Distros in der Reihenfolge ihres Auftretens.
|
|
439
|
+
const eindeutig = [...new Set(welten)].sort((a, b) => (a === undefined ? -1 : b === undefined ? 1 : 0));
|
|
440
|
+
for (const distro of eindeutig) {
|
|
441
|
+
let env = umgebungen.get(distro);
|
|
442
|
+
if (env === undefined) {
|
|
443
|
+
env = this.mcpUmgebungDerWelt(distro);
|
|
444
|
+
umgebungen.set(distro, env);
|
|
445
|
+
}
|
|
446
|
+
const umgebung = await env;
|
|
447
|
+
if (umgebung === undefined)
|
|
448
|
+
befunde.push({ distro: distro, ungeprueft: true });
|
|
449
|
+
else {
|
|
450
|
+
const fehlend = verweise.filter((v) => umgebung[v] === undefined);
|
|
451
|
+
befunde.push(distro === undefined ? { fehlend } : { distro, fehlend });
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
ergebnis.set(k.eintrag.name, befunde);
|
|
455
|
+
}
|
|
456
|
+
return ergebnis;
|
|
457
|
+
}
|
|
397
458
|
/**
|
|
398
459
|
* F39: fehlende `${VAR}`-Verweise als Warnung, nie als Abbruch. Geprüft wird gegen die eigene
|
|
399
460
|
* Prozess-Umgebung und, wenn die Fähigkeit eine `.env`-Datei nennt (Hermes), zusätzlich gegen sie.
|
|
@@ -404,17 +465,10 @@ export class Anwendungsfaelle {
|
|
|
404
465
|
return undefined;
|
|
405
466
|
// Ein WSL-Ziel startet claude in der Distro mit deren Umgebung, nicht mit der von Windows (E104).
|
|
406
467
|
const distro = wslDistroVonOrt(ort);
|
|
407
|
-
|
|
408
|
-
if (
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
else {
|
|
412
|
-
const distroEnv = await this.p.wsl.variablen(distro).catch(() => undefined);
|
|
413
|
-
if (distroEnv === undefined) {
|
|
414
|
-
return (`hmgr konnte die Umgebung der WSL-Distro ${distro} nicht lesen; die Verweise ` +
|
|
415
|
-
`${verweise.map((v) => '${' + v + '}').join(', ')} sind deshalb ungeprüft.`);
|
|
416
|
-
}
|
|
417
|
-
prozessEnv = distroEnv;
|
|
468
|
+
const prozessEnv = await this.mcpUmgebungDerWelt(distro);
|
|
469
|
+
if (prozessEnv === undefined) {
|
|
470
|
+
return (`hmgr konnte die Umgebung der WSL-Distro ${distro} nicht lesen; die Verweise ` +
|
|
471
|
+
`${verweise.map((v) => '${' + v + '}').join(', ')} sind deshalb ungeprüft.`);
|
|
418
472
|
}
|
|
419
473
|
const envPfad = faehig.mcp.envDatei?.(ort);
|
|
420
474
|
const zusatzEnv = envPfad === undefined ? {} : await this.p.umgebung.envDatei(envPfad);
|