kimal3 0.2.0 → 0.2.1
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/api.js +43 -8
- package/dist/arbeitsplatz-dateien.js +84 -22
- package/dist/argumente.js +150 -0
- package/dist/befehle/arbeitsplatz.js +139 -17
- package/dist/befehle/kontext-fragen.js +17 -0
- package/dist/befehle/kontext-gemeinsam.js +17 -3
- package/dist/befehle/kontext-hoch.js +36 -3
- package/dist/befehle/kontext-runter.js +58 -7
- package/dist/befehle/skill-install.js +51 -17
- package/dist/befehle/werkbank.js +128 -17
- package/dist/befehle-katalog.js +14 -7
- package/dist/firmen-liste.js +4 -2
- package/dist/kimal3.js +20 -2
- package/dist/kontext-stand.js +304 -50
- package/dist/nachricht.js +87 -3
- package/package.json +1 -1
- package/skill/SKILL.md +44 -8
- package/skill/commands/k3.md +59 -18
- package/skill/commands/k3kontext.md +89 -0
- /package/skill/commands/{k3firma.md → k3analyse.md} +0 -0
package/dist/kontext-stand.js
CHANGED
|
@@ -42,6 +42,18 @@ import { createHash } from "node:crypto";
|
|
|
42
42
|
* ⛔ Die Werkbank-`CLAUDE.md` steht NICHT hier. Sie traegt einen Namen im
|
|
43
43
|
* Ordner und gehoert einem Menschen (Spec §4).
|
|
44
44
|
*/
|
|
45
|
+
/**
|
|
46
|
+
* Die oberste `CLAUDE.md` des Firmen-Ordners -- die einzige verwaltete Datei,
|
|
47
|
+
* die den Firmennamen im Klartext traegt (seit A-11) UND den Weg zum zweiten
|
|
48
|
+
* Menschen mitgeht (sie steht in der Positiv-Liste der `.gitignore`).
|
|
49
|
+
* Deshalb ist sie das Erkennungszeichen in `firmennameAusClaudeMd`.
|
|
50
|
+
*
|
|
51
|
+
* ⚠️ Sie ist zugleich der erste Eintrag von `VERWALTETE_DATEIEN` darunter --
|
|
52
|
+
* dass beide dieselbe Datei meinen, prueft `check:cli`. Dort haengt auch die
|
|
53
|
+
* Pruefung, dass die ECHTE Vorlage ihre Ueberschrift noch so schreibt, wie
|
|
54
|
+
* `firmennameAusClaudeMd` sie liest.
|
|
55
|
+
*/
|
|
56
|
+
export const FIRMEN_CLAUDE_MD = "CLAUDE.md";
|
|
45
57
|
export const VERWALTETE_DATEIEN = [
|
|
46
58
|
"CLAUDE.md",
|
|
47
59
|
"kontext/kurzprofil.md",
|
|
@@ -117,6 +129,83 @@ export const LEER = "leer";
|
|
|
117
129
|
export const FORMAT_AKTUELL = 1;
|
|
118
130
|
/** Der leere Merkzettel -- weder Datei-Eintraege noch eine bekannte Firma. */
|
|
119
131
|
const LEERER_MERKZETTEL = { firma_id: null, dateien: {} };
|
|
132
|
+
/**
|
|
133
|
+
* Den Firmennamen aus der obersten `CLAUDE.md` lesen -- ihre erste Zeile
|
|
134
|
+
* lautet `# CLAUDE.md — <Firma> · KI-Arbeitsplatz`.
|
|
135
|
+
*
|
|
136
|
+
* 🔴 **Warum es diese zweite Quelle ueberhaupt braucht** (Befund 2 der DRITTEN
|
|
137
|
+
* Review-Runde, 2026-08-27, und er trifft die Reparatur der zweiten):
|
|
138
|
+
* `firmenAbgleich` verglich zuerst nur die IDs aus den Merkzetteln. Der
|
|
139
|
+
* Merkzettel steht aber in der `.gitignore` der Firmenvorlage -- bewusst, er
|
|
140
|
+
* ist Maschinenzustand. **Genau der Fall, fuer den die Wache gebaut wurde, hat
|
|
141
|
+
* ihn deshalb nie:** Wer den Firmenordner als Kopie oder ueber das Repo der
|
|
142
|
+
* Firma bekommt -- also der zweite Mensch, fuer den `werkbank neu` da ist --
|
|
143
|
+
* hat kein `.kimal3-stand.json`. `firma_id` war `null`, die Antwort lautete
|
|
144
|
+
* `unbekannt`, und die Wache liess durch.
|
|
145
|
+
* *Eine Wache, die ihr Erkennungszeichen aus einer Datei liest, die den Weg
|
|
146
|
+
* zum Kunden gar nicht mitgeht, leuchtet fuer immer gruen.*
|
|
147
|
+
*
|
|
148
|
+
* 🔑 Die `CLAUDE.md` geht den Weg mit: Sie steht ausdruecklich in der
|
|
149
|
+
* Positiv-Liste der `.gitignore` (`!/CLAUDE.md`), und seit A-11 traegt sie den
|
|
150
|
+
* echten Firmennamen statt eines Platzhalters.
|
|
151
|
+
*
|
|
152
|
+
* ⚠️ Ein unersetzter `[FIRMA]`-Platzhalter zaehlt als **kein** Name: Er steht
|
|
153
|
+
* genau dann da, wenn der Server die Firma nicht kannte -- also im
|
|
154
|
+
* Vordruck-Fall, in dem es nichts zu vergleichen gibt.
|
|
155
|
+
*/
|
|
156
|
+
export function firmennameAusClaudeMd(inhalt) {
|
|
157
|
+
if (inhalt === null)
|
|
158
|
+
return null;
|
|
159
|
+
const treffer = /^#\s*CLAUDE\.md\s*—\s*(.+?)\s*·\s*KI-Arbeitsplatz\s*$/m.exec(inhalt);
|
|
160
|
+
if (treffer === null)
|
|
161
|
+
return null;
|
|
162
|
+
const name = treffer[1].trim();
|
|
163
|
+
return name === "" || name === "[FIRMA]" ? null : name;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* 🔑 **ZWEI Erkennungszeichen, in dieser Reihenfolge -- die ID schlaegt den
|
|
167
|
+
* Namen.** Zwei Firmen duerfen gleich heissen (dafuer gibt es `--firma-id`),
|
|
168
|
+
* aber nie dieselbe ID haben. Wo beide Seiten eine ID kennen, ist die Antwort
|
|
169
|
+
* also sicher; der Name ist der Rueckfall fuer den geklonten Ordner, der
|
|
170
|
+
* keinen Merkzettel hat.
|
|
171
|
+
*
|
|
172
|
+
* ⚠️ **Der Name ist die schwaechere Auskunft und wird nur gefragt, wenn die
|
|
173
|
+
* ID schweigt** -- nicht zusaetzlich. Sonst widersprechen sich zwei Quellen
|
|
174
|
+
* bei zwei gleichnamigen Firmen, und die staerkere verloere.
|
|
175
|
+
*/
|
|
176
|
+
export function firmenAbgleich(lokal, geliefert) {
|
|
177
|
+
if (lokal.id !== null && geliefert.id !== null) {
|
|
178
|
+
return lokal.id === geliefert.id ? { art: "passt" } : { art: "andere-firma" };
|
|
179
|
+
}
|
|
180
|
+
if (lokal.name !== null && geliefert.name !== null) {
|
|
181
|
+
if (lokal.name === geliefert.name)
|
|
182
|
+
return { art: "passt" };
|
|
183
|
+
/*
|
|
184
|
+
🔴 **EIN VERSCHIEDENER NAME IST EIN VERDACHT, KEIN BEWEIS** (Befund 1
|
|
185
|
+
der vierten Review-Runde, 2026-08-27 -- und er trifft die Reparatur der
|
|
186
|
+
dritten).
|
|
187
|
+
|
|
188
|
+
Die `CLAUDE.md` ist ausdruecklich eine Datei, die der Kunde AENDERN
|
|
189
|
+
darf: `kontext runter` sagt ihm woertlich „Ich fasse nichts an -- du
|
|
190
|
+
hast lokal geaendert". Schreibt eine Admin in die erste Zeile den vollen
|
|
191
|
+
Firmennamen („Nordwind Handel GmbH"), waehrend die App noch „Nordwind"
|
|
192
|
+
fuehrt, und legt den Ordner ins Firmen-Repo, dann liest ihr Kollege beim
|
|
193
|
+
Klonen einen Namen, der nicht zum gelieferten passt.
|
|
194
|
+
|
|
195
|
+
Mit `andere-firma` waere er damit HART GESPERRT worden -- mit einem Satz,
|
|
196
|
+
der falsch ist („eine andere Firma") und keinen gangbaren Ausweg nennt.
|
|
197
|
+
*Und gesperrt worden waere genau der Mensch, fuer den `werkbank neu`
|
|
198
|
+
ueberhaupt gebaut ist.*
|
|
199
|
+
|
|
200
|
+
🔑 Deshalb `zweifel`: Der Name ist das SCHWAECHERE Erkennungszeichen und
|
|
201
|
+
bekommt die schwaechere Folge. Sperren darf nur, was sicher ist -- die
|
|
202
|
+
ID. *Wer auf einen Verdacht hin zusperrt, schadet oefter dem Unschuldigen
|
|
203
|
+
als dem Fall, den er treffen wollte.*
|
|
204
|
+
*/
|
|
205
|
+
return { art: "zweifel", hier: lokal.name, gewaehlt: geliefert.name };
|
|
206
|
+
}
|
|
207
|
+
return { art: "unbekannt" };
|
|
208
|
+
}
|
|
120
209
|
/**
|
|
121
210
|
* Kurz-Pruefsumme des Inhalts. Zwoelf Hexzeichen aus SHA-256.
|
|
122
211
|
*
|
|
@@ -333,24 +422,27 @@ export function bekannterStandAus(merkzettel) {
|
|
|
333
422
|
* vergessenes Argument ist das nicht: Wer diese Funktion aufruft, muss sich
|
|
334
423
|
* entscheiden, nicht stillschweigend `null` bekommen.
|
|
335
424
|
*
|
|
336
|
-
* 🔴 TASK 2: `vorlagenPruefsummen`
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
425
|
+
* 🔴 TASK 2: `vorlagenPruefsummen` traegt je Datei den Fingerabdruck UNSERER
|
|
426
|
+
* VORLAGE -- nicht den des ausgelieferten Inhalts (das ist `pruef`). Fehlt
|
|
427
|
+
* eine Pruefsumme fuer eine Datei, traegt ihr `vorlage`-Feld `LEER` --
|
|
428
|
+
* derselbe Sicherheitswert wie beim ungepflegten `stand` zwei Zeilen weiter
|
|
429
|
+
* unten, aus demselben Grund: *wer nichts weiss, behauptet nichts.*
|
|
430
|
+
*
|
|
431
|
+
* 🔴 **PUNKT A-1 (2026-08-26): DIESES ARGUMENT IST JETZT PFLICHT.** Es war
|
|
432
|
+
* optional, mit Default `{}` -- und genau deshalb hat es ein halbes Jahr lang
|
|
433
|
+
* niemand uebergeben. `ausliefern.ts` rief die Funktion mit drei Werten auf,
|
|
434
|
+
* jeder ausgelieferte Merkzettel trug bei allen sechs Dateien
|
|
435
|
+
* `"vorlage": "leer"`, und die Lage `vorlage-neuer` unten konnte in der
|
|
436
|
+
* Wirklichkeit nie entstehen: *keine fehlende Zeile, kein Compiler-Fehler,
|
|
437
|
+
* kein roter Waechter.* Ein Pflicht-Argument ist die einzige Absicherung, die
|
|
438
|
+
* auch den erwischt, der diesen Kommentar nie liest.
|
|
347
439
|
*
|
|
348
440
|
* 🔑 `format` wird HIER, beim NEU-Bauen einer Lieferung, immer gesetzt --
|
|
349
441
|
* anders als beim blossen LESEN einer womoeglich alten Datei
|
|
350
442
|
* (`leseMerkzettel` oben). Jede Lieferung, die durch diese Funktion entsteht,
|
|
351
443
|
* ist per Definition die aktuelle Fassung.
|
|
352
444
|
*/
|
|
353
|
-
export function baueMerkzettel(dateien, staende, firmenId, vorlagenPruefsummen
|
|
445
|
+
export function baueMerkzettel(dateien, staende, firmenId, vorlagenPruefsummen) {
|
|
354
446
|
const raus = {};
|
|
355
447
|
for (const pfad of VERWALTETE_DATEIEN) {
|
|
356
448
|
const datei = dateien.find((d) => d.pfad === pfad);
|
|
@@ -454,15 +546,25 @@ export function merkzettelNachHoch(vomServer, lokal, gesendet) {
|
|
|
454
546
|
* Firmen-Zeile -- in beiden Faellen wuerde ein sang- und klangloses
|
|
455
547
|
* Ueberschreiben echte Arbeit verlieren, also wird "beides".
|
|
456
548
|
*
|
|
457
|
-
* 🔴 `aktuelleVorlage`
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
*
|
|
465
|
-
*
|
|
549
|
+
* 🔴 **PUNKT A-1 (2026-08-26): `aktuelleVorlage` IST JETZT PFLICHT.** Es war
|
|
550
|
+
* optional -- mit der Begruendung, das Verdrahten gehoere zu einer spaeteren
|
|
551
|
+
* Aufgabe. Zurueckgekommen ist danach nie jemand: `kontext-runter.ts` rief
|
|
552
|
+
* diese Funktion ohne den Wert auf, `vorlage-neuer` konnte in der
|
|
553
|
+
* Wirklichkeit nicht entstehen, und der Kunde las weiter „Dein Firmenkontext
|
|
554
|
+
* ist aktuell". *Die Rechnung war gebaut, geprueft, dokumentiert -- und tot.*
|
|
555
|
+
* Wer den Wert jetzt weglaesst, bekommt einen Kompilierfehler.
|
|
556
|
+
*
|
|
557
|
+
* ⚠️ **Ein Merkzettel-Eintrag OHNE `vorlage` gilt als „unbekannt", und
|
|
558
|
+
* unbekannt zaehlt als GEAeNDERT.** Solche Eintraege liegen echt auf Platten:
|
|
559
|
+
* Sie stammen von einer Auslieferung, bevor es dieses Feld gab. Der Vergleich
|
|
560
|
+
* `undefined !== aktuelleVorlage` ist wahr, es entsteht also einmalig
|
|
561
|
+
* `vorlage-neuer` bzw. `beides` -- dieselbe Antwort wie bei einem fehlenden
|
|
562
|
+
* Eintrag, aus demselben Grund: *wer nichts weiss, sichert, bevor er
|
|
563
|
+
* ueberschreibt.* Die Gegenrichtung waere schlimmer: Wuerde „unbekannt" als
|
|
564
|
+
* „unveraendert" gelesen, bekaeme der Kunde die Verbesserung nicht -- und der
|
|
565
|
+
* naechste Lauf haette obendrein einen Merkzettel, der den Server-Text
|
|
566
|
+
* beschreibt, waehrend die alte Datei danebenliegt, und meldete faelschlich
|
|
567
|
+
* „du hast lokal geaendert".
|
|
466
568
|
*/
|
|
467
569
|
export function lageFuerDatei(a) {
|
|
468
570
|
if (a.lokalerInhalt === a.serverInhalt)
|
|
@@ -472,19 +574,76 @@ export function lageFuerDatei(a) {
|
|
|
472
574
|
return "server-neuer";
|
|
473
575
|
const lokalGeaendert = a.eintrag === null ? true : pruefsumme(a.lokalerInhalt) !== a.eintrag.pruef;
|
|
474
576
|
const serverNeuer = a.eintrag === null ? true : a.eintrag.stand !== a.serverStand;
|
|
475
|
-
const vorlageNeuer = a.
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
577
|
+
const vorlageNeuer = a.eintrag === null ? true : a.eintrag.vorlage !== a.aktuelleVorlage;
|
|
578
|
+
/*
|
|
579
|
+
🔴 **`vorlageNeuer` zaehlt hier BEWUSST nicht mit** (Review-Befund 1 zu
|
|
580
|
+
Punkt A-1, 2026-08-26 -- gemessen, nicht vermutet).
|
|
581
|
+
|
|
582
|
+
Hier stand einen Nachmittag lang `serverNeuer || vorlageNeuer`. Die Folge:
|
|
583
|
+
Wer seine Datei lokal geaendert hatte, um sie spaeter mit `kimal3 kontext
|
|
584
|
+
hoch` zu schicken, verlor beim naechsten `runter` seinen Arbeitsstand,
|
|
585
|
+
sobald WIR irgendeine Frage umformuliert hatten -- gesichert zwar, aber
|
|
586
|
+
aus der Datei verschwunden, und ohne dass er danach gefragt haette.
|
|
587
|
+
*Eine Verbesserung an unserem Text darf nicht die Arbeit von jemandem
|
|
588
|
+
wegraeumen, der gerade an seiner sitzt.*
|
|
589
|
+
|
|
590
|
+
🔑 Der richtige Weg ist der, den `lokal-geaendert` ohnehin nennt: erst
|
|
591
|
+
hochschicken, dann herunterladen. Dann liegen seine Antworten auf dem
|
|
592
|
+
Server, der Stand aendert sich, und der naechste `runter` bringt seine
|
|
593
|
+
Antworten UND unsere neuen Fragen -- zusammengefuehrt statt eines gegen
|
|
594
|
+
das andere. Wer nie hochschickt, behaelt seine Datei; sie gehoert ihm.
|
|
595
|
+
|
|
596
|
+
⚠️ `vorlage-neuer` unten bleibt davon unberuehrt. Genau dafuer wurde A-1
|
|
597
|
+
gebaut, und es ist der haeufige Fall: eine Datei, die unangetastet so
|
|
598
|
+
dasteht, wie wir sie geliefert haben.
|
|
599
|
+
*/
|
|
480
600
|
if (lokalGeaendert)
|
|
481
|
-
return serverNeuer
|
|
601
|
+
return serverNeuer ? "beides" : "lokal-geaendert";
|
|
482
602
|
if (serverNeuer)
|
|
483
603
|
return "server-neuer";
|
|
484
604
|
if (vorlageNeuer)
|
|
485
605
|
return "vorlage-neuer";
|
|
486
606
|
return "schon-aktuell";
|
|
487
607
|
}
|
|
608
|
+
/**
|
|
609
|
+
* Dieselbe Entscheidung wie {@link lageFuerDatei} -- aber gefuettert aus den
|
|
610
|
+
* ZWEI Merkzetteln, zwischen denen `kimal3 kontext runter` steht: dem auf der
|
|
611
|
+
* Platte und dem aus der Antwort des Servers.
|
|
612
|
+
*
|
|
613
|
+
* 🔴 **WARUM ES DIESE FUNKTION GIBT (Punkt A-1, 2026-08-26).** Der eigentliche
|
|
614
|
+
* Fehler war nicht die Rechnung -- die stimmte. Er war, WOHER ihre Eingaben
|
|
615
|
+
* kommen: `kontext-runter.ts` gab ihr den Vordruck-Abdruck gar nicht erst mit.
|
|
616
|
+
* Genau dieser Schritt ("aus welchem der beiden Merkzettel kommt welcher
|
|
617
|
+
* Wert?") liess sich von keiner Wache sehen, weil er mitten im Befehl wohnte
|
|
618
|
+
* -- zwischen `fetch` und Dateisystem, wo `check:kontext` nie hinkommt.
|
|
619
|
+
*
|
|
620
|
+
* 🔴 **DIE ZUORDNUNG, DIE HIER ABGESICHERT WIRD -- sie ist nicht offensichtlich
|
|
621
|
+
* und in beide Richtungen falsch machbar:**
|
|
622
|
+
* - `eintrag` kommt aus dem LOKALEN Merkzettel. Er sagt, was beim letzten
|
|
623
|
+
* Holen galt: die eine Seite des Vergleichs.
|
|
624
|
+
* - `serverStand` UND `aktuelleVorlage` kommen aus dem Merkzettel DES SERVERS.
|
|
625
|
+
* Sie sagen, was heute gilt: die andere Seite.
|
|
626
|
+
*
|
|
627
|
+
* ⚠️ **Nimmt man beide Seiten aus derselben Datei, vergleicht die Rechnung
|
|
628
|
+
* eine Zahl mit sich selbst und findet NIE einen Unterschied** -- kein Fehler,
|
|
629
|
+
* keine Meldung, der Kunde liest „Dein Firmenkontext ist aktuell". Gemessen:
|
|
630
|
+
* Mit `aktuelleVorlage` aus dem lokalen Merkzettel blieb die verbesserte
|
|
631
|
+
* Datei liegen, und der naechste Lauf behauptete obendrein „du hast lokal
|
|
632
|
+
* geaendert". *Das ist derselbe Schaden wie vorher, nur eine Zeile weiter.*
|
|
633
|
+
*
|
|
634
|
+
* 🔑 Fehlt die Datei im Merkzettel des Servers, gilt fuer beide Werte `LEER`
|
|
635
|
+
* -- „wir wissen nichts", derselbe Rueckfall wie ueberall in dieser Datei.
|
|
636
|
+
*/
|
|
637
|
+
export function lageAusMerkzetteln(a) {
|
|
638
|
+
const vomServer = a.vomServer.dateien[a.pfad] ?? null;
|
|
639
|
+
return lageFuerDatei({
|
|
640
|
+
lokalerInhalt: a.lokalerInhalt,
|
|
641
|
+
serverInhalt: a.serverInhalt,
|
|
642
|
+
eintrag: a.lokal.dateien[a.pfad] ?? null,
|
|
643
|
+
serverStand: vomServer?.stand ?? LEER,
|
|
644
|
+
aktuelleVorlage: vomServer?.vorlage ?? LEER,
|
|
645
|
+
});
|
|
646
|
+
}
|
|
488
647
|
/** `kontext/vorher-2026-08-21` */
|
|
489
648
|
export function sicherungsOrdner(datum) {
|
|
490
649
|
return `${SICHERUNG_BASIS}/vorher-${datum}`;
|
|
@@ -564,6 +723,102 @@ export function arbeitsplatzAus(kandidaten) {
|
|
|
564
723
|
Antworten an der Stelle von `EINSETZ_MARKE_DREI_SAETZE` ein, und dass DIESE
|
|
565
724
|
Marke woertlich in der Vorlage steht, prueft `check:arbeitsplatz`.
|
|
566
725
|
*/
|
|
726
|
+
/**
|
|
727
|
+
* Die ARTEN von Rat, die es gibt -- **in der Reihenfolge, in der sie im
|
|
728
|
+
* Terminal stehen.**
|
|
729
|
+
*
|
|
730
|
+
* 🔑 Diese Liste ist zugleich die Quelle des Typs {@link RatArt}. Wer eine
|
|
731
|
+
* dritte Art erfindet, muss sie hier eintragen -- und bekommt danach vom
|
|
732
|
+
* Compiler gesagt, dass {@link RAT_TEXT} noch keinen Text dafuer hat. *Eine
|
|
733
|
+
* Reihenfolge, die nebenher den Typ traegt, kann nicht unvollstaendig sein.*
|
|
734
|
+
*
|
|
735
|
+
* ⚠️ Die Reihenfolge ist nicht Geschmack: `kimal3 kontext runter` druckt seit
|
|
736
|
+
* Befund F-3 erst den Rat fuer die Firmen-Texte und darunter den fuer unsere
|
|
737
|
+
* Vorlage. Wer sie dreht, dreht die Ausgabe beim Kunden.
|
|
738
|
+
*/
|
|
739
|
+
const RAT_REIHENFOLGE = ["hochschickbar", "nicht-hochschickbar"];
|
|
740
|
+
/**
|
|
741
|
+
* 🔴 **PUNKT A-7 (2026-08-26): DIESE TABELLE IST DIE ABSICHERUNG, NICHT NUR
|
|
742
|
+
* EINE AUFRAEUMAKTION.**
|
|
743
|
+
*
|
|
744
|
+
* Bis hierher zaehlte {@link ratNachUnberuehrt} ihre Faelle auf: ein `if` fuer
|
|
745
|
+
* „irgendetwas aus {@link FIRMEN_TEXTE}" und ein zweites fuer den woertlichen
|
|
746
|
+
* Dateinamen `"CLAUDE.md"`. {@link VERWALTETE_DATEIEN} hat aber SECHS
|
|
747
|
+
* Eintraege, und eine kuenftige SIEBTE waere durch beide `if`s gefallen --
|
|
748
|
+
* ohne Fehler, ohne Meldung, ohne Rat. *Der Mensch haette gelesen, dass seine
|
|
749
|
+
* Datei in Ruhe gelassen wurde, und nirgends, was er jetzt tun soll.*
|
|
750
|
+
*
|
|
751
|
+
* 🔑 **Warum ein `Record` und keine zweite Liste:** Der Schluesseltyp ist die
|
|
752
|
+
* Vereinigung aller Pfade aus {@link VERWALTETE_DATEIEN}. Eine siebte Datei
|
|
753
|
+
* dort weitet ihn -- und dieses Objekt hat dann einen Schluessel zu wenig,
|
|
754
|
+
* *also uebersetzt die CLI nicht mehr*. Das ist die einzige Absicherung, die
|
|
755
|
+
* auch den erwischt, der diesen Kommentar nie liest.
|
|
756
|
+
*
|
|
757
|
+
* ⚠️ **Warum die Zuordnung nicht IN {@link VERWALTETE_DATEIEN} steht**, wo sie
|
|
758
|
+
* inhaltlich hingehoerte: Diese Liste ist an sechs Stellen ausserhalb dieser
|
|
759
|
+
* Datei eine reine Pfadliste (`ausliefern.ts`, `route.ts`,
|
|
760
|
+
* `kontext-runter.ts`, `kontext-dateien.ts`, zwei Waechter). Aus ihr eine
|
|
761
|
+
* Liste von Objekten zu machen, haette all das angefasst -- fuer denselben
|
|
762
|
+
* Schutz, den der `Record` hier ohne einen einzigen fremden Eingriff gibt.
|
|
763
|
+
*
|
|
764
|
+
* ⚠️ **Sie sagt dasselbe wie {@link FIRMEN_TEXTE}, und das ist eine
|
|
765
|
+
* Doppelung** -- gehalten wird sie von einer Pruefung in `check:kontext`
|
|
766
|
+
* („der `hoch`-Rat geht an genau die Dateien, die `kontext hoch` wirklich
|
|
767
|
+
* traegt"). Die konnte vor diesem Umbau gar nicht rot werden, weil der Rat
|
|
768
|
+
* SELBST aus {@link FIRMEN_TEXTE} entstand; jetzt sind es zwei Tabellen, und
|
|
769
|
+
* ihr Auseinanderlaufen ist messbar.
|
|
770
|
+
*/
|
|
771
|
+
const RAT_ART_JE_DATEI = {
|
|
772
|
+
"CLAUDE.md": "nicht-hochschickbar",
|
|
773
|
+
"kontext/kurzprofil.md": "hochschickbar",
|
|
774
|
+
"kontext/firma.md": "hochschickbar",
|
|
775
|
+
"kontext/marke.md": "hochschickbar",
|
|
776
|
+
"kontext/systeme.md": "hochschickbar",
|
|
777
|
+
"kontext/sicherheit.md": "hochschickbar",
|
|
778
|
+
};
|
|
779
|
+
/**
|
|
780
|
+
* Der Wortlaut je Art und Rolle.
|
|
781
|
+
*
|
|
782
|
+
* ⚠️ ECHTE UMLAUTE -- das liest ein Kunde. Die ASCII-Umschrift dieser Datei
|
|
783
|
+
* gilt nur fuer Kommentare.
|
|
784
|
+
*
|
|
785
|
+
* 🔑 `wer` ist die fertige Anrede (` an Lena` oder ` an euren Firmen-Admin`),
|
|
786
|
+
* damit der Rueckfall auf den Sammelbegriff an EINER Stelle steht und nicht in
|
|
787
|
+
* jedem Zweig neu. Ruling T7-1: nie `null` im Klartext.
|
|
788
|
+
*/
|
|
789
|
+
const RAT_TEXT = {
|
|
790
|
+
hochschickbar: (rolle, wer) => rolle === "admin"
|
|
791
|
+
? " Deine Fassung ist die neuere? Dann schick sie hoch: kimal3 kontext hoch"
|
|
792
|
+
: " Deine Fassung bleibt stehen — hochschicken darf nur der Firmen-Admin.\n" +
|
|
793
|
+
` Gib deine Ergänzung${wer} weiter; von dort geht sie in der App unter\n` +
|
|
794
|
+
" Firma → Kontext oder mit `kimal3 kontext hoch` an alle.",
|
|
795
|
+
/*
|
|
796
|
+
🔴 **Auch dieser Zweig kennt die ROLLE -- Punkt A-5, 2026-08-26.** Er tat
|
|
797
|
+
es bis dahin nicht und riet jedem dasselbe: „Aendere sie dort", also im
|
|
798
|
+
Formular unter Firma → Kontext. Ein MITGLIED kann das nicht. `kimal3
|
|
799
|
+
kontext hoch` weist es ab, und den Firmenkontext der Firma darf es in der
|
|
800
|
+
App nicht schreiben. *Ein Rat, der die Lage nicht aendern kann, ist keiner*
|
|
801
|
+
-- er schickt einen Menschen an eine Tuer, vor der er keinen Schluessel
|
|
802
|
+
hat, und laesst ihn den Fehler bei sich suchen.
|
|
803
|
+
|
|
804
|
+
🔑 Was das Mitglied stattdessen liest: WAS es weitergeben soll (die drei
|
|
805
|
+
Saetze aus `kontext/kurzprofil.md`) und AN WEN -- genau die Form, die der
|
|
806
|
+
Zweig fuer die fuenf `kontext/`-Dateien oben schon hat.
|
|
807
|
+
*/
|
|
808
|
+
"nicht-hochschickbar": (rolle, wer) => rolle === "admin"
|
|
809
|
+
? " Die `CLAUDE.md` kann `kimal3 kontext hoch` nicht mitnehmen — der Befehl schickt nur\n" +
|
|
810
|
+
" die fünf Dateien aus `kontext/`. Die drei Sätze in dieser Datei kommen aus\n" +
|
|
811
|
+
" `kontext/kurzprofil.md`, der Firmenname aus der App: Ändere sie dort, dann holt\n" +
|
|
812
|
+
" der nächste `kimal3 kontext runter` sie hierher.\n" +
|
|
813
|
+
" Alles Übrige darin ist unsere Vorlage — dafür gibt es keinen Weg zurück."
|
|
814
|
+
: " Die `CLAUDE.md` kann `kimal3 kontext hoch` nicht mitnehmen — der Befehl schickt nur\n" +
|
|
815
|
+
" die fünf Dateien aus `kontext/`. Deine Änderung bleibt stehen.\n" +
|
|
816
|
+
" Die drei Sätze in dieser Datei kommen aus `kontext/kurzprofil.md`, und die ändert\n" +
|
|
817
|
+
` nur der Firmen-Admin. Gib deinen Wunsch${wer} weiter; von dort geht\n` +
|
|
818
|
+
" `kontext/kurzprofil.md` in der App unter Firma → Kontext oder mit\n" +
|
|
819
|
+
" `kimal3 kontext hoch` an alle.\n" +
|
|
820
|
+
" Alles Übrige darin ist unsere Vorlage — dafür gibt es keinen Weg zurück.",
|
|
821
|
+
};
|
|
567
822
|
/**
|
|
568
823
|
* Was ein Mensch lesen soll, wenn `kimal3 kontext runter` Dateien in Ruhe
|
|
569
824
|
* laesst, weil er sie lokal geaendert hat -- je nach Rolle und je nach DATEI.
|
|
@@ -587,30 +842,29 @@ export function arbeitsplatzAus(kandidaten) {
|
|
|
587
842
|
* Verhalten eines Befehls wohnte im Befehl selbst, wo keine Vorlagen-Wache je
|
|
588
843
|
* hinsieht.* `check:kontext` prueft jetzt genau diese Zuordnung.
|
|
589
844
|
*
|
|
590
|
-
*
|
|
591
|
-
*
|
|
845
|
+
* 🔴 **PUNKT A-7 (2026-08-26): DER RAT WIRD ERZEUGT, NICHT AUFGEZAEHLT.** Diese
|
|
846
|
+
* Funktion hatte zwei `if`s -- eines fuer „irgendetwas aus
|
|
847
|
+
* {@link FIRMEN_TEXTE}", eines fuer den woertlichen Namen `"CLAUDE.md"`. Eine
|
|
848
|
+
* siebte verwaltete Datei waere durch beide gefallen und haette schweigend gar
|
|
849
|
+
* keinen Rat bekommen. Jetzt laeuft die Schleife ueber
|
|
850
|
+
* {@link VERWALTETE_DATEIEN} selbst und schlaegt die Art in
|
|
851
|
+
* {@link RAT_ART_JE_DATEI} nach -- eine Datei ohne Zuordnung uebersetzt nicht.
|
|
852
|
+
*
|
|
853
|
+
* ⚠️ **Eine ART, ein Satz -- auch wenn drei ihrer Dateien betroffen sind.** Das
|
|
854
|
+
* war vorher so (ein `if` feuerte einmal) und bleibt so: Der Rat spricht ueber
|
|
855
|
+
* den Weg, nicht ueber die einzelne Datei; dreimal derselbe Absatz waere
|
|
856
|
+
* Laerm.
|
|
592
857
|
*/
|
|
593
858
|
export function ratNachUnberuehrt(unberuehrt, rolle, adminName) {
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
else {
|
|
601
|
-
const wer = adminName ? ` an ${adminName}` : " an euren Firmen-Admin";
|
|
602
|
-
zeilen.push(" Deine Fassung bleibt stehen — hochschicken darf nur der Firmen-Admin.\n" +
|
|
603
|
-
` Gib deine Ergänzung${wer} weiter; von dort geht sie in der App unter\n` +
|
|
604
|
-
" Firma → Kontext oder mit `kimal3 kontext hoch` an alle.");
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
// Und fuer die eine Datei, die er nicht tragen kann.
|
|
608
|
-
if (unberuehrt.includes("CLAUDE.md")) {
|
|
609
|
-
zeilen.push(" Die `CLAUDE.md` kann `kimal3 kontext hoch` nicht mitnehmen — der Befehl schickt nur\n" +
|
|
610
|
-
" die fünf Dateien aus `kontext/`. Die drei Sätze in dieser Datei kommen aus\n" +
|
|
611
|
-
" `kontext/kurzprofil.md`, der Firmenname aus der App: Ändere sie dort, dann holt\n" +
|
|
612
|
-
" der nächste `kimal3 kontext runter` sie hierher.\n" +
|
|
613
|
-
" Alles Übrige darin ist unsere Vorlage — dafür gibt es keinen Weg zurück.");
|
|
859
|
+
// Ruling T7-1: kein `null` im Klartext, sondern der Sammelbegriff.
|
|
860
|
+
const wer = adminName ? ` an ${adminName}` : " an euren Firmen-Admin";
|
|
861
|
+
const betroffeneArten = new Set();
|
|
862
|
+
for (const pfad of VERWALTETE_DATEIEN) {
|
|
863
|
+
if (unberuehrt.includes(pfad))
|
|
864
|
+
betroffeneArten.add(RAT_ART_JE_DATEI[pfad]);
|
|
614
865
|
}
|
|
615
|
-
|
|
866
|
+
// 🔑 Die Reihenfolge kommt aus RAT_REIHENFOLGE, NICHT aus der Einfuegereihen-
|
|
867
|
+
// folge des `Set` -- sonst haenge die Ausgabe beim Kunden davon ab, in
|
|
868
|
+
// welcher Reihenfolge VERWALTETE_DATEIEN zufaellig steht.
|
|
869
|
+
return RAT_REIHENFOLGE.filter((art) => betroffeneArten.has(art)).map((art) => RAT_TEXT[art](rolle, wer));
|
|
616
870
|
}
|
package/dist/nachricht.js
CHANGED
|
@@ -62,6 +62,21 @@ function teile(v) {
|
|
|
62
62
|
}
|
|
63
63
|
return zahlen;
|
|
64
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Laesst sich das ueberhaupt als Versionsstand lesen?
|
|
67
|
+
*
|
|
68
|
+
* 🔴 **Gebraucht, weil `istAelter` unten bei Muell `false` sagt** -- und
|
|
69
|
+
* `false` heisst dort „nicht aelter", was ein Aufrufer als „neu genug" liest.
|
|
70
|
+
* Fuer den Update-Hinweis ist das richtig („im Zweifel schweigen"), fuer eine
|
|
71
|
+
* Faehigkeits-Frage (`cli/src/faehigkeiten.ts`) ist es genau verkehrt: Dort
|
|
72
|
+
* wuerde ein unlesbarer Kopf zur Auskunft „die Fassung kann alles".
|
|
73
|
+
*
|
|
74
|
+
* *Dieselbe Antwort `false` bedeutet an zwei Stellen Verschiedenes -- deshalb
|
|
75
|
+
* muss die Frage „ist das ueberhaupt eine Nummer" getrennt gestellt werden.*
|
|
76
|
+
*/
|
|
77
|
+
export function istVersionsstand(v) {
|
|
78
|
+
return teile(v) !== null;
|
|
79
|
+
}
|
|
65
80
|
/**
|
|
66
81
|
* Ist `a` aelter als `b`? Zahl fuer Zahl, nicht als Text.
|
|
67
82
|
*
|
|
@@ -100,9 +115,73 @@ export function heuteAus(d) {
|
|
|
100
115
|
return new Intl.DateTimeFormat("sv-SE", { timeZone: "Europe/Berlin" }).format(d);
|
|
101
116
|
}
|
|
102
117
|
/**
|
|
103
|
-
* Die
|
|
118
|
+
* Die Kennung eines FIRMENKONTEXT-Hinweises faengt hiermit an, und dahinter
|
|
119
|
+
* steht der Server-Stand, den er meint (`kontext-2026-08-26T09:00:00Z`).
|
|
120
|
+
*
|
|
121
|
+
* 🔑 Sie steht als eigener Name da, weil sie von ZWEI Seiten gebraucht wird:
|
|
122
|
+
* `firmenHinweisAus` baut die Kennung, `hinweisErledigt` liest sie wieder
|
|
123
|
+
* auseinander. Zwei getippte `"kontext-"` waeren zwei Wahrheiten -- und die
|
|
124
|
+
* zweite verrottete lautlos, weil ein Hinweis, der nicht mehr erkannt wird,
|
|
125
|
+
* einfach wieder erscheint, statt einen Fehler zu machen.
|
|
126
|
+
*/
|
|
127
|
+
export const KONTEXT_HINWEIS_PRAEFIX = "kontext-";
|
|
128
|
+
/**
|
|
129
|
+
* Ist der ANLASS dieses Hinweises inzwischen erledigt?
|
|
130
|
+
*
|
|
131
|
+
* 🔴 DER FALL, DER DIESE FUNKTION RECHTFERTIGT (offener Punkt A-4, gemessen
|
|
132
|
+
* am 2026-08-26): Direkt nach `kimal3 kontext runter` stand da
|
|
133
|
+
*
|
|
134
|
+
* Dein Firmenkontext ist aktuell.
|
|
135
|
+
* Nordwind hat den Firmenkontext aktualisiert. kimal3 kontext runter
|
|
136
|
+
*
|
|
137
|
+
* -- die zweite Zeile riet zu genau dem Befehl, der gerade gelaufen war. Kein
|
|
138
|
+
* Rechenfehler: Die CLI schickt ihren Stand VOR dem Herunterladen mit, der
|
|
139
|
+
* Server vergleicht ihn mit seinem eigenen und haengt den Hinweis an. Bis der
|
|
140
|
+
* Hinweis ausgegeben wird, hat der Befehl den lokalen Stand laengst
|
|
141
|
+
* nachgezogen. *Die Meldung kam einen Aufruf zu spaet.*
|
|
142
|
+
*
|
|
143
|
+
* Die Regel dagegen: **Ein Hinweis, dessen Stand der lokale Merkzettel JETZT
|
|
144
|
+
* traegt, ist erledigt und wird nicht ausgegeben.**
|
|
145
|
+
*
|
|
146
|
+
* ⚠️ NUR Kontext-Hinweise. Die globale Nachricht aus der Datenbank traegt eine
|
|
147
|
+
* UUID als Kennung und darf durch diese Regel NIE verstummen -- sie hat mit
|
|
148
|
+
* dem Firmenkontext nichts zu tun, und ein Kanal, der sich versehentlich selbst
|
|
149
|
+
* stilllegt, faellt niemandem auf.
|
|
150
|
+
*
|
|
151
|
+
* ⚠️ `null` und leer heissen "wir wissen es nicht", nicht "erledigt": Wer den
|
|
152
|
+
* lokalen Stand nicht kennt, darf keinen Hinweis unterdruecken. Im Zweifel
|
|
153
|
+
* zeigen -- eine Zeile zu viel ist harmlos, eine verschluckte Zeile nicht.
|
|
154
|
+
*/
|
|
155
|
+
export function hinweisErledigt(hinweisId, lokalerStandJetzt) {
|
|
156
|
+
if (!hinweisId)
|
|
157
|
+
return false;
|
|
158
|
+
if (!hinweisId.startsWith(KONTEXT_HINWEIS_PRAEFIX))
|
|
159
|
+
return false;
|
|
160
|
+
const gemeinterStand = hinweisId.slice(KONTEXT_HINWEIS_PRAEFIX.length);
|
|
161
|
+
if (gemeinterStand === "")
|
|
162
|
+
return false;
|
|
163
|
+
if (lokalerStandJetzt === null || lokalerStandJetzt === "")
|
|
164
|
+
return false;
|
|
165
|
+
return gemeinterStand === lokalerStandJetzt;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Die ganze Entscheidung, als Funktion von fuenf Werten.
|
|
169
|
+
*
|
|
170
|
+
* 🔴 `lokalerKontextStandJetzt` IST ABSICHTLICH PFLICHT, nicht optional
|
|
171
|
+
* (A-4). Am 2026-08-26 hat dieses Projekt gemessen, was ein optionales
|
|
172
|
+
* Argument anrichtet: `lageFuerDatei` konnte erkennen, dass sich unsere
|
|
173
|
+
* Vorlage geaendert hat -- die Aufrufstelle uebergab den noetigen Wert nie,
|
|
174
|
+
* und weil das Argument optional war, fehlte keine Zeile, meckerte kein
|
|
175
|
+
* Compiler und wurde kein Waechter rot. Die Rechnung war gebaut, geprueft,
|
|
176
|
+
* dokumentiert und in der Wirklichkeit tot. *Ein Pflicht-Argument ist die
|
|
177
|
+
* einzige Verdrahtung, die der Compiler fuer einen mitdenkt.*
|
|
178
|
+
*
|
|
179
|
+
* 🔑 UND ER MUSS FRISCH SEIN. Der Wert, den die CLI im Kopf mitschickt, wird
|
|
180
|
+
* VOR dem Netzaufruf gelesen; dieser hier gehoert an das ENDE des Befehls.
|
|
181
|
+
* Wer denselben Wert zweimal benutzt, baut den Fehler wieder ein, gegen den
|
|
182
|
+
* `hinweisErledigt` geschrieben ist.
|
|
104
183
|
*/
|
|
105
|
-
export function sollZeigen(h, eigeneVersion, gesehen, heute) {
|
|
184
|
+
export function sollZeigen(h, eigeneVersion, gesehen, heute, lokalerKontextStandJetzt) {
|
|
106
185
|
if (!h.id)
|
|
107
186
|
return false;
|
|
108
187
|
if (!h.text || h.text.trim() === "")
|
|
@@ -110,6 +189,11 @@ export function sollZeigen(h, eigeneVersion, gesehen, heute) {
|
|
|
110
189
|
// Leeres Feld = alle sehen es. Sonst nur, wer aelter ist als die Grenze.
|
|
111
190
|
if (h.gilt_unter_version && !istAelter(eigeneVersion, h.gilt_unter_version))
|
|
112
191
|
return false;
|
|
192
|
+
// Der Anlass ist erledigt -- der Befehl, zu dem geraten wird, ist gerade
|
|
193
|
+
// gelaufen. Bewusst VOR der Tagessperre: Ein Hinweis, der gar nicht mehr
|
|
194
|
+
// gilt, soll auch nicht den einen Platz des Tages verbrauchen.
|
|
195
|
+
if (hinweisErledigt(h.id, lokalerKontextStandJetzt))
|
|
196
|
+
return false;
|
|
113
197
|
// Hoechstens einmal am Tag -- auch bei zwanzig Befehlen.
|
|
114
198
|
if (gesehen[h.id] === heute)
|
|
115
199
|
return false;
|
|
@@ -242,7 +326,7 @@ export function firmenHinweisAus(lokalerStand, serverStand, firmenName) {
|
|
|
242
326
|
if (lokalerStand === serverStand)
|
|
243
327
|
return null;
|
|
244
328
|
return {
|
|
245
|
-
id:
|
|
329
|
+
id: `${KONTEXT_HINWEIS_PRAEFIX}${serverStand}`,
|
|
246
330
|
text: `${firmenName} hat den Firmenkontext aktualisiert. kimal3 kontext runter`,
|
|
247
331
|
gilt_unter_version: null,
|
|
248
332
|
};
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -43,6 +43,21 @@ Das ist meist richtig, aber nicht immer schön (`s.mueller@…` wird zu `werkban
|
|
|
43
43
|
**Frag den Menschen nach seinem Vornamen und gib ihn mit**, statt es dem Server zu überlassen —
|
|
44
44
|
er heißt selten so, wie seine Adresse aussieht.
|
|
45
45
|
|
|
46
|
+
🔴 **Gehört der Mensch zu MEHREREN Firmen, fragen beide Befehle nach — mit `--firma`.**
|
|
47
|
+
Sie legen dann nichts an, sondern nennen die Firmen als fertige Zeilen zum Kopieren. Das ist
|
|
48
|
+
kein Fehler, sondern die Rückfrage: Der Ordner trägt den Namen der Firma, und raten darf der
|
|
49
|
+
Befehl ihn nicht.
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
kimal3 arbeitsplatz neu sabine --firma "Nordwind Handel GmbH"
|
|
53
|
+
kimal3 werkbank neu sabine --firma "Nordwind Handel GmbH"
|
|
54
|
+
kimal3 werkbank neu sabine --firma-id "…" # falls zwei Firmen GLEICH heissen
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
⚠️ Der Rückgabewert ist dann `1` und die Absage steht auf der Fehlerausgabe. **Nimm eine der
|
|
58
|
+
angebotenen Zeilen, statt es unverändert zu wiederholen** — ohne `--firma` kommt dieselbe
|
|
59
|
+
Rückfrage noch einmal.
|
|
60
|
+
|
|
46
61
|
⚠️ **`werkbank neu` verlangt ein eigenes Pro-Konto.** Die Route prüft den Plan **pro Person**
|
|
47
62
|
(`konto_plan`), nicht über die Firmen-Mitgliedschaft. Ein Kollege ohne eigenes Pro bekommt
|
|
48
63
|
Rückgabewert `4` — dann **nicht** wiederholen und nicht raten, sondern genau das sagen: Sein
|
|
@@ -106,10 +121,19 @@ Stelle.
|
|
|
106
121
|
Anker, Frage, Hinweis. Sind alle beantwortet, sagt er das in einem Satz, und du bist fertig.
|
|
107
122
|
Der Befehl liest nur; er braucht weder Netz noch Anmeldung.
|
|
108
123
|
2. **Die Fragen EINZELN stellen.** Eine Frage, die Antwort abwarten, dann die nächste. Keine
|
|
109
|
-
Liste
|
|
110
|
-
|
|
124
|
+
lange Liste und kein Fragebogen am Stück — es sind Fragen über die Firma eines Menschen, und
|
|
125
|
+
die beantwortet er nicht in einem Rutsch.
|
|
111
126
|
3. **Die Antwort in die genannte Datei schreiben** — unter ihre `## `-Überschrift, über der der
|
|
112
127
|
Anker steht. Die Hinweiszeilen mit `>` gehören uns; **lass sie stehen und schreib darunter.**
|
|
128
|
+
|
|
129
|
+
🔴 **Die Pfade zählen ab dem Ordner, den `kontext fragen` als `Arbeitsplatz:` nennt — nicht
|
|
130
|
+
ab deinem Arbeitsverzeichnis.** Der Normalfall ist, dass beides auseinanderfällt:
|
|
131
|
+
`kimal3 arbeitsplatz neu` rät ausdrücklich, in die **Werkbank** zu wechseln und dort Claude
|
|
132
|
+
zu starten; die fünf Dateien liegen dann eine Ebene höher. **Setz jeden Pfad an den
|
|
133
|
+
genannten Arbeitsplatz an, bevor du schreibst.**
|
|
134
|
+
⚠️ Wer das übergeht, legt eine **neue** Datei am falschen Ort an. `kimal3 kontext hoch` liest
|
|
135
|
+
weiter die echten Dateien und schickt leere Antworten hoch — *beide Seiten melden Erfolg, und
|
|
136
|
+
die Arbeit des Menschen ist trotzdem weg.*
|
|
113
137
|
4. **`kimal3 kontext hoch`** — schickt alle fünf Dateien an die Firma. **Nur der Firmen-Admin
|
|
114
138
|
darf das.**
|
|
115
139
|
|
|
@@ -124,12 +148,24 @@ darüberkopiert wurde —, bricht `kontext hoch` ab und schickt gar nichts, auch
|
|
|
124
148
|
nicht** (Rückgabewert `1`). Das ist **kein** „noch einmal versuchen": Sag dem Menschen, welche
|
|
125
149
|
Datei gemeint ist, und hol sie mit `kimal3 kontext runter` zurück.
|
|
126
150
|
|
|
127
|
-
🔴 **
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
151
|
+
🔴 **Bei `kontext hoch` sagt die Zahl `1` allein GAR NICHTS — die Meldung sagt es. LIES SIE.**
|
|
152
|
+
|
|
153
|
+
⚠️ **Hier stand bis zum 2026-08-28: „Rückgabewert `1` heißt ‚du bist kein Admin dieser
|
|
154
|
+
Firma'".** Das war falsch und gefährlich. `kontext hoch` hat **sechs** verschiedene Ausgänge
|
|
155
|
+
auf dieser einen Zahl (`cli/src/befehle/kontext-hoch.ts`): unbekannte Option · kein
|
|
156
|
+
Arbeitsplatz gefunden · eine Datei nicht lesbar · eine Datei ohne Fragen · „jemand anderes hat
|
|
157
|
+
geändert" (Ausweg `--ueberschreiben`) · mehrere Firmen (Ausweg `--firma`) — und die Rolle.
|
|
158
|
+
|
|
159
|
+
🔴 **Der teuerste davon steht in `kontext-hoch.ts` (Merkzettel-Zweig) und ist ein ERFOLG:** *„Die Firma hat
|
|
160
|
+
deine Änderungen gespeichert — nur der lokale Merkzettel ließ sich nicht schreiben."* Auch das
|
|
161
|
+
gibt `1` zurück. Wer die Zahl als „kein Admin" deutet, sagt einem Menschen, der gerade alle
|
|
162
|
+
Fragen beantwortet und **erfolgreich hochgeschickt** hat, er solle sich an seinen Admin wenden.
|
|
163
|
+
*Ein Erfolg, als Absage vorgelesen — und er tippt danach alles noch einmal.*
|
|
164
|
+
|
|
165
|
+
**Also:** Nimm den Satz, den der Befehl geschrieben hat, und sag dem Menschen, was er bedeutet.
|
|
166
|
+
Geht es wirklich um die Rolle, nenne den Admin — lief vorher `kontext runter`, kennt dessen
|
|
167
|
+
Ausgabe den Namen bereits; sonst frag, wer in der Firma Admin ist. Ein zweiter Versuch hilft nur
|
|
168
|
+
dort, wo die Meldung einen Ausweg nennt (`--ueberschreiben`, `--firma`), sonst nie.
|
|
133
169
|
|
|
134
170
|
⚠️ **Beide Befehle brauchen wie `werkbank neu` ein eigenes Pro-Konto** — ohne das kommt
|
|
135
171
|
Rückgabewert `4`, dann **nicht wiederholen**.
|