hmgr 0.0.51 → 0.0.52
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/agents.js +3 -0
- package/dist/adapter/claude-code.js +3 -0
- package/dist/adapter/hermes.js +3 -0
- package/dist/aenderungen.json +3 -0
- package/dist/cli/hilfe.js +5 -0
- package/dist/cli/main.js +6 -2
- package/dist/gui/main.js +9 -0
- package/dist/gui/renderer/renderer.js +10 -4
- package/dist/kern/anwendungsfaelle.js +68 -14
- package/dist/kern/modell.js +16 -2
- package/package.json +1 -1
package/dist/adapter/agents.js
CHANGED
|
@@ -51,6 +51,9 @@ export class Agents {
|
|
|
51
51
|
if (ort.art === 'arbeitsverzeichnis' && (await istGitRepo(ort.pfad)))
|
|
52
52
|
await gitignoreEintragen(ort.pfad, GITIGNORE_ZEILE);
|
|
53
53
|
}
|
|
54
|
+
quellOrdner() {
|
|
55
|
+
return `${AGENTS_VERZEICHNIS}/${SKILLS_ORDNER}`;
|
|
56
|
+
}
|
|
54
57
|
folgtLinks() {
|
|
55
58
|
return true;
|
|
56
59
|
}
|
|
@@ -681,6 +681,9 @@ export class ClaudeCode {
|
|
|
681
681
|
if (ort.art === 'arbeitsverzeichnis' && (await istGitRepo(ort.pfad)))
|
|
682
682
|
await gitignoreEintragen(ort.pfad, GITIGNORE_ZEILE);
|
|
683
683
|
}
|
|
684
|
+
quellOrdner() {
|
|
685
|
+
return `${CLAUDE_VERZEICHNIS}/${SKILLS_ORDNER}`;
|
|
686
|
+
}
|
|
684
687
|
folgtLinks() {
|
|
685
688
|
return true;
|
|
686
689
|
}
|
package/dist/adapter/hermes.js
CHANGED
package/dist/aenderungen.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"fassung": 1,
|
|
3
3
|
"versionen": {
|
|
4
|
+
"0.0.52": [
|
|
5
|
+
"Liegt ein Skill in einem Repo in mehreren Fassungen, je Werkzeug eine (etwa `.claude/skills` und `.hermes/skills`), verlinkt hmgr jetzt für jeden Harness die passende Fassung. Gibt es keine passende, nennt die Meldung die Pfade, und `hmgr link … --pfad` wählt einen aus."
|
|
6
|
+
],
|
|
4
7
|
"0.0.51": [
|
|
5
8
|
"Ein gelöschter Projektordner, an dem noch ein Bundle hing, wird beim Aktualisieren nicht mehr neu angelegt. `hmgr doctor` findet solche Ordner jetzt und bietet an, sie samt ihren Bundles zu vergessen."
|
|
6
9
|
],
|
package/dist/cli/hilfe.js
CHANGED
|
@@ -147,6 +147,7 @@ Schalter:
|
|
|
147
147
|
--ort <ort> home, wsl:<distro>, dir:<pfad> oder profil:<name>, Standard home. profil
|
|
148
148
|
kennt nur hermes, wsl:<distro> nur claude-code unter Windows (E78)
|
|
149
149
|
--quelle <teil> Teilstring der Quelle, wenn der Skill-Name in mehreren Quellen vorkommt
|
|
150
|
+
--pfad <skill-pfad> Skill-Ordner in der Quelle, wenn der Name dort mehrfach vorkommt (E121)
|
|
150
151
|
--version <spanne> Versionseinschränkung nach Composer-Regeln (etwa ^1.2) oder ein Tag- oder
|
|
151
152
|
Branchname. Nur mit Zeiger, also dir:<pfad> ohne --local (E33)
|
|
152
153
|
--composer <pfad> composer.json des Arbeitsverzeichnisses, wenn mehrere in Frage kommen
|
|
@@ -155,11 +156,15 @@ Schalter:
|
|
|
155
156
|
|
|
156
157
|
Beispiele:
|
|
157
158
|
hmgr link netzwerk
|
|
159
|
+
hmgr link impeccable --pfad plugin/skills/impeccable
|
|
158
160
|
hmgr link netzwerk --harness hermes --ort profil:researcher
|
|
159
161
|
hmgr link tq-schema --ort dir:. --version ^2.0
|
|
160
162
|
|
|
161
163
|
Häufige Fälle:
|
|
162
164
|
„liegt in mehreren Quellen": mit --quelle <teilstring der URL oder des Pfads> entscheiden.
|
|
165
|
+
„liegt in der Quelle … mehrfach": mit --pfad einen der genannten Pfade wählen. Liegt genau
|
|
166
|
+
eine Fassung im Skill-Ordner des Harness (claude-code .claude/skills, hermes .hermes/skills,
|
|
167
|
+
agents .agents/skills), nimmt hmgr sie von selbst und fragt nicht nach.
|
|
163
168
|
„liegt bereits ein fremder Eintrag": --ersetzen setzen oder vorher hmgr adopt <name>.
|
|
164
169
|
„gibt es keinen Zeiger": --version braucht ein Arbeitsverzeichnis mit composer.json und kein
|
|
165
170
|
--local. Ohne Zeiger den Link ohne --version legen.
|
package/dist/cli/main.js
CHANGED
|
@@ -121,7 +121,7 @@ const SCHALTER = {
|
|
|
121
121
|
source: { werte: ['name'], flaggen: [] },
|
|
122
122
|
dir: { werte: ['composer'], flaggen: [] },
|
|
123
123
|
link: {
|
|
124
|
-
werte: ['harness', 'ort', 'composer', 'quelle', 'version'],
|
|
124
|
+
werte: ['harness', 'ort', 'composer', 'quelle', 'version', 'pfad'],
|
|
125
125
|
flaggen: ['local', 'lokal', 'ersetzen'],
|
|
126
126
|
},
|
|
127
127
|
unlink: { werte: ['harness', 'ort', 'composer'], flaggen: ['local', 'lokal'] },
|
|
@@ -507,10 +507,12 @@ export async function ausfuehren(argv, umgebung, optionen = {}) {
|
|
|
507
507
|
}
|
|
508
508
|
const quelle = werte.get('quelle');
|
|
509
509
|
const version = werte.get('version');
|
|
510
|
+
const pfad = werte.get('pfad');
|
|
510
511
|
const link = await anwendungsfaelle.linkLegen({
|
|
511
512
|
skill,
|
|
512
513
|
ziel,
|
|
513
514
|
...(quelle === undefined ? {} : { quelle }),
|
|
515
|
+
...(pfad === undefined ? {} : { pfad }),
|
|
514
516
|
...(version === undefined ? {} : { version }),
|
|
515
517
|
ersetzen: flaggen.has('ersetzen'),
|
|
516
518
|
lokal,
|
|
@@ -1320,7 +1322,9 @@ function istModellFehler(fehler) {
|
|
|
1320
1322
|
*/
|
|
1321
1323
|
function naechsterSchritt(fehler) {
|
|
1322
1324
|
if (fehler instanceof SkillMehrdeutig)
|
|
1323
|
-
return
|
|
1325
|
+
return fehler.nurEineQuelle
|
|
1326
|
+
? `Fassung wählen: hmgr link ${fehler.name} --pfad <einer der genannten Pfade>`
|
|
1327
|
+
: `Quelle eingrenzen: hmgr link ${fehler.name} --quelle <teilstring einer der genannten Quellen>`;
|
|
1324
1328
|
if (fehler instanceof SkillUnbekannt)
|
|
1325
1329
|
return 'Erst die Quelle hinzufügen: hmgr source add <url|pfad>. hmgr source list zeigt die bekannten Quellen.';
|
|
1326
1330
|
if (fehler instanceof NameBelegt)
|
package/dist/gui/main.js
CHANGED
|
@@ -228,6 +228,7 @@ function registriereIpc() {
|
|
|
228
228
|
...(skill.eigenerKontext === undefined ? {} : { eigenerKontext: skill.eigenerKontext }),
|
|
229
229
|
...(skill.argumentHinweis === undefined ? {} : { argumentHinweis: skill.argumentHinweis }),
|
|
230
230
|
...(skill.geaendert === undefined ? {} : { geaendert: skill.geaendert }),
|
|
231
|
+
...(skill.jeHarness === undefined ? {} : { jeHarness: skill.jeHarness }),
|
|
231
232
|
quelleText: quelleAlsText(eintrag.quelle),
|
|
232
233
|
quelleName: quelleName(eintrag.quelle),
|
|
233
234
|
quelleSchluessel: quelleSchluessel(eintrag.quelle),
|
|
@@ -886,6 +887,8 @@ function fensterOeffnen() {
|
|
|
886
887
|
var dskBundleBoxSichtbar = false;
|
|
887
888
|
var dskBundleText = null;
|
|
888
889
|
var dskBundleZuVorher = null, dskBundleKoerperText = null;
|
|
890
|
+
// E121: ein Name mit mehreren Fassungen in der Quelle steht einmal, mit Vermerk statt Pfad.
|
|
891
|
+
var dskMehrfachAnzahl = null, dskMehrfachText = null;
|
|
889
892
|
// Aufklappbereich je Zeile (E92): zu vor dem Klick, danach sichtbar mit der ungekürzten
|
|
890
893
|
// Beschreibung; die Checkbox bleibt unberührt, der Dialog offen.
|
|
891
894
|
var dskKoerperVorher = null;
|
|
@@ -920,6 +923,10 @@ function fensterOeffnen() {
|
|
|
920
923
|
dskAufklapp?.click();
|
|
921
924
|
dskKoerper?.querySelector('p')?.click();
|
|
922
925
|
dskAufklappFreiAngehakt = dskEingabe?.checked ?? null;
|
|
926
|
+
var dskMehrfach = Array.from(document.querySelectorAll('#dsk-liste .wahlzeile'))
|
|
927
|
+
.filter((z) => z.querySelector('b')?.textContent === 'zmehrfach');
|
|
928
|
+
dskMehrfachAnzahl = dskMehrfach.length;
|
|
929
|
+
dskMehrfachText = dskMehrfach[0]?.querySelector('.mono')?.textContent ?? null;
|
|
923
930
|
dskBundleBoxSichtbar = document.getElementById('dsk-bundlebox')?.hidden === false;
|
|
924
931
|
dskBundleText = document.querySelector('#dsk-bundles .wahlzeile')?.textContent
|
|
925
932
|
?.replace(/\\s+/g, ' ').trim() ?? null;
|
|
@@ -1283,6 +1290,8 @@ function fensterOeffnen() {
|
|
|
1283
1290
|
katalogDetails,
|
|
1284
1291
|
katalogMarkenWarnend,
|
|
1285
1292
|
dskMarken,
|
|
1293
|
+
dskMehrfachAnzahl,
|
|
1294
|
+
dskMehrfachText,
|
|
1286
1295
|
dskKoerperVorher,
|
|
1287
1296
|
dskKoerperNachher,
|
|
1288
1297
|
dskKoerperText,
|
|
@@ -813,7 +813,7 @@
|
|
|
813
813
|
/** Skill zu einem Mitglied einer Definition aus dem Skill-Katalog (E114 L1): gleiche Quelle, gleicher
|
|
814
814
|
Pfad. null, wenn die Quelle (noch) nicht eingerichtet oder nicht lesbar ist. */
|
|
815
815
|
function bundleMitgliedSkill(m) {
|
|
816
|
-
return SKILLS.filter(function (s) { return s.quelleSchluessel === m.quelleSchluessel && s.pfad === m.pfad; })[0] || null;
|
|
816
|
+
return SKILLS.filter(function (s) { return s.quelleSchluessel === m.quelleSchluessel && (s.pfad === m.pfad || (s.jeHarness || []).indexOf(m.pfad) > -1); })[0] || null;
|
|
817
817
|
}
|
|
818
818
|
|
|
819
819
|
/** Skill eines nicht verlinkten Mitglieds über seinen Namen, gesucht unter den Mitgliedern der
|
|
@@ -2274,7 +2274,8 @@
|
|
|
2274
2274
|
// Skill-Ordner berührt. Nicht der Pull-Zeitpunkt — der steht als „Zuletzt geprüft" in der
|
|
2275
2275
|
// Update-Ansicht und wäre für alle Skills einer Quelle derselbe.
|
|
2276
2276
|
var geaendert = datumDeutsch(skill.geaendert);
|
|
2277
|
-
var nachRef = ' · Ref ' + skill.ref + (geaendert ? ' · geändert ' + geaendert : '')
|
|
2277
|
+
var nachRef = ' · Ref ' + skill.ref + (geaendert ? ' · geändert ' + geaendert : '')
|
|
2278
|
+
+ (skill.jeHarness ? ' · ' + JE_HARNESS_VERMERK : '');
|
|
2278
2279
|
if (herkunftQuelle) {
|
|
2279
2280
|
herkunft.appendChild(quelleLinkElement(herkunftQuelle));
|
|
2280
2281
|
herkunft.appendChild(e('b', null, nachRef));
|
|
@@ -2341,7 +2342,8 @@
|
|
|
2341
2342
|
var sichtbar = 0;
|
|
2342
2343
|
document.querySelectorAll('#katalog .zeile').forEach(function (li) {
|
|
2343
2344
|
var skill = SKILLS[+li.dataset.index];
|
|
2344
|
-
var passtSuche = !suche || suchform(skill.name).indexOf(suche) > -1 || suchform(skill.pfad).indexOf(suche) > -1
|
|
2345
|
+
var passtSuche = !suche || suchform(skill.name).indexOf(suche) > -1 || suchform(skill.pfad).indexOf(suche) > -1
|
|
2346
|
+
|| (skill.jeHarness || []).some(function (p) { return suchform(p).indexOf(suche) > -1; });
|
|
2345
2347
|
var passtFilter = quellenFilter === 'alle' || skill.quelleSchluessel === quellenFilter;
|
|
2346
2348
|
var an = passtSuche && passtFilter;
|
|
2347
2349
|
li.hidden = !an;
|
|
@@ -2581,9 +2583,13 @@
|
|
|
2581
2583
|
/** Quelle · [Pfad ·] Ref für eine Skill-Karte im „Skills hinzufügen"-Dialog (F106): der Pfad
|
|
2582
2584
|
unterscheidet Skills, die unter demselben Namen mehrfach im selben Repo liegen (z. B. je
|
|
2583
2585
|
Harness ein eigener Ordner). Ein Wurzel-Skill hat pfad === '' und zeigt kein Pfad-Segment. */
|
|
2586
|
+
var JE_HARNESS_VERMERK = 'je Harness eigene Fassung';
|
|
2587
|
+
|
|
2584
2588
|
function skillQuelleBeschriftung(skill) {
|
|
2585
2589
|
var teile = [skill.quelleName];
|
|
2586
|
-
|
|
2590
|
+
// Mehrfach in der Quelle, je Harness eine eigene Fassung (E121): der Kern löst beim Verlinken auf.
|
|
2591
|
+
if (skill.jeHarness) teile.push(JE_HARNESS_VERMERK);
|
|
2592
|
+
else if (skill.pfad) teile.push(skill.pfad);
|
|
2587
2593
|
teile.push('Ref ' + skill.ref);
|
|
2588
2594
|
return teile.join(' · ');
|
|
2589
2595
|
}
|
|
@@ -861,10 +861,10 @@ export class Anwendungsfaelle {
|
|
|
861
861
|
ergebnis.push({
|
|
862
862
|
quelle,
|
|
863
863
|
ref,
|
|
864
|
-
skills: skills.map((skill) => {
|
|
864
|
+
skills: this.fassungenZusammenfassen(skills.map((skill) => {
|
|
865
865
|
const geaendert = daten.get(skill.pfad);
|
|
866
866
|
return geaendert === undefined ? skill : { ...skill, geaendert };
|
|
867
|
-
}),
|
|
867
|
+
})),
|
|
868
868
|
});
|
|
869
869
|
}
|
|
870
870
|
catch (fehler) {
|
|
@@ -873,6 +873,39 @@ export class Anwendungsfaelle {
|
|
|
873
873
|
}
|
|
874
874
|
return ergebnis;
|
|
875
875
|
}
|
|
876
|
+
/**
|
|
877
|
+
* Katalog-Zusammenfassung (E121): Ein Name, der in einer Quelle mehrfach vorkommt und mindestens
|
|
878
|
+
* einmal unmittelbar in einem Harness-Skill-Ordner liegt, erscheint einmal, mit `jeHarness`. Als
|
|
879
|
+
* Vertreter dient die Fassung im ersten passenden Harness-Ordner (Reihenfolge der Harnesses),
|
|
880
|
+
* sonst die erste. Alle anderen Namen bleiben unverändert, ebenso die Reihenfolge.
|
|
881
|
+
*/
|
|
882
|
+
fassungenZusammenfassen(skills) {
|
|
883
|
+
const ordner = this.p.harnesses.map((h) => `${h.quellOrdner()}/`);
|
|
884
|
+
const direkt = (s, o) => s.pfad.startsWith(o) && !s.pfad.slice(o.length).includes('/');
|
|
885
|
+
const gruppen = new Map();
|
|
886
|
+
for (const s of skills)
|
|
887
|
+
gruppen.set(s.name, [...(gruppen.get(s.name) ?? []), s]);
|
|
888
|
+
const ergebnis = [];
|
|
889
|
+
for (const s of skills) {
|
|
890
|
+
const gruppe = gruppen.get(s.name);
|
|
891
|
+
if (gruppe.length < 2 || !gruppe.some((g) => ordner.some((o) => direkt(g, o)))) {
|
|
892
|
+
ergebnis.push(s);
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
if (gruppe[0] !== s)
|
|
896
|
+
continue; // Vertreter steht an der Stelle der ersten Fassung
|
|
897
|
+
let vertreter = gruppe[0];
|
|
898
|
+
for (const o of ordner) {
|
|
899
|
+
const treffer = gruppe.find((g) => direkt(g, o));
|
|
900
|
+
if (treffer !== undefined) {
|
|
901
|
+
vertreter = treffer;
|
|
902
|
+
break;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
ergebnis.push({ ...vertreter, jeHarness: gruppe.map((g) => g.pfad) });
|
|
906
|
+
}
|
|
907
|
+
return ergebnis;
|
|
908
|
+
}
|
|
876
909
|
/** Alle Marketplaces der bekannten Quellen, für `hmgr plugin list`. */
|
|
877
910
|
async marketplaces() {
|
|
878
911
|
const zustand = await this.p.zustand.lesen();
|
|
@@ -1566,7 +1599,7 @@ export class Anwendungsfaelle {
|
|
|
1566
1599
|
throw new Error(`Mehrere Quellen passen auf „${hinweis}", bitte eingrenzen:\n${zeilen(treffer)}`);
|
|
1567
1600
|
}
|
|
1568
1601
|
/** Skill über alle Quellen suchen. Mehrere Treffer sind nur mit Quellenhinweis erlaubt. */
|
|
1569
|
-
async skillFinden(name, quelleHinweis) {
|
|
1602
|
+
async skillFinden(name, quelleHinweis, wahl = {}) {
|
|
1570
1603
|
const zustand = await this.p.zustand.lesen();
|
|
1571
1604
|
const funde = [];
|
|
1572
1605
|
for (const quelle of zustand.quellen) {
|
|
@@ -1574,16 +1607,33 @@ export class Anwendungsfaelle {
|
|
|
1574
1607
|
continue;
|
|
1575
1608
|
const ref = await this.p.quellen.standardRef(quelle);
|
|
1576
1609
|
const skills = await this.p.quellen.skills(quelle, ref);
|
|
1577
|
-
for (const skill of skills)
|
|
1578
|
-
|
|
1579
|
-
funde.push({ quelle, ref, skill });
|
|
1610
|
+
for (const skill of Anwendungsfaelle.skillTreffer(skills, name, wahl))
|
|
1611
|
+
funde.push({ quelle, ref, skill });
|
|
1580
1612
|
}
|
|
1581
1613
|
if (funde.length === 0)
|
|
1582
1614
|
throw new SkillUnbekannt(name);
|
|
1583
1615
|
if (funde.length > 1)
|
|
1584
|
-
throw new SkillMehrdeutig(name, funde.map((f) => f.quelle));
|
|
1616
|
+
throw new SkillMehrdeutig(name, funde.map((f) => ({ quelle: f.quelle, pfad: f.skill.pfad })));
|
|
1585
1617
|
return funde[0];
|
|
1586
1618
|
}
|
|
1619
|
+
/**
|
|
1620
|
+
* Die Skills einer Quelle zu einem Namen (E121). Mit `pfad` zählt nur der Skill mit genau diesem
|
|
1621
|
+
* Pfad. Sonst gewinnt bei mehreren Fassungen die eine, die unmittelbar im Skill-Ordner des
|
|
1622
|
+
* Harness liegt (`<quellOrdner>/<ordner>`, eine Ebene); gibt es keine solche oder mehrere,
|
|
1623
|
+
* bleiben alle, und der Aufrufer meldet die Mehrdeutigkeit.
|
|
1624
|
+
*/
|
|
1625
|
+
static skillTreffer(skills, name, wahl) {
|
|
1626
|
+
const gleichnamig = skills.filter((s) => s.name === name);
|
|
1627
|
+
if (wahl.pfad !== undefined) {
|
|
1628
|
+
const pfad = wahl.pfad.replace(/^\.?\/+|\/+$/g, '');
|
|
1629
|
+
return gleichnamig.filter((s) => s.pfad === pfad);
|
|
1630
|
+
}
|
|
1631
|
+
if (gleichnamig.length < 2 || wahl.quellOrdner === undefined)
|
|
1632
|
+
return gleichnamig;
|
|
1633
|
+
const praefix = `${wahl.quellOrdner}/`;
|
|
1634
|
+
const direkt = gleichnamig.filter((s) => s.pfad.startsWith(praefix) && !s.pfad.slice(praefix.length).includes('/'));
|
|
1635
|
+
return direkt.length === 1 ? direkt : gleichnamig;
|
|
1636
|
+
}
|
|
1587
1637
|
/** Checkout anlegen oder erweitern, Ziel vorbereiten, Link setzen. Ohne Zeiger-Arbeit. */
|
|
1588
1638
|
async linkAnlegen(harness, ziel, fund, ersetzen) {
|
|
1589
1639
|
if (!harness.orte().includes(ziel.ort.art))
|
|
@@ -1627,8 +1677,12 @@ export class Anwendungsfaelle {
|
|
|
1627
1677
|
if (!harness.orte().includes(args.ziel.ort.art))
|
|
1628
1678
|
throw new OrtNichtUnterstuetzt(harness.name, args.ziel.ort.art);
|
|
1629
1679
|
const version = args.version;
|
|
1680
|
+
const wahl = {
|
|
1681
|
+
quellOrdner: harness.quellOrdner(),
|
|
1682
|
+
...(args.pfad === undefined ? {} : { pfad: args.pfad }),
|
|
1683
|
+
};
|
|
1630
1684
|
if (version === undefined) {
|
|
1631
|
-
const fund = await this.skillFinden(args.skill, args.quelle);
|
|
1685
|
+
const fund = await this.skillFinden(args.skill, args.quelle, wahl);
|
|
1632
1686
|
const ergebnis = await this.linkAusFund(harness, args.ziel, fund, args.ersetzen, args.lokal);
|
|
1633
1687
|
return Anwendungsfaelle.hinweisAnhaengen(ergebnis, await this.bundleMitgliedZurueckholen(args.ziel, fund));
|
|
1634
1688
|
}
|
|
@@ -1640,7 +1694,7 @@ export class Anwendungsfaelle {
|
|
|
1640
1694
|
// Eine Versionseinschränkung schreibt immer geteilt (siehe EinschraenkungOhneZeiger oben), das
|
|
1641
1695
|
// trifft die Sperre also ausnahmslos, solange sie steht (E57).
|
|
1642
1696
|
await this.zeigerSchreibenPruefen(args.ziel, args.lokal);
|
|
1643
|
-
const fund = await this.fundAusZeiger(args.skill, version, args.quelle);
|
|
1697
|
+
const fund = await this.fundAusZeiger(args.skill, version, args.quelle, wahl);
|
|
1644
1698
|
const link = await this.linkAnlegen(harness, args.ziel, fund, args.ersetzen);
|
|
1645
1699
|
await this.zeigerErgaenzen(zeigerPfad, fund, version);
|
|
1646
1700
|
const hinweis = await this.harnessHinweis(harness, args.ziel.ort);
|
|
@@ -1957,9 +2011,9 @@ export class Anwendungsfaelle {
|
|
|
1957
2011
|
* gilt der Text als genauer Ref-Name gegen alle Refs, damit Tags und Branches ohne
|
|
1958
2012
|
* Versions-Schema erreichbar bleiben. Nie auf den Standard-Ref ausweichen (B8).
|
|
1959
2013
|
*/
|
|
1960
|
-
async fundAusZeiger(name, einschraenkung, quelleHinweis) {
|
|
2014
|
+
async fundAusZeiger(name, einschraenkung, quelleHinweis, wahl = {}) {
|
|
1961
2015
|
if (einschraenkung === null)
|
|
1962
|
-
return await this.skillFinden(name, quelleHinweis);
|
|
2016
|
+
return await this.skillFinden(name, quelleHinweis, wahl);
|
|
1963
2017
|
const zustand = await this.p.zustand.lesen();
|
|
1964
2018
|
const quellen = zustand.quellen.filter((q) => quellePasst(q, quelleHinweis));
|
|
1965
2019
|
for (const quelle of quellen) {
|
|
@@ -1968,7 +2022,7 @@ export class Anwendungsfaelle {
|
|
|
1968
2022
|
const ref = passenderRef(tags, einschraenkung);
|
|
1969
2023
|
if (ref === null)
|
|
1970
2024
|
continue;
|
|
1971
|
-
const skill = (await this.p.quellen.skills(quelle, ref)
|
|
2025
|
+
const skill = Anwendungsfaelle.skillTreffer(await this.p.quellen.skills(quelle, ref), name, wahl)[0];
|
|
1972
2026
|
if (skill)
|
|
1973
2027
|
return { quelle, ref, skill };
|
|
1974
2028
|
}
|
|
@@ -1976,7 +2030,7 @@ export class Anwendungsfaelle {
|
|
|
1976
2030
|
const refs = await this.p.quellen.refs(quelle).catch(() => []);
|
|
1977
2031
|
if (!refs.includes(einschraenkung))
|
|
1978
2032
|
continue;
|
|
1979
|
-
const skill = (await this.p.quellen.skills(quelle, einschraenkung)
|
|
2033
|
+
const skill = Anwendungsfaelle.skillTreffer(await this.p.quellen.skills(quelle, einschraenkung), name, wahl)[0];
|
|
1980
2034
|
if (skill)
|
|
1981
2035
|
return { quelle, ref: einschraenkung, skill };
|
|
1982
2036
|
}
|
|
@@ -2053,7 +2107,7 @@ export class Anwendungsfaelle {
|
|
|
2053
2107
|
}
|
|
2054
2108
|
for (const [name, einschraenkung] of zeiger.skills) {
|
|
2055
2109
|
try {
|
|
2056
|
-
const fund = await this.fundAusZeiger(name, einschraenkung);
|
|
2110
|
+
const fund = await this.fundAusZeiger(name, einschraenkung, undefined, { quellOrdner: harness.quellOrdner() });
|
|
2057
2111
|
const gefunden = eintraege.find((e) => e.art === 'link' && e.link.name === name);
|
|
2058
2112
|
// Ein eigener Link auf einen anderen Ref weicht ab und wird umgelegt (E33). Das trifft
|
|
2059
2113
|
// die Einschränkung, die inzwischen einen höheren Tag findet.
|
package/dist/kern/modell.js
CHANGED
|
@@ -338,10 +338,24 @@ export class LinkAnlegenFehlgeschlagen extends Error {
|
|
|
338
338
|
export class SkillMehrdeutig extends Error {
|
|
339
339
|
name;
|
|
340
340
|
quellen;
|
|
341
|
-
|
|
342
|
-
|
|
341
|
+
funde;
|
|
342
|
+
/** Die Mehrdeutigkeit kommt aus einer einzigen Quelle: `--pfad` hilft, nicht `--quelle` (E121). */
|
|
343
|
+
nurEineQuelle;
|
|
344
|
+
constructor(name, funde) {
|
|
345
|
+
const quellen = [];
|
|
346
|
+
for (const f of funde)
|
|
347
|
+
if (!quellen.some((q) => quelleSchluessel(q) === quelleSchluessel(f.quelle)))
|
|
348
|
+
quellen.push(f.quelle);
|
|
349
|
+
const zeilen = funde
|
|
350
|
+
.map((f) => ` ${quelleSchluessel(f.quelle)}: ${f.pfad === '' ? '(Repo-Wurzel)' : f.pfad}`)
|
|
351
|
+
.join('\n');
|
|
352
|
+
super(quellen.length === 1
|
|
353
|
+
? `Skill „${name}" liegt in der Quelle ${quelleSchluessel(quellen[0])} mehrfach:\n${zeilen}`
|
|
354
|
+
: `Skill „${name}" liegt in mehreren Quellen:\n${zeilen}`);
|
|
343
355
|
this.name = name;
|
|
344
356
|
this.quellen = quellen;
|
|
357
|
+
this.funde = funde;
|
|
358
|
+
this.nurEineQuelle = quellen.length === 1;
|
|
345
359
|
}
|
|
346
360
|
}
|
|
347
361
|
export class SkillUnbekannt extends Error {
|