hmgr 0.0.17 → 0.0.19
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/adapter/composer.js +4 -0
- package/dist/adapter/git.js +6 -2
- package/dist/cli/hilfe.js +23 -2
- package/dist/cli/main.js +24 -1
- package/dist/gui/renderer/renderer.js +3 -0
- package/dist/kern/anwendungsfaelle.js +37 -3
- package/package.json +1 -1
package/dist/adapter/composer.js
CHANGED
|
@@ -92,4 +92,8 @@ export class ComposerZeiger {
|
|
|
92
92
|
daten.scripts = scripts;
|
|
93
93
|
await writeFile(pfad, `${JSON.stringify(daten, null, 4)}\n`);
|
|
94
94
|
}
|
|
95
|
+
async verzeichnisExistiert(pfad) {
|
|
96
|
+
const info = await stat(pfad).catch(() => undefined);
|
|
97
|
+
return info !== undefined && info.isDirectory();
|
|
98
|
+
}
|
|
95
99
|
}
|
package/dist/adapter/git.js
CHANGED
|
@@ -325,7 +325,10 @@ export class GitQuellen {
|
|
|
325
325
|
async refsNachziehen(quelle) {
|
|
326
326
|
if (quelle.art === 'lokal')
|
|
327
327
|
return;
|
|
328
|
-
|
|
328
|
+
// --force: mitlaufende Tags (z.B. cmux `nightly`) zeigen bei jedem Build auf einen neuen
|
|
329
|
+
// Commit; ohne --force verweigert git das Überschreiben ("would clobber existing tag") und
|
|
330
|
+
// bricht den ganzen Fetch ab (E87). Betrifft nur lokale Tag-Refs im bare-Basis-Clone.
|
|
331
|
+
await this.git(['fetch', '--prune', '--force', '--tags', 'origin'], await this.basis(quelle));
|
|
329
332
|
}
|
|
330
333
|
async standardRef(quelle) {
|
|
331
334
|
if (quelle.art === 'lokal')
|
|
@@ -413,7 +416,8 @@ export class GitQuellen {
|
|
|
413
416
|
const basis = await this.basis(checkout.quelle);
|
|
414
417
|
const von = (await this.git(['rev-parse', 'HEAD'], checkout.pfad)).trim();
|
|
415
418
|
try {
|
|
416
|
-
|
|
419
|
+
// --force: siehe refsNachziehen (E87), mitlaufende Tags dürfen den Fetch nicht abbrechen.
|
|
420
|
+
await this.git(['fetch', '--prune', '--force', '--tags', 'origin'], basis);
|
|
417
421
|
}
|
|
418
422
|
catch (fehler) {
|
|
419
423
|
return { ergebnis: 'fehlgeschlagen', fehler: fehler instanceof Error ? fehler.message : String(fehler) };
|
package/dist/cli/hilfe.js
CHANGED
|
@@ -34,6 +34,7 @@ hmgr <kommando> [schalter]
|
|
|
34
34
|
update Alle Checkouts aktualisieren
|
|
35
35
|
status Ist-Zustand der Ziele
|
|
36
36
|
log Verlauf der letzten Läufe (Changelog)
|
|
37
|
+
doctor Fehlende Arbeitsverzeichnisse finden und Vergessen anbieten
|
|
37
38
|
harness list Harness-Typen mit Stand aktiv/inaktiv und vorhanden
|
|
38
39
|
harness enable <name> Harness-Typ aktivieren, hmgr richtet ihn künftig ein
|
|
39
40
|
harness disable <name> Harness-Typ deaktivieren, mit Angebot zum Säubern
|
|
@@ -118,7 +119,7 @@ Häufige Fälle:
|
|
|
118
119
|
link --ort dir:<pfad> merkt das Verzeichnis von selbst. dir add braucht es vorher nur, wenn die
|
|
119
120
|
composer.json mehrdeutig ist.
|
|
120
121
|
|
|
121
|
-
Siehe auch: hmgr help link, hmgr help sync, hmgr help harness`;
|
|
122
|
+
Siehe auch: hmgr help link, hmgr help sync, hmgr help harness, hmgr help doctor`;
|
|
122
123
|
const LINK = `hmgr link <skill> [schalter]
|
|
123
124
|
|
|
124
125
|
Legt im Ziel einen Symlink auf den Skill an, der aus einer bekannten Quelle stammt, und trägt ihn
|
|
@@ -495,7 +496,7 @@ Häufige Fälle:
|
|
|
495
496
|
„liegen lassen … ohne Bestätigung nicht gelöscht": die Frage kam ohne Ja zurück, etwa in einer
|
|
496
497
|
Pipe oder einem Composer-Script. In einem Terminal erneut hmgr update aufrufen.
|
|
497
498
|
|
|
498
|
-
Siehe auch: hmgr help sync, hmgr help status, hmgr help log`;
|
|
499
|
+
Siehe auch: hmgr help sync, hmgr help status, hmgr help log, hmgr help doctor`;
|
|
499
500
|
const LOG = `hmgr log
|
|
500
501
|
|
|
501
502
|
Zeigt den Verlauf der letzten Läufe aus ~/.hmgr/verlauf.json (E80), neueste zuerst: dieselbe Datei,
|
|
@@ -521,6 +522,25 @@ Häufige Fälle:
|
|
|
521
522
|
„Noch keine Ereignisse": entweder frisch installiert, oder jeder bisherige Lauf war ohne Fund.
|
|
522
523
|
|
|
523
524
|
Siehe auch: hmgr help update, hmgr help status`;
|
|
525
|
+
const DOCTOR = `hmgr doctor
|
|
526
|
+
|
|
527
|
+
Prüft, ob jedes gemerkte Arbeitsverzeichnis (hmgr dir add) noch auf der Platte existiert (E88): ein
|
|
528
|
+
umbenanntes oder woanders neu geklontes Projekt hinterlässt sonst für immer einen toten Pfad im
|
|
529
|
+
Zustand, den nur hmgr dir forget von Hand entfernt. Bei einem Fund fragt doctor wie hmgr update
|
|
530
|
+
einmal für alle Funde, ob sie vergessen werden sollen; ohne Bestätigung bleiben sie gemeldet, aber
|
|
531
|
+
gemerkt. Anders als update holt doctor nichts aus dem Netz und schreibt keinen Eintrag in den
|
|
532
|
+
Verlauf — ein reiner Konsolen-Check, kein Lauf im E80-Sinn.
|
|
533
|
+
|
|
534
|
+
Schalter: keine.
|
|
535
|
+
|
|
536
|
+
Beispiel:
|
|
537
|
+
hmgr doctor
|
|
538
|
+
|
|
539
|
+
Häufige Fälle:
|
|
540
|
+
„liegen lassen … ohne Bestätigung nicht vergessen": die Frage kam ohne Ja zurück. In einem
|
|
541
|
+
Terminal erneut hmgr doctor aufrufen, oder hmgr dir forget <pfad> gezielt.
|
|
542
|
+
|
|
543
|
+
Siehe auch: hmgr help update, hmgr help dir`;
|
|
524
544
|
const STATUS = `hmgr status
|
|
525
545
|
|
|
526
546
|
Liest den Ist-Zustand vom Dateisystem: je Ziel eines vorhandenen, aktiven Harness die Einträge mit Quelle
|
|
@@ -648,6 +668,7 @@ const THEMEN = new Map([
|
|
|
648
668
|
['update', UPDATE],
|
|
649
669
|
['status', STATUS],
|
|
650
670
|
['log', LOG],
|
|
671
|
+
['doctor', DOCTOR],
|
|
651
672
|
['harness', HARNESS],
|
|
652
673
|
['help', HILFE],
|
|
653
674
|
]);
|
package/dist/cli/main.js
CHANGED
|
@@ -96,6 +96,7 @@ const SCHALTER = {
|
|
|
96
96
|
update: { werte: [], flaggen: [] },
|
|
97
97
|
status: { werte: [], flaggen: [] },
|
|
98
98
|
log: { werte: [], flaggen: [] },
|
|
99
|
+
doctor: { werte: [], flaggen: [] },
|
|
99
100
|
harness: { werte: ['profil'], flaggen: [] },
|
|
100
101
|
};
|
|
101
102
|
/**
|
|
@@ -715,7 +716,7 @@ export async function ausfuehren(argv, umgebung, optionen = {}) {
|
|
|
715
716
|
}
|
|
716
717
|
if (kommando === 'update') {
|
|
717
718
|
restPruefen(schalterLesen(argv.slice(1), 'update').rest, 0, 'update');
|
|
718
|
-
const { checkouts: liste, bundles, aufraeumen } = await anwendungsfaelle.aktualisieren({ ausloeser: 'cli' });
|
|
719
|
+
const { checkouts: liste, bundles, aufraeumen, doctor, } = await anwendungsfaelle.aktualisieren({ ausloeser: 'cli' });
|
|
719
720
|
if (liste.length === 0)
|
|
720
721
|
console.log('Keine Checkouts.');
|
|
721
722
|
for (const { checkout, aktualisierung, geaenderteSkills } of liste) {
|
|
@@ -751,6 +752,13 @@ export async function ausfuehren(argv, umgebung, optionen = {}) {
|
|
|
751
752
|
const geloescht = aufraeumen.verwaiste.filter((v) => v.geloescht).length;
|
|
752
753
|
console.log(`${aufraeumen.verwaiste.length} verwaist, ${geloescht} gelöscht, ${aufraeumen.verwaiste.length - geloescht} liegen geblieben.`);
|
|
753
754
|
}
|
|
755
|
+
// Fehlende Arbeitsverzeichnisse (E88): was es auf der Platte nicht mehr gibt.
|
|
756
|
+
for (const pfad of doctor.fehlendeArbeitsverzeichnisse) {
|
|
757
|
+
if (doctor.vergessen.includes(pfad))
|
|
758
|
+
console.log(` vergessen Arbeitsverzeichnis ${pfad} (nicht mehr auf der Platte)`);
|
|
759
|
+
else
|
|
760
|
+
console.log(` liegen lassen Arbeitsverzeichnis ${pfad} (nicht mehr auf der Platte, ohne Bestätigung nicht vergessen)`);
|
|
761
|
+
}
|
|
754
762
|
// Zuletzt hmgr selbst (E77): wer schon aktualisiert, will auch wissen, dass sein hmgr alt ist.
|
|
755
763
|
// Verglichen wird die eigene Version (E72) gegen npm, gemeldet wird nur — installiert wird
|
|
756
764
|
// nichts. Offline oder Registry unerreichbar heißt keine Zeile, still: der Lauf selbst ist
|
|
@@ -809,6 +817,19 @@ export async function ausfuehren(argv, umgebung, optionen = {}) {
|
|
|
809
817
|
}
|
|
810
818
|
return 0;
|
|
811
819
|
}
|
|
820
|
+
if (kommando === 'doctor') {
|
|
821
|
+
restPruefen(schalterLesen(argv.slice(1), 'doctor').rest, 0, 'doctor');
|
|
822
|
+
const { fehlendeArbeitsverzeichnisse, vergessen } = await anwendungsfaelle.doctor();
|
|
823
|
+
if (fehlendeArbeitsverzeichnisse.length === 0)
|
|
824
|
+
console.log('Keine fehlenden Arbeitsverzeichnisse.');
|
|
825
|
+
for (const pfad of fehlendeArbeitsverzeichnisse) {
|
|
826
|
+
if (vergessen.includes(pfad))
|
|
827
|
+
console.log(` vergessen ${pfad}`);
|
|
828
|
+
else
|
|
829
|
+
console.log(` liegen lassen ${pfad} (ohne Bestätigung nicht vergessen)`);
|
|
830
|
+
}
|
|
831
|
+
return 0;
|
|
832
|
+
}
|
|
812
833
|
if (kommando === 'harness') {
|
|
813
834
|
const schalter = schalterLesen(argv.slice(1), 'harness');
|
|
814
835
|
unterkommandoPruefen('harness', schalter);
|
|
@@ -1042,6 +1063,8 @@ function verlaufEreignisZeile(ereignis) {
|
|
|
1042
1063
|
}
|
|
1043
1064
|
if (ereignis.art === 'aufgeraeumt')
|
|
1044
1065
|
return `Checkout ${ereignis.checkout} aufgeräumt`;
|
|
1066
|
+
if (ereignis.art === 'arbeitsverzeichnis-vergessen')
|
|
1067
|
+
return `Arbeitsverzeichnis ${ereignis.pfad} vergessen (nicht mehr auf der Platte)`;
|
|
1045
1068
|
if (ereignis.art === 'fehler')
|
|
1046
1069
|
return `Fehler ${ereignis.betrifft}: ${ereignis.fehler}`;
|
|
1047
1070
|
if (ereignis.art === 'hmgr-installiert')
|
|
@@ -2754,6 +2754,9 @@
|
|
|
2754
2754
|
} else if (ereignis.art === 'aufgeraeumt') {
|
|
2755
2755
|
li.appendChild(e('span', 'marke-ok', 'aufgeräumt'));
|
|
2756
2756
|
li.appendChild(e('span', 'pfad', ereignis.checkout));
|
|
2757
|
+
} else if (ereignis.art === 'arbeitsverzeichnis-vergessen') {
|
|
2758
|
+
li.appendChild(e('span', 'marke-ok', 'vergessen'));
|
|
2759
|
+
li.appendChild(e('span', 'pfad', ereignis.pfad));
|
|
2757
2760
|
} else if (ereignis.art === 'fehler') {
|
|
2758
2761
|
li.appendChild(e('span', 'marke-aus', 'fehlgeschlagen'));
|
|
2759
2762
|
li.appendChild(e('span', 'pfad', ereignis.betrifft + ': ' + ereignis.fehler));
|
|
@@ -14,6 +14,17 @@ export function aufraeumFrage(checkouts) {
|
|
|
14
14
|
const pfade = checkouts.map((c) => ` ${c.pfad}`).join('\n');
|
|
15
15
|
return `${kopf}\n${pfade}\nLöschen?`;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Frage vor dem Vergessen fehlender Arbeitsverzeichnisse (E88), eine für alle Funde — Analogie zu
|
|
19
|
+
* `aufraeumFrage`.
|
|
20
|
+
*/
|
|
21
|
+
export function doctorFrage(pfade) {
|
|
22
|
+
const kopf = pfade.length === 1
|
|
23
|
+
? 'Ein Arbeitsverzeichnis gibt es auf der Platte nicht mehr:'
|
|
24
|
+
: `${pfade.length} Arbeitsverzeichnisse gibt es auf der Platte nicht mehr:`;
|
|
25
|
+
const zeilen = pfade.map((p) => ` ${p}`).join('\n');
|
|
26
|
+
return `${kopf}\n${zeilen}\nVergessen?`;
|
|
27
|
+
}
|
|
17
28
|
function arbeitsverzeichnisZiel(harness, pfad) {
|
|
18
29
|
return { harness, ort: { art: 'arbeitsverzeichnis', pfad } };
|
|
19
30
|
}
|
|
@@ -1205,6 +1216,26 @@ export class Anwendungsfaelle {
|
|
|
1205
1216
|
zustand.bindungen = zustand.bindungen.filter((b) => !(b.ziel.ort.art === 'arbeitsverzeichnis' && b.ziel.ort.pfad === verzeichnis));
|
|
1206
1217
|
await this.p.zustand.schreiben(zustand);
|
|
1207
1218
|
}
|
|
1219
|
+
/**
|
|
1220
|
+
* Arbeitsverzeichnisse erkennen, die es auf der Platte nicht mehr gibt, und ihr Vergessen anbieten
|
|
1221
|
+
* (E88). `rueckfragen: false` (GUI-Automatik, Smoke) meldet nur, fragt nicht und vergisst nichts —
|
|
1222
|
+
* dieselbe Weiche wie bei `verwaisteAufraeumen`.
|
|
1223
|
+
*/
|
|
1224
|
+
async doctor(args) {
|
|
1225
|
+
const rueckfragen = args?.rueckfragen ?? true;
|
|
1226
|
+
const zustand = await this.p.zustand.lesen();
|
|
1227
|
+
const fehlend = [];
|
|
1228
|
+
for (const pfad of zustand.arbeitsverzeichnisse)
|
|
1229
|
+
if (!(await this.p.zeiger.verzeichnisExistiert(pfad)))
|
|
1230
|
+
fehlend.push(pfad);
|
|
1231
|
+
if (fehlend.length === 0 || !rueckfragen)
|
|
1232
|
+
return { fehlendeArbeitsverzeichnisse: fehlend, vergessen: [] };
|
|
1233
|
+
if (!(await this.p.rueckfrage.bestaetigen(doctorFrage(fehlend))))
|
|
1234
|
+
return { fehlendeArbeitsverzeichnisse: fehlend, vergessen: [] };
|
|
1235
|
+
for (const pfad of fehlend)
|
|
1236
|
+
await this.arbeitsverzeichnisVergessen(pfad);
|
|
1237
|
+
return { fehlendeArbeitsverzeichnisse: fehlend, vergessen: [...fehlend] };
|
|
1238
|
+
}
|
|
1208
1239
|
/**
|
|
1209
1240
|
* Mehrere composer.json unter einem Verzeichnis (E26): hmgr rät nicht, es fragt. Bleibt die Frage
|
|
1210
1241
|
* ohne Antwort, weil niemand antworten kann oder die Eingabe keine der Kandidaten trifft, gilt
|
|
@@ -1785,15 +1816,16 @@ export class Anwendungsfaelle {
|
|
|
1785
1816
|
// in seinem Eintrag, er bricht den Lauf nicht ab — wie eine unerreichbare Quelle (E51).
|
|
1786
1817
|
const bundles = await this.bundleAbgleich();
|
|
1787
1818
|
const aufraeumen = await this.verwaisteAufraeumen(checkouts, rueckfragen);
|
|
1788
|
-
await this.
|
|
1789
|
-
|
|
1819
|
+
const doctorErgebnis = await this.doctor({ rueckfragen });
|
|
1820
|
+
await this.verlaufVermerken(ausloeser, this.aktualisierungsEreignisse(checkouts, bundles, aufraeumen, doctorErgebnis));
|
|
1821
|
+
return { checkouts, pluginHarnesses, bundles, aufraeumen, doctor: doctorErgebnis };
|
|
1790
1822
|
}
|
|
1791
1823
|
/**
|
|
1792
1824
|
* Ereignisse eines Aktualisieren-Laufs für den Verlauf (E80): Plugins bleiben draußen, weil sich
|
|
1793
1825
|
* eine Änderung dort nicht messen lässt (`claude plugin marketplace update` liefert keine
|
|
1794
1826
|
* Auskunft) — die bisherige Zeile „Plugins aktualisiert" war deshalb geschönt.
|
|
1795
1827
|
*/
|
|
1796
|
-
aktualisierungsEreignisse(checkouts, bundles, aufraeumen) {
|
|
1828
|
+
aktualisierungsEreignisse(checkouts, bundles, aufraeumen, doctorErgebnis) {
|
|
1797
1829
|
const ereignisse = [];
|
|
1798
1830
|
for (const { checkout, aktualisierung, geaenderteSkills } of checkouts) {
|
|
1799
1831
|
if (aktualisierung.ergebnis === 'aktualisiert')
|
|
@@ -1827,6 +1859,8 @@ export class Anwendungsfaelle {
|
|
|
1827
1859
|
for (const verwaist of aufraeumen.verwaiste)
|
|
1828
1860
|
if (verwaist.geloescht)
|
|
1829
1861
|
ereignisse.push({ art: 'aufgeraeumt', checkout: `${quelleAlsText(verwaist.checkout.quelle)} @ ${verwaist.checkout.ref}` });
|
|
1862
|
+
for (const pfad of doctorErgebnis.vergessen)
|
|
1863
|
+
ereignisse.push({ art: 'arbeitsverzeichnis-vergessen', pfad });
|
|
1830
1864
|
return ereignisse;
|
|
1831
1865
|
}
|
|
1832
1866
|
/** Neuen Eintrag vorn anfügen, nur wenn Ereignisse da sind (E80). Kappen übernimmt der Adapter. */
|