kimal3 0.2.8 → 0.2.10
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/arbeitsplatz-dateien.js +43 -15
- package/dist/befehle/arbeitsplatz.js +2 -1
- package/dist/befehle/kontext-fragen.js +10 -2
- package/dist/befehle/kontext-gemeinsam.js +2 -3
- package/dist/befehle/kontext-runter.js +2 -2
- package/dist/befehle/werkbank.js +26 -7
- package/dist/firmen-liste.js +34 -0
- package/dist/kimal3.js +38 -4
- package/dist/kontext-stand.js +4 -0
- package/dist/wache-schalter.js +40 -5
- package/package.json +1 -1
- package/skill/SKILL.md +20 -1
- package/skill/commands/k3feierabend.md +97 -43
- package/skill/commands/k3kontext.md +3 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join, resolve } from "node:path";
|
|
3
|
-
import { ruf } from "./api.js";
|
|
3
|
+
import { feld, ruf } from "./api.js";
|
|
4
|
+
import { angeboteneFirmen, firmaAusOrdner } from "./firmen-liste.js";
|
|
4
5
|
/*
|
|
5
6
|
🔴 **Ja, hierher -- und nicht in eine zweite eigene Absage** (Punkt A-3,
|
|
6
7
|
2026-08-26). `absage` ist die Ausgabe, die `kimal3 kontext runter` und
|
|
@@ -75,26 +76,42 @@ export function firmenSuche(wunsch) {
|
|
|
75
76
|
* zweite Tür, die man einzeln absichern und einzeln nachmessen müsste — für
|
|
76
77
|
* exakt denselben Inhalt. Der Ausschnitt entsteht hier auf dem Rechner.
|
|
77
78
|
*
|
|
78
|
-
* 🔴 **
|
|
79
|
+
* 🔴 **Alle drei Parameter sind PFLICHT** (Punkt A-3, 2026-08-26). `wunsch` könnte
|
|
79
80
|
* bequem entfallen, wenn niemand eine Firma nennt -- und genau so bleibt eine
|
|
80
81
|
* gebaute Rechnung an der Aufrufstelle tot, ohne dass ein Compiler oder ein
|
|
81
82
|
* Wächter etwas merkt (dieselbe Falle wie bei `lageFuerDatei`, Punkt A-1).
|
|
82
83
|
* `befehl` nennt den Befehl, den die 409-Absage zum Kopieren anbietet -- stünde
|
|
83
84
|
* dort fest `kontext runter`, bekäme ein Mensch bei `werkbank neu` einen Rat,
|
|
84
|
-
* der seine Werkbank nicht anlegt.
|
|
85
|
+
* der seine Werkbank nicht anlegt. `ordner` ist `null` bei `arbeitsplatz neu`
|
|
86
|
+
* (dort entsteht der Ordner erst) und die Firma des Ordners bei `werkbank neu`.
|
|
87
|
+
*
|
|
88
|
+
* 🔑 **Die Firma des Ordners wird nur benutzt, wenn der Server FRAGT** (A2-6,
|
|
89
|
+
* Entscheidung Dennis 25.09.): Gehört der Mensch zu mehreren Firmen
|
|
90
|
+
* (`mehrere-firmen`) und hat er selbst keine genannt, versucht der Befehl es
|
|
91
|
+
* EIN zweites Mal mit der Firma aus dem Ordner (`firmaAusOrdner`). Die Lagen
|
|
92
|
+
* und warum genau so: docs/superpowers/specs/2026-09-25-werkbank-nimmt-firma-lagen.md.
|
|
93
|
+
* - Hat er selbst `--firma`/`--firma-id` getippt, gilt seine Angabe -- auch
|
|
94
|
+
* eine falsche wird nie still ersetzt (Lage L7b).
|
|
95
|
+
* - Scheitert die zweite Anfrage mit `409`, sieht er die ERSTE Rückfrage, nicht
|
|
96
|
+
* eine über einen Namen, den er nie getippt hat (L11).
|
|
85
97
|
*/
|
|
86
|
-
export async function vorlageHolen(befehl, wunsch) {
|
|
87
|
-
const antwort = await
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
+
export async function vorlageHolen(befehl, wunsch, ordner) {
|
|
99
|
+
const antwort = await holeVorlage(wunsch);
|
|
100
|
+
if (antwort.status === 200)
|
|
101
|
+
return lesbar(antwort.koerper, false);
|
|
102
|
+
const selbstGenannt = wunsch.firma !== undefined || wunsch.firmaId !== undefined;
|
|
103
|
+
const wahl = antwort.status === 409 && ordner !== null && !selbstGenannt &&
|
|
104
|
+
feld(antwort.koerper, "grund") === "mehrere-firmen"
|
|
105
|
+
? firmaAusOrdner(ordner, angeboteneFirmen(antwort.koerper))
|
|
106
|
+
: null;
|
|
107
|
+
if (wahl !== null) {
|
|
108
|
+
const zweite = await holeVorlage(wahl);
|
|
109
|
+
if (zweite.status === 200)
|
|
110
|
+
return lesbar(zweite.koerper, true);
|
|
111
|
+
// Netz, Ausweis, Pro: deren eigene Meldung. Nur eine zweite Rückfrage wird
|
|
112
|
+
// durch die erste ersetzt (L11).
|
|
113
|
+
if (zweite.status !== 409)
|
|
114
|
+
return { ok: false, wert: absage(zweite, befehl) };
|
|
98
115
|
}
|
|
99
116
|
/*
|
|
100
117
|
🔴 **Hier standen dieselben vier Zweige noch einmal abgetippt** (402 vor
|
|
@@ -109,6 +126,17 @@ export async function vorlageHolen(befehl, wunsch) {
|
|
|
109
126
|
*/
|
|
110
127
|
return { ok: false, wert: absage(antwort, befehl) };
|
|
111
128
|
}
|
|
129
|
+
function holeVorlage(wunsch) {
|
|
130
|
+
return ruf(`/api/cli/arbeitsplatz${firmenSuche(wunsch)}`, { methode: "GET", mitAusweis: true });
|
|
131
|
+
}
|
|
132
|
+
function lesbar(koerper, uebernommen) {
|
|
133
|
+
const daten = alsVorlageAntwort(koerper);
|
|
134
|
+
if (daten === null) {
|
|
135
|
+
console.error("Die Antwort war nicht lesbar. Bitte gleich noch einmal.");
|
|
136
|
+
return { ok: false, wert: 3 };
|
|
137
|
+
}
|
|
138
|
+
return { ok: true, daten, uebernommen };
|
|
139
|
+
}
|
|
112
140
|
/** Prueft die Antwort-Form, ohne `any` -- eine falsche Form ist unlesbar, keine Ausnahme. */
|
|
113
141
|
function alsVorlageAntwort(koerper) {
|
|
114
142
|
if (!koerper || typeof koerper !== "object")
|
|
@@ -221,7 +221,8 @@ export async function arbeitsplatzNeu(argv) {
|
|
|
221
221
|
const befehlsname = nameArg === undefined
|
|
222
222
|
? "arbeitsplatz neu"
|
|
223
223
|
: `arbeitsplatz neu ${alsWort(nameArg)}`;
|
|
224
|
-
|
|
224
|
+
// `null`: Der Ordner entsteht hier erst -- es gibt keine Firma, die man aus ihm lesen koennte.
|
|
225
|
+
const holen = await vorlageHolen(befehlsname, wunsch, null);
|
|
225
226
|
if (!holen.ok)
|
|
226
227
|
return holen.wert;
|
|
227
228
|
const daten = holen.daten;
|
|
@@ -141,8 +141,16 @@ export function kontextFragen(argv) {
|
|
|
141
141
|
liest ein Mensch „fertig" und die App widerspricht ihm morgen.
|
|
142
142
|
*/
|
|
143
143
|
console.log(" Gezählt ist, was in kontext/ steht. Nennt die App unter Firma → Kontext");
|
|
144
|
-
console.log(" eine höhere Zahl, fehlt in einer Datei eine Frage
|
|
145
|
-
|
|
144
|
+
console.log(" eine höhere Zahl, fehlt in einer Datei eine Frage oder die Zeile <!-- k3:… --> darüber.");
|
|
145
|
+
// 🔴 Hier stand „`kimal3 kontext runter` holt sie zurück" -- stimmt nur fuer
|
|
146
|
+
// eine FEHLENDE Datei. Eine selbst bearbeitete fasst `runter` nicht an
|
|
147
|
+
// (`lageFuerDatei` -> `lokal-geaendert`), Schlusspruefung 25.09.
|
|
148
|
+
// Und er NENNT die Datei nicht -- dieser Befehl weiss nicht, welche es ist
|
|
149
|
+
// (er zaehlt nur, was da ist). Deshalb der Weg, sie zu finden (Review 25.09.).
|
|
150
|
+
console.log(" Welche Datei: die, deren Überschriften nicht zu denen in der App passen.");
|
|
151
|
+
console.log(" Benenn sie um (etwa firma.md → firma-alt.md), dann holt `kimal3 kontext runter`");
|
|
152
|
+
console.log(" die Fassung der Firma frisch. Antworten, die du noch nicht hochgeschickt hast,");
|
|
153
|
+
console.log(" stehen danach nur in der umbenannten Datei — kopier sie zurück.");
|
|
146
154
|
return 0;
|
|
147
155
|
}
|
|
148
156
|
console.log(`${offen} von ${gesamt} Fragen über deine Firma sind noch offen.\n`);
|
|
@@ -3,6 +3,7 @@ import { alsWort } from "../argumente.js";
|
|
|
3
3
|
import { schlussFehler } from "../fehler.js";
|
|
4
4
|
import { BASIS_URL } from "../anmeldung.js";
|
|
5
5
|
import { findeArbeitsplatz } from "../kontext-dateien.js";
|
|
6
|
+
import { angeboteneFirmen } from "../firmen-liste.js";
|
|
6
7
|
/**
|
|
7
8
|
* Was `kontext runter` (`kontext-runter.ts`) und `kontext hoch`
|
|
8
9
|
* (`kontext-hoch.ts`) TEILEN -- die `--firma`/`--firma-id`-Optionen und die
|
|
@@ -127,9 +128,7 @@ export function absage(antwort, befehl) {
|
|
|
127
128
|
return 1;
|
|
128
129
|
}
|
|
129
130
|
const koerper = antwort.koerper;
|
|
130
|
-
const namen =
|
|
131
|
-
? koerper.firmen.filter((x) => typeof x === "string")
|
|
132
|
-
: [];
|
|
131
|
+
const namen = angeboteneFirmen(koerper);
|
|
133
132
|
console.error(meldung);
|
|
134
133
|
const auswahl = Array.isArray(koerper.auswahl)
|
|
135
134
|
? koerper.auswahl.filter((x) => !!x &&
|
|
@@ -239,8 +239,8 @@ export async function kontextRunter(argv) {
|
|
|
239
239
|
// und dann sucht er in der App eine Aenderung, die es dort nicht gibt.
|
|
240
240
|
if (vorlageErneuert.length > 0) {
|
|
241
241
|
console.log(` Davon aus unserer verbesserten Vorlage: ${vorlageErneuert.join(", ")}`);
|
|
242
|
-
console.log(" Diese Dateien
|
|
243
|
-
" von dir verloren gegangen. Hättest du
|
|
242
|
+
console.log(" Diese Dateien waren seit dem letzten Abgleich mit der Firma unverändert — es ist nichts\n" +
|
|
243
|
+
" von dir verloren gegangen. Hättest du seitdem etwas geändert, hätte ich vorher gesichert.");
|
|
244
244
|
}
|
|
245
245
|
// §8: Ein Fehlerfall darf nie denselben Namen tragen wie ein Erfolgsfall --
|
|
246
246
|
// "nichts geschrieben" heisst hier DREI verschiedene Dinge, und die Ausgabe
|
package/dist/befehle/werkbank.js
CHANGED
|
@@ -66,7 +66,9 @@ const HILFE = `
|
|
|
66
66
|
wird "werkbank-sabine". Ohne Angabe steht dort der Name,
|
|
67
67
|
den der Server aus deiner Anmelde-Adresse gebildet hat.
|
|
68
68
|
|
|
69
|
-
--firma "Name"
|
|
69
|
+
--firma "Name" Nur noetig, wenn du zu mehreren Firmen gehoerst UND dieser
|
|
70
|
+
Ordner seine Firma nicht eindeutig nennt -- sonst nehme
|
|
71
|
+
ich die Firma des Ordners und sage dir das.
|
|
70
72
|
Die Absage nennt dir die Namen als fertige Befehle.
|
|
71
73
|
|
|
72
74
|
--firma-id "…" Fuer den Fall, dass zwei deiner Firmen GLEICH heissen.
|
|
@@ -201,7 +203,18 @@ export async function werkbankNeu(argv) {
|
|
|
201
203
|
const befehlsname = nameArg === undefined
|
|
202
204
|
? "werkbank neu"
|
|
203
205
|
: `werkbank neu ${alsWort(nameArg)}`;
|
|
204
|
-
|
|
206
|
+
/*
|
|
207
|
+
🔑 **Die Firma dieses Ordners** -- Kennung aus dem Merkzettel, Name aus der
|
|
208
|
+
Firmen-`CLAUDE.md`. `vorlageHolen` nimmt sie nur, wenn der Server wegen
|
|
209
|
+
mehrerer Firmen fragt (A2-6, 25.09.), und die Wache weiter unten
|
|
210
|
+
(`firmenAbgleich`) vergleicht mit genau diesen beiden Werten.
|
|
211
|
+
*/
|
|
212
|
+
const hierGelesen = leseEineDatei(process.cwd(), FIRMEN_CLAUDE_MD);
|
|
213
|
+
const ordnerFirma = {
|
|
214
|
+
id: leseMerkzettelDatei(process.cwd()).firma_id,
|
|
215
|
+
name: firmennameAusClaudeMd(hierGelesen.ok ? hierGelesen.inhalt : null),
|
|
216
|
+
};
|
|
217
|
+
const holen = await vorlageHolen(befehlsname, wunsch, ordnerFirma);
|
|
205
218
|
if (!holen.ok)
|
|
206
219
|
return holen.wert;
|
|
207
220
|
const daten = holen.daten;
|
|
@@ -365,11 +378,7 @@ export async function werkbankNeu(argv) {
|
|
|
365
378
|
(„ich schicke nichts Halbes hoch“).
|
|
366
379
|
*/
|
|
367
380
|
const inhaltAus = (pfad) => daten.dateien.find((d) => d.pfad === pfad)?.inhalt ?? null;
|
|
368
|
-
const
|
|
369
|
-
const abgleich = firmenAbgleich({
|
|
370
|
-
id: leseMerkzettelDatei(process.cwd()).firma_id,
|
|
371
|
-
name: firmennameAusClaudeMd(hierGelesen.ok ? hierGelesen.inhalt : null),
|
|
372
|
-
}, {
|
|
381
|
+
const abgleich = firmenAbgleich(ordnerFirma, {
|
|
373
382
|
id: leseMerkzettel(inhaltAus(MERKZETTEL_PFAD)).firma_id,
|
|
374
383
|
name: firmennameAusClaudeMd(inhaltAus(FIRMEN_CLAUDE_MD)),
|
|
375
384
|
});
|
|
@@ -461,6 +470,16 @@ export async function werkbankNeu(argv) {
|
|
|
461
470
|
console.log("");
|
|
462
471
|
console.log(" Die Firmenebene ist unberuehrt geblieben.");
|
|
463
472
|
console.log("");
|
|
473
|
+
/*
|
|
474
|
+
Erst NACH dem Anlegen (Lage L2): Vorher koennte noch eine Absage folgen, und
|
|
475
|
+
dann stuende da „uebernommen" fuer etwas, das nie entstanden ist.
|
|
476
|
+
*/
|
|
477
|
+
if (holen.uebernommen) {
|
|
478
|
+
const gewaehlt = firmennameAusClaudeMd(inhaltAus(FIRMEN_CLAUDE_MD));
|
|
479
|
+
console.log(` Die Firma kam aus diesem Ordner${gewaehlt ? `: „${gewaehlt}"` : ""}.`);
|
|
480
|
+
console.log(" Sollte es eine andere sein: Ordner wieder loeschen und mit --firma \"Name\" neu anlegen.");
|
|
481
|
+
console.log("");
|
|
482
|
+
}
|
|
464
483
|
console.log(" Weiter geht's:");
|
|
465
484
|
console.log(` cd ${alsWort(ordnerName)}`);
|
|
466
485
|
console.log(" claude");
|
package/dist/firmen-liste.js
CHANGED
|
@@ -70,3 +70,37 @@ export function firmenZeilen(namen) {
|
|
|
70
70
|
export function firmenIdZeilen(auswahl) {
|
|
71
71
|
return auswahl.map((f, i) => ` kimal3 firma daten --firma-id "${f.id}" # ${f.name} (${i + 1}.)`);
|
|
72
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Die Namen der eigenen Firmen aus einer `409`-Antwort -- was nicht als Text
|
|
75
|
+
* ankommt, faellt weg. EINE Lesart fuer `absage` (kontext-gemeinsam.ts) und
|
|
76
|
+
* `vorlageHolen` -- zwei Kopien liefen irgendwann auseinander (Review 25.09.).
|
|
77
|
+
*/
|
|
78
|
+
export function angeboteneFirmen(koerper) {
|
|
79
|
+
const firmen = koerper?.firmen;
|
|
80
|
+
return Array.isArray(firmen) ? firmen.filter((x) => typeof x === "string") : [];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Welche Firma `werkbank neu` aus dem Ordner uebernimmt, wenn der Server
|
|
84
|
+
* fragt, weil der Mensch zu mehreren Firmen gehoert (Entscheidung Dennis,
|
|
85
|
+
* 25.09. -- A2-6; Lagen: docs/superpowers/specs/2026-09-25-werkbank-nimmt-firma-lagen.md).
|
|
86
|
+
*
|
|
87
|
+
* 🔑 **Die Kennung aus dem Merkzettel zuerst** -- sie ist eindeutig, auch bei
|
|
88
|
+
* zwei gleichnamigen Firmen, und dieselbe, nach der die Firmen-Wache danach
|
|
89
|
+
* vergleicht (`firmenAbgleich`). Ob der Mensch dort Mitglied ist, prueft der
|
|
90
|
+
* Server selbst; sagt er nein, zeigt der Aufrufer die URSPRUENGLICHE Rueckfrage.
|
|
91
|
+
*
|
|
92
|
+
* Ohne Merkzettel (geklonter Ordner, er steht in der `.gitignore`) zaehlt der
|
|
93
|
+
* Name aus der Firmen-`CLAUDE.md` -- aber nur, wenn er GENAU EINMAL unter den
|
|
94
|
+
* angebotenen steht. Kein Ausgleich von Gross/klein, keine aehnlichen Namen:
|
|
95
|
+
* *Wer raten muss, soll fragen.*
|
|
96
|
+
*
|
|
97
|
+
* `null` heisst: nichts Eindeutiges -- dann bleibt es bei der Rueckfrage.
|
|
98
|
+
*/
|
|
99
|
+
export function firmaAusOrdner(ordner, angeboten) {
|
|
100
|
+
if (ordner.id)
|
|
101
|
+
return { firmaId: ordner.id };
|
|
102
|
+
const name = ordner.name;
|
|
103
|
+
if (name && angeboten.filter((n) => n === name).length === 1)
|
|
104
|
+
return { firma: name };
|
|
105
|
+
return null;
|
|
106
|
+
}
|
package/dist/kimal3.js
CHANGED
|
@@ -390,8 +390,34 @@ function endeMitHinweis(code) {
|
|
|
390
390
|
|
|
391
391
|
🔑 DIE NOTBREMSE BLEIBT, und sie ist die einzige Stelle, die noch hart
|
|
392
392
|
beendet: Sie ist `unref`t, haelt die Schleife also nicht am Leben, und
|
|
393
|
-
feuert nur, wenn ein Kanal wirklich haengt.
|
|
394
|
-
|
|
393
|
+
feuert nur, wenn ein Kanal wirklich haengt.
|
|
394
|
+
|
|
395
|
+
🔬 WARUM ZWEI SEKUNDEN -- gemessen statt behauptet (2026-09-10, nach
|
|
396
|
+
Review-Runde 1 am PR #31). Hier stand als Begruendung: "nach zwei
|
|
397
|
+
Sekunden ist die Verbindung von draussen ohnehin zu". Das war die
|
|
398
|
+
einzige ungemessene Zahl im ganzen Umbau, und der Review vermutete
|
|
399
|
+
genau darin die Gefahr -- die Notbremse koenne ausgerechnet in dem
|
|
400
|
+
Augenblick zuschlagen, gegen den dieser Fix gebaut ist.
|
|
401
|
+
Nachgemessen (echte Netzanfrage, danach hartes Beenden nach N ms, je
|
|
402
|
+
20 Laeufe, Node 24):
|
|
403
|
+
0 ms .... 20 von 20 Abstuerzen
|
|
404
|
+
1 ms .... 17 von 20
|
|
405
|
+
5 ms .... 14 von 20
|
|
406
|
+
10 ms ..... 7 von 20
|
|
407
|
+
25 ms ..... 0 von 20
|
|
408
|
+
50 ms ..... 0 von 20
|
|
409
|
+
2 000 ms ..... 0 von 20
|
|
410
|
+
5 000 ms ..... 0 von 20
|
|
411
|
+
Das gefaehrliche Fenster ist also rund 25 Millisekunden breit, nicht
|
|
412
|
+
Sekunden -- die zwei Sekunden liegen achtzigfach dahinter. Der Verdacht
|
|
413
|
+
des Reviews ist damit widerlegt, und Erhoehen wuerde nichts kaufen: Es
|
|
414
|
+
wuerde nur den einzigen Fall verlangsamen, in dem die Notbremse
|
|
415
|
+
ueberhaupt zaehlt (ein Kanal, der wirklich haengt).
|
|
416
|
+
⚠️ Gemessen auf Node 24; ausgeliefert wird ab Node 20 (cli/package.json).
|
|
417
|
+
Auf Node 20 ist es NICHT nachgemessen -- auf diesem Rechner steht keine
|
|
418
|
+
solche Fassung. Was dagegen spricht, dass es dort anders liegt: Der
|
|
419
|
+
Abbruch haengt an einem Kanal, der gerade zugeht, und das ist eine Sache
|
|
420
|
+
von Millisekunden, nicht von Sekunden.
|
|
395
421
|
*/
|
|
396
422
|
setTimeout(() => process.exit(code), 2000).unref();
|
|
397
423
|
process.stdout.write("", () => {
|
|
@@ -524,8 +550,16 @@ haupt()
|
|
|
524
550
|
// Kommentar an `endeMitHinweis` verbietet, denn auf Windows sind beide
|
|
525
551
|
// Ausgabekanaele asynchron und `process.exit()` wirft Ausstehendes weg.
|
|
526
552
|
// Ausgerechnet die Fehlermeldung waere das Erste, was verlorengeht.
|
|
527
|
-
//
|
|
528
|
-
//
|
|
553
|
+
// ⚠️ Die beiden Faelle liegen dabei VERSCHIEDEN, und das stand hier bis zur
|
|
554
|
+
// dritten Review-Runde falsch ("beide entstehen nach einer Netzanfrage"):
|
|
555
|
+
// `NichtAngemeldet` wird in cli/src/api.ts:117 geworfen, BEVOR die Anfrage
|
|
556
|
+
// ueberhaupt hinausgeht (der `fetch` steht dort erst in Zeile 171) -- dort
|
|
557
|
+
// drohte der Absturz aus D-18 also nie. Nur die zweite Meldung ("nicht
|
|
558
|
+
// erreichbar") kommt nach einer Netzanfrage, und nur fuer sie galt das.
|
|
559
|
+
// 🔑 Fuer BEIDE gilt dagegen der Grund darueber: Auf Windows sind die
|
|
560
|
+
// Ausgabekanaele asynchron, und ein hartes Beenden wirft Ausstehendes weg.
|
|
561
|
+
// *Ein Kommentar, der eine richtige Aenderung halb falsch begruendet, ist
|
|
562
|
+
// gefaehrlicher als keiner -- der naechste Leser rechnet nicht nach.*
|
|
529
563
|
// 🔑 `exitCode` statt `exit`: Die Zahl stimmt, die Meldung kommt an, und
|
|
530
564
|
// Node laeuft aus, sobald die Kanaele leer sind.
|
|
531
565
|
.catch((f) => {
|
package/dist/kontext-stand.js
CHANGED
|
@@ -466,6 +466,10 @@ export function baueMerkzettel(dateien, staende, firmenId, vorlagenPruefsummen)
|
|
|
466
466
|
* schreibt keine einzige Datei. Fuer die fuenf gesendeten Texte geht das
|
|
467
467
|
* trotzdem auf: Was der Server zurueckgibt, entsteht aus dem, was die CLI ihm
|
|
468
468
|
* gerade geschickt hat, und dasselbe steht auf der Platte.
|
|
469
|
+
* ⚠️ Seit dem 25.09. (Luecke L12) gilt das nur noch, weil der SERVER es
|
|
470
|
+
* sicherstellt: Er liefert einen um neue Fragen ergaenzten Text aus, traegt im
|
|
471
|
+
* Merkzettel aber die Pruefsumme des GESENDETEN ein -- `merkzettelFuerHochAntwort`
|
|
472
|
+
* in `src/lib/cli/merkzettel-hoch.ts`. Wer dort etwas aendert, bricht diese Zeile.
|
|
469
473
|
*
|
|
470
474
|
* ⚠️ **Fuer die Firmen-`CLAUDE.md` geht es NICHT auf, seit Ruling K-6.** Sie
|
|
471
475
|
* wird nicht mehr gesendet, aber der Server BAUT sie neu (er setzt die frischen
|
package/dist/wache-schalter.js
CHANGED
|
@@ -29,6 +29,9 @@ export function leseWacheDatei() {
|
|
|
29
29
|
raus.zuletzt = inhalt.zuletzt;
|
|
30
30
|
if (typeof inhalt.sitzung === "string")
|
|
31
31
|
raus.sitzung = inhalt.sitzung;
|
|
32
|
+
if (Array.isArray(inhalt.sitzungen)) {
|
|
33
|
+
raus.sitzungen = inhalt.sitzungen.filter((s) => typeof s === "string");
|
|
34
|
+
}
|
|
32
35
|
return raus;
|
|
33
36
|
}
|
|
34
37
|
catch {
|
|
@@ -107,12 +110,44 @@ export function sitzungJetzt() {
|
|
|
107
110
|
const roh = process.env.CLAUDE_CODE_SESSION_ID;
|
|
108
111
|
return typeof roh === "string" && roh.trim() !== "" ? roh : null;
|
|
109
112
|
}
|
|
110
|
-
/** Merken, fuer
|
|
113
|
+
/** Merken, dass fuer diese Claude-Sitzung nachgesehen wurde. Wirft nie. */
|
|
111
114
|
export function merkeSitzung(sitzung) {
|
|
112
115
|
if (sitzung === null)
|
|
113
116
|
return;
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
schreibeWacheDatei(mitSitzung(leseWacheDatei() ?? {}, sitzung));
|
|
118
|
+
}
|
|
119
|
+
/** Wie viele Sitzungen der Merkzettel sich merkt -- genug fuer mehrere Fenster ueber Tage. */
|
|
120
|
+
const MERKE_SITZUNGEN = 20;
|
|
121
|
+
/**
|
|
122
|
+
* Der Merkzettel, nachdem fuer `sitzung` nachgesehen wurde.
|
|
123
|
+
*
|
|
124
|
+
* 🔴 **EINE LISTE, NICHT EINE NUMMER** (gemessen 19.09., behoben 25.09.). Bis
|
|
125
|
+
* dahin stand hier nur `sitzung` -- das zweite Claude-Fenster ueberschrieb die
|
|
126
|
+
* Nummer des ersten, und von da an haengte jeder `kimal3`-Befehl im ersten
|
|
127
|
+
* Fenster die Zeile „die taegliche Pruefung hat nicht nachgesehen" an, obwohl
|
|
128
|
+
* sie lief. Ein Fehlalarm genau dort, wo die Meldung Vertrauen braucht.
|
|
129
|
+
*
|
|
130
|
+
* ⚠️ `sitzung` (die juengste) wird WEITER geschrieben: Eine aeltere Fassung auf
|
|
131
|
+
* demselben Rechner liest nur dieses Feld. Neueste zuerst, doppelte raus,
|
|
132
|
+
* hoechstens {@link MERKE_SITZUNGEN} -- damit die Datei nicht waechst.
|
|
133
|
+
* REIN, damit `check:wache` sie ohne Dateisystem pruefen kann.
|
|
134
|
+
*
|
|
135
|
+
* 📌 **Zwei bekannte Grenzen** (Review 25.09., bewusst nicht gebaut):
|
|
136
|
+
* - Starten zwei Fenster in DERSELBEN Millisekunde, lesen beide die alte Liste
|
|
137
|
+
* und der Letzte gewinnt -- Lesen und Schreiben liegen in `merkeSitzung`
|
|
138
|
+
* direkt nacheinander, das Fenster ist winzig. Eine Dateisperre waere ein
|
|
139
|
+
* zweites Risiko fuer einen Claude-Start, der nie haengen darf.
|
|
140
|
+
* - Laeuft auf demselben Rechner zusaetzlich eine Fassung vor 0.2.10, schreibt
|
|
141
|
+
* sie die Datei ohne `sitzungen` zurueck. Dann gilt bis zum naechsten Lauf
|
|
142
|
+
* wieder das Einzelfeld -- der alte Zustand, kein neuer Fehler.
|
|
143
|
+
*/
|
|
144
|
+
export function mitSitzung(bisher, sitzung) {
|
|
145
|
+
const aeltere = (bisher.sitzungen ?? []).filter((s) => s !== sitzung);
|
|
146
|
+
return { ...bisher, sitzung, sitzungen: [sitzung, ...aeltere].slice(0, MERKE_SITZUNGEN) };
|
|
147
|
+
}
|
|
148
|
+
/** Steht diese Sitzung im Merkzettel -- im alten Einzelfeld oder in der Liste? */
|
|
149
|
+
function gesehen(inhalt, jetzt) {
|
|
150
|
+
return inhalt.sitzung === jetzt || (inhalt.sitzungen ?? []).includes(jetzt);
|
|
116
151
|
}
|
|
117
152
|
/**
|
|
118
153
|
* Hat die Wache fuer GENAU DIESE Claude-Sitzung schon nachgesehen?
|
|
@@ -137,7 +172,7 @@ export function merkeSitzung(sitzung) {
|
|
|
137
172
|
* darf ihn nicht zum Schweigen bringen.
|
|
138
173
|
*/
|
|
139
174
|
export function schonFuerDieseSitzung(inhalt, jetzt) {
|
|
140
|
-
return jetzt !== null && inhalt !== null && inhalt
|
|
175
|
+
return jetzt !== null && inhalt !== null && gesehen(inhalt, jetzt);
|
|
141
176
|
}
|
|
142
177
|
/**
|
|
143
178
|
* Ist die Wache fuer diese Claude-Sitzung ausgefallen?
|
|
@@ -170,5 +205,5 @@ inhalt, jetzt) {
|
|
|
170
205
|
return false;
|
|
171
206
|
if (inhalt !== null && inhalt.aus === true)
|
|
172
207
|
return false;
|
|
173
|
-
return inhalt === null || inhalt
|
|
208
|
+
return inhalt === null || !gesehen(inhalt, jetzt);
|
|
174
209
|
}
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -110,6 +110,12 @@ Sie legen dann nichts an, sondern nennen die Firmen als fertige Zeilen zum Kopie
|
|
|
110
110
|
kein Fehler, sondern die Rückfrage: Der Ordner trägt den Namen der Firma, und raten darf der
|
|
111
111
|
Befehl ihn nicht.
|
|
112
112
|
|
|
113
|
+
🔑 **Ausnahme ab 0.2.10: `werkbank neu` im Firmen-Ordner fragt nicht, wenn der Ordner seine Firma
|
|
114
|
+
eindeutig nennt** (Merkzettel oder Firmenzeile der `CLAUDE.md`). Dann steht nach dem Anlegen
|
|
115
|
+
„Die Firma kam aus diesem Ordner: …“ — das ist die Wahl des Programms aus dem Ordner, nicht
|
|
116
|
+
deine. Sag dem Menschen die Firma; will er eine andere, löscht er den neuen Ordner und legt ihn
|
|
117
|
+
mit `--firma` neu an.
|
|
118
|
+
|
|
113
119
|
```
|
|
114
120
|
kimal3 arbeitsplatz neu sabine --firma "Nordwind Handel GmbH"
|
|
115
121
|
kimal3 werkbank neu sabine --firma "Nordwind Handel GmbH"
|
|
@@ -192,6 +198,17 @@ Stelle.
|
|
|
192
198
|
3. **Die Antwort in die genannte Datei schreiben** — unter ihre `## `-Überschrift, über der der
|
|
193
199
|
Anker steht. Die Hinweiszeilen mit `>` gehören uns; **lass sie stehen und schreib darunter.**
|
|
194
200
|
|
|
201
|
+
🔴 **Schreib die Antwort so, dass man sie als Rohtext lesen kann:**
|
|
202
|
+
- **Eine Zeile nie mitten im Satz umbrechen** — auch nicht, wenn sie lang wird. Ein Absatz
|
|
203
|
+
ist eine Zeile. Die `>`-Hinweise darüber sind umbrochen; **ahm sie nicht nach.**
|
|
204
|
+
- **Kein `**fett**`, keine Überschriften, keine Tabellen.**
|
|
205
|
+
- Mehrere Aussagen werden am besten eine Liste, jede Zeile beginnt mit `- `.
|
|
206
|
+
|
|
207
|
+
🔑 **Warum:** In der App (**Firma → Kontext**) steht jede Antwort in einem Eingabefeld, das
|
|
208
|
+
den Text zeigt, wie er in der Datei steht. Ein Umbruch nach ~100 Zeichen reißt dort den Satz
|
|
209
|
+
mitten durch, und `**fett**` erscheint als Sternchen — bei jeder Kollegin, die dort liest oder
|
|
210
|
+
weiterschreibt. *Aufgefallen am 25.09.2026 an unseren eigenen Antworten.*
|
|
211
|
+
|
|
195
212
|
🔴 **Die Pfade zählen ab dem Ordner, den `kontext fragen` als `Arbeitsplatz:` nennt — nicht
|
|
196
213
|
ab deinem Arbeitsverzeichnis.** Der Normalfall ist, dass beides auseinanderfällt:
|
|
197
214
|
`kimal3 arbeitsplatz neu` rät ausdrücklich, in die **Werkbank** zu wechseln und dort Claude
|
|
@@ -212,7 +229,9 @@ selbst schreibt, ist in Ordnung; ein Satz, den du dir ausdenkst, nicht.
|
|
|
212
229
|
⚠️ **Sieht eine der fünf Dateien nicht mehr aus wie ihre Frageliste — etwa weil etwas Fremdes
|
|
213
230
|
darüberkopiert wurde —, bricht `kontext hoch` ab und schickt gar nichts, auch die vier anderen
|
|
214
231
|
nicht** (Rückgabewert `1`). Das ist **kein** „noch einmal versuchen": Sag dem Menschen, welche
|
|
215
|
-
Datei gemeint ist
|
|
232
|
+
Datei gemeint ist. Zurück holt sie `kimal3 kontext runter` nur, wenn sie **fehlt** — eine
|
|
233
|
+
bearbeitete Datei fasst es nicht an. Also: Datei umbenennen (etwa `firma-alt.md`), dann
|
|
234
|
+
`kimal3 kontext runter`; die Fassung der Firma kommt frisch, seine bleibt daneben liegen.
|
|
216
235
|
|
|
217
236
|
🔴 **Bei `kontext hoch` sagt die Zahl `1` allein GAR NICHTS — die Meldung sagt es. LIES SIE.**
|
|
218
237
|
|
|
@@ -1,43 +1,97 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Sitzung sauber beenden — Stand sichern, aufräumen, zusammenfassen
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
<!-- kimal3:erzeugt — diese Datei wird von `kimal3 skill install` gepflegt und bei
|
|
6
|
-
jedem Update ueberschrieben. Eigene Aenderungen gehen dabei verloren; wer sie
|
|
7
|
-
behalten will, kopiert die Datei unter einem anderen Namen. -->
|
|
8
|
-
# Feierabend
|
|
9
|
-
|
|
10
|
-
> Sauberer Sitzungs-Abschluss: Stand sichern, aufräumen, zusammenfassen — damit der nächste
|
|
11
|
-
> Start (in diesem oder einem anderen Projekt) sauber weitergeht.
|
|
12
|
-
|
|
13
|
-
Führe die Schritte der Reihe nach aus. Bleib im Coaching-Ton: erklär kurz, was du tust, und hol
|
|
14
|
-
dir **vor dem Veröffentlichen (Push)** ein OK. Ist ein Schritt hier nicht relevant, sag das kurz
|
|
15
|
-
und überspring ihn — kein Leerlauf.
|
|
16
|
-
|
|
17
|
-
## 1. Stand sichten
|
|
18
|
-
- Ist es ein Git-Repo? Dann `git status` + `git diff --stat`: Was wurde in dieser Sitzung
|
|
19
|
-
geändert? Fass es in 1–2 Sätzen zusammen.
|
|
20
|
-
- Kein Git-Repo? Sag das kurz und biete an, eins einzurichten (Sicherheitsnetz) — erzwing nichts.
|
|
21
|
-
|
|
22
|
-
## 2.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
1
|
+
---
|
|
2
|
+
description: Sitzung sauber beenden — Stand sichern, aufräumen, zusammenfassen
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
<!-- kimal3:erzeugt — diese Datei wird von `kimal3 skill install` gepflegt und bei
|
|
6
|
+
jedem Update ueberschrieben. Eigene Aenderungen gehen dabei verloren; wer sie
|
|
7
|
+
behalten will, kopiert die Datei unter einem anderen Namen. -->
|
|
8
|
+
# Feierabend
|
|
9
|
+
|
|
10
|
+
> Sauberer Sitzungs-Abschluss: Stand sichern, aufräumen, zusammenfassen — damit der nächste
|
|
11
|
+
> Start (in diesem oder einem anderen Projekt) sauber weitergeht.
|
|
12
|
+
|
|
13
|
+
Führe die Schritte der Reihe nach aus. Bleib im Coaching-Ton: erklär kurz, was du tust, und hol
|
|
14
|
+
dir **vor dem Veröffentlichen (Push)** ein OK. Ist ein Schritt hier nicht relevant, sag das kurz
|
|
15
|
+
und überspring ihn — kein Leerlauf.
|
|
16
|
+
|
|
17
|
+
## 1. Stand sichten
|
|
18
|
+
- Ist es ein Git-Repo? Dann `git status` + `git diff --stat`: Was wurde in dieser Sitzung
|
|
19
|
+
geändert? Fass es in 1–2 Sätzen zusammen.
|
|
20
|
+
- Kein Git-Repo? Sag das kurz und biete an, eins einzurichten (Sicherheitsnetz) — erzwing nichts.
|
|
21
|
+
|
|
22
|
+
## 2. Status-Datei nachziehen — und aufräumen
|
|
23
|
+
Die Status-Datei (`WEITER-HIER.md` oder `ROADMAP.md`) ist der Zettel für den nächsten Start. Sie
|
|
24
|
+
taugt nur, solange man sie in einem Atemzug lesen kann. **Jeder Feierabend schreibt etwas dazu —
|
|
25
|
+
also muss auch jeder Feierabend etwas wegräumen**, sonst wächst sie, bis niemand sie mehr liest.
|
|
26
|
+
|
|
27
|
+
Gibt es keine Status-Datei und die Arbeit wächst über eine Sitzung hinaus: eine vorschlagen,
|
|
28
|
+
dann weiter mit Schritt 3.
|
|
29
|
+
|
|
30
|
+
1. **Nachziehen:** „Wo wir stehen" und „nächster Schritt" auf das setzen, was heute passiert ist.
|
|
31
|
+
2. **Wegräumen, was nicht mehr gilt.** Ins Archiv wandert:
|
|
32
|
+
- was **erledigt** ist (fertige Aufgaben, abgehakte Punkte),
|
|
33
|
+
- die Geschichten **früherer Sitzungen** („Davor …", „Stand vom …") — in „Wo wir stehen" bleibt
|
|
34
|
+
nur der heutige Stand,
|
|
35
|
+
- was im Text **widerlegt oder überholt** ist.
|
|
36
|
+
Was bleibt: der aktuelle Stand, der nächste Schritt, die offenen Punkte, und je Idee für später
|
|
37
|
+
**höchstens zwei Sätze** — Ausführliches bekommt eine eigene Datei, die Status-Datei verlinkt sie.
|
|
38
|
+
3. **Ins Archiv heißt: verschieben, nicht löschen.** Gibt es schon ein Archiv (steht meist im Kopf
|
|
39
|
+
der Status-Datei), dorthin; sonst `WEITER-HIER-archiv.md` daneben anlegen. Unten anhängen, mit
|
|
40
|
+
dem heutigen Datum als Überschrift, **im Wortlaut** — das Warum früherer Entscheidungen soll
|
|
41
|
+
auffindbar bleiben.
|
|
42
|
+
4. **Messen statt schätzen:** Zeilen der Status-Datei **vorher und nachher zählen**. Steht in ihrem
|
|
43
|
+
Kopf eine Zielgröße, gilt die, sonst **150 Zeilen**. Liegt sie danach noch drüber, weiter
|
|
44
|
+
wegräumen — oder sag laut, warum der Rest bleiben muss. Prüf danach im Archiv nach, dass das
|
|
45
|
+
Verschobene wirklich dort steht (eine Zeile daraus suchen), bevor du es als erledigt meldest.
|
|
46
|
+
5. **Sag laut, was du geändert hast:** was neu drinsteht, was ins Archiv ging, Zeilen vorher → nachher.
|
|
47
|
+
|
|
48
|
+
## 3. Gelernte Regeln — gehört etwas festgehalten?
|
|
49
|
+
**Nur bei echtem Anlass**, nicht als Pflichtübung. Ein Anlass ist: Ich habe dich heute korrigiert,
|
|
50
|
+
eine Arbeitsweise ausdrücklich gewollt, oder dieselbe Art Frage zum dritten Mal gleich beantwortet.
|
|
51
|
+
Kein Anlass? Sag das in einem Halbsatz und geh weiter.
|
|
52
|
+
|
|
53
|
+
Gibt es einen, **schlag die Regel vor** — ein Satz, was du künftig anders machst, dazu Datum und
|
|
54
|
+
Anlass in einem Satz — und trag sie erst nach meinem OK ein. Wohin, hängt davon ab, was sie ist:
|
|
55
|
+
|
|
56
|
+
| Was ist es? | Wohin |
|
|
57
|
+
|---|---|
|
|
58
|
+
| **Eine Arbeitsregel** — wie du arbeiten, fragen, prüfen, erklären sollst | `~/.claude/rules/kimal3-coach.md`, **unten** im Abschnitt „Gelernte Regeln" (neueste unten) |
|
|
59
|
+
| **Etwas über mich** — wer ich bin, meine Rollen, meine Werkzeuge | meine `~/.claude/CLAUDE.md` |
|
|
60
|
+
| **Etwas über dieses Projekt** — Aufbau, Werkzeuge, Fallen | die `CLAUDE.md` im Projektordner |
|
|
61
|
+
|
|
62
|
+
🔬 **Vorher nachsehen, ob es die Regel schon gibt** — im Coach und in den CLAUDE.md-Dateien. Steht
|
|
63
|
+
sie schon da, trag sie **nicht** doppelt ein: Sag mir, wo sie steht und dass sie heute nicht
|
|
64
|
+
gegriffen hat. Eine Regel, die zweimal dasteht, wird nicht besser befolgt.
|
|
65
|
+
⚠️ **Gibt es `~/.claude/rules/kimal3-coach.md` nicht**, kommt auch eine Arbeitsregel in meine
|
|
66
|
+
`~/.claude/CLAUDE.md`. Leg die Coach-Datei **nicht** selbst an — sie gehört kimal3.
|
|
67
|
+
🔴 **Im Coach änderst du NUR den Abschnitt „Gelernte Regeln"** und schreibst nur unten dazu. Alles
|
|
68
|
+
darüber ist die Vorlage von kimal3 — dort änderst du nichts.
|
|
69
|
+
|
|
70
|
+
Sag danach laut, **welcher Satz in welcher Datei** steht (vollständiger Pfad). Der Ordner
|
|
71
|
+
`~/.claude` ist meist kein Git-Repo — die Datei ist dann nicht über Git gesichert; sag das dazu.
|
|
72
|
+
|
|
73
|
+
## 4. Projekt aufräumen (leichtgewichtig)
|
|
74
|
+
- Offensichtlichen Müll entfernen (`.DS_Store`, `*.tmp`, `*.log`, `__pycache__`).
|
|
75
|
+
- Bei allem Unklaren: **nicht** löschen — auflisten und mich fragen.
|
|
76
|
+
|
|
77
|
+
## 5. Sichern (mit meinem OK)
|
|
78
|
+
- Stage die relevanten Änderungen **Datei für Datei** — **niemals** Secrets oder `.env*`, und kein
|
|
79
|
+
`git add -A`, das fremde Arbeit mitnimmt.
|
|
80
|
+
- Zeig mir kurz, was in den Commit geht — **und was bewusst draußen bleibt**: Dateien, die Git noch
|
|
81
|
+
nicht kennt und die nicht aus dieser Sitzung stammen, stehen mit Namen und einem Satz, was sie
|
|
82
|
+
sind, in derselben Liste. (Sie kommen oft aus einer anderen Sitzung und fallen sonst niemandem
|
|
83
|
+
auf.) Mein OK zum Commit gilt für die ganze Liste; will ich eine davon doch dabeihaben, sage ich es.
|
|
84
|
+
- Schlag eine Commit-Nachricht vor.
|
|
85
|
+
- Nach meinem OK: committen.
|
|
86
|
+
- **Pushen, je nach Projekt:** Prüf mit `git remote`, ob es überhaupt ein Ziel gibt.
|
|
87
|
+
- Kein Ziel: sag das kurz — der Commit ist dann die Sicherung, fertig.
|
|
88
|
+
- Ein Ziel: **frag, ob du pushen sollst** (der Schritt „nach außen"). Steht in der
|
|
89
|
+
Projekt-`CLAUDE.md`, dass ein Push etwas auslöst (zum Beispiel die Live-Seite neu ausliefert),
|
|
90
|
+
sag das dazu. Erst nach meiner Bestätigung `git push`.
|
|
91
|
+
|
|
92
|
+
## 6. Zusammenfassen & Abschied
|
|
93
|
+
- 2–3 Sätze **ohne Fachjargon**: Was haben wir heute geschafft, was habe ich gelernt — und in
|
|
94
|
+
einem Satz, was aufgeräumt wurde.
|
|
95
|
+
- **Ein** konkreter, kleiner nächster Schritt fürs nächste Mal (der Cliffhanger — klein halten).
|
|
96
|
+
- Kurzer, freundlicher Abschied wie ein guter Kollege, der Feierabend macht. Warte auf meine
|
|
97
|
+
Antwort, bevor die Sitzung endet.
|
|
@@ -44,6 +44,8 @@ beantwortet keine davon gut. Genau deshalb ist das ein Gespräch und kein Formul
|
|
|
44
44
|
|
|
45
45
|
Schreib die Antwort in die Datei, die `kimal3 kontext fragen` genannt hat, unter ihre
|
|
46
46
|
`## `-Überschrift. Die `>`-Hinweiszeilen gehören uns: **stehen lassen, darunter schreiben.**
|
|
47
|
+
**Wie die Antwort aussieht** (nie mitten im Satz umbrechen, kein Fett) steht in
|
|
48
|
+
`SKILL.md`, Schritt 3 des Ablaufs — halte dich daran, sonst ist sie in der App kaum lesbar.
|
|
47
49
|
|
|
48
50
|
🔴 **Nichts erfinden**, auch nichts vorschlagen, was wie eine Antwort aussieht. Weiß der Mensch
|
|
49
51
|
etwas nicht, **bleibt die Frage offen** und ist beim nächsten Mal wieder da.
|
|
@@ -76,7 +78,7 @@ Sammelausgang für mindestens sechs verschiedene Lagen, und sie verlangen Gegens
|
|
|
76
78
|
| „Hier steht kein KI-Arbeitsplatz" | **Nicht** `arbeitsplatz neu` raten! Siehe Abschnitt 2 — der Ordner existiert meist, nur steht der Mensch woanders. |
|
|
77
79
|
| „Der Kontext wurde inzwischen … geändert" | Der Ausweg steht in derselben Meldung: `--ueberschreiben`. Schlag ihn nur vor, wenn der Mensch die fremde Änderung wirklich verwerfen will — sie ist die Arbeit eines Kollegen. |
|
|
78
80
|
| mehrere Firmen / mehrdeutig | Der Ausweg heißt `--firma "…"`. **Du wählst nicht** — leg die Liste vor. |
|
|
79
|
-
| eine Datei ist nicht lesbar oder trägt keine Fragen mehr | `kimal3 kontext runter`
|
|
81
|
+
| eine Datei ist nicht lesbar oder trägt keine Fragen mehr | Die Datei umbenennen (etwa `firma-alt.md`), dann holt `kimal3 kontext runter` die Fassung der Firma frisch. Eine selbst bearbeitete Datei fasst `runter` sonst **nicht** an. |
|
|
80
82
|
| **„Du gehörst keiner Firma an."** | 🔴 **Schick ihn NICHT zu einem Admin — es gibt keinen.** Das trifft ausgerechnet den frischen Pro-Käufer: Er bekommt seinen Arbeitsplatz mit allen Fragen offen, beantwortet sie brav, und hier ist niemand, an den sie gehen könnten. Sag ihm, dass seine Antworten **in seinen Dateien stehen und dort bleiben**, und dass sie hochgehen, sobald es eine Firma gibt. Nichts geht verloren. |
|
|
81
83
|
| **„Die Firma hat deine Änderungen gespeichert — nur der lokale Merkzettel …"** | 🔴 **Das ist ein ERFOLG.** Alles ist oben angekommen; nur eine Datei auf der Platte ließ sich nicht schreiben. Sag genau das — **niemals** „das hat nicht geklappt". (ab 0.2.8 Rückgabe 0) |
|
|
82
84
|
|