kimal3 0.2.7 → 0.2.9
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/befehle/kontext-hoch.js +12 -4
- package/dist/befehle/projekt-neu.js +33 -3
- package/dist/befehle/wache.js +7 -1
- package/dist/kimal3.js +38 -4
- package/dist/kontext-hoch-zeile.js +11 -0
- package/dist/projekt-neu-firma.js +74 -0
- package/package.json +27 -27
- package/skill/SKILL.md +18 -6
- package/skill/commands/k3feierabend.md +97 -43
- package/skill/commands/k3kontext.md +10 -6
- package/skill/commands/k3projekt.md +4 -2
|
@@ -4,6 +4,7 @@ import { FIRMEN_TEXTE, alsMerkzettel, bekannterStandAus, merkzettelNachHoch, } f
|
|
|
4
4
|
import { traegtFragenVon } from "../fragen-lesen.js";
|
|
5
5
|
import { leseEineDatei, leseMerkzettelDatei, schreibeMerkzettelDatei } from "../kontext-dateien.js";
|
|
6
6
|
import { ERLAUBT, absage, arbeitsplatzOderAbsage, fremdeDateiAbsage } from "./kontext-gemeinsam.js";
|
|
7
|
+
import { hochZeile } from "../kontext-hoch-zeile.js";
|
|
7
8
|
/*
|
|
8
9
|
🪦 **Hier stand `feldSchluessel`, gestrichen mit Ruling K-6 (Task 7).**
|
|
9
10
|
|
|
@@ -185,7 +186,7 @@ export async function kontextHoch(argv) {
|
|
|
185
186
|
was daneben schiefging. Was hochgeschickt wurde, haengt nicht daran, ob ein
|
|
186
187
|
Merkzettel auf der Platte landet.
|
|
187
188
|
*/
|
|
188
|
-
console.log(
|
|
189
|
+
console.log(hochZeile(ergebnis.uebernommen));
|
|
189
190
|
const merkzettelSchreiben = schreibeMerkzettelDatei(ordner, zuSchreiben);
|
|
190
191
|
if (!merkzettelSchreiben.ok) {
|
|
191
192
|
/*
|
|
@@ -210,10 +211,17 @@ export async function kontextHoch(argv) {
|
|
|
210
211
|
*/
|
|
211
212
|
console.error("Die Firma hat deine Änderungen gespeichert — nur der lokale Merkzettel ließ sich nicht schreiben:");
|
|
212
213
|
console.error(merkzettelSchreiben.meldung);
|
|
213
|
-
|
|
214
|
+
// B-d (Dennis, 17.09.): Das ist ein ERFOLG -- die Firma hat gespeichert.
|
|
215
|
+
// Der Rueckgabewert ist fuer Maschinen da, und fuer die ist "gespeichert"
|
|
216
|
+
// die Wahrheit; die Warnung steht auf stderr fuer den Menschen. Bis 0.2.7
|
|
217
|
+
// stand hier `1`, und zwei Anleitungen fuehrten eine Tabelle, nur um diese
|
|
218
|
+
// Zahl zu uebersetzen.
|
|
219
|
+
return 0;
|
|
214
220
|
}
|
|
215
|
-
// US-3: WAS
|
|
216
|
-
// Runde 4 oben, vor der Merkzettel-Pruefung (Begruendung
|
|
221
|
+
// US-3: WAS sich bei der Firma geaendert hat, nicht nur "fertig" -- die
|
|
222
|
+
// Zeile steht seit Runde 4 oben, vor der Merkzettel-Pruefung (Begruendung
|
|
223
|
+
// dort). Seit Task 7 (B-e) kommt der Satz aus `hochZeile` und nennt nur
|
|
224
|
+
// die WIRKLICH geaenderten Dateien -- oder "nichts geaendert".
|
|
217
225
|
//
|
|
218
226
|
// 🔑 Der Erklaersatz darunter ist mit Fund F ersatzlos WEGGEFALLEN. Er
|
|
219
227
|
// benannte eine Ausnahme, die es nicht mehr gibt -- fuenf Texte, zwei
|
|
@@ -2,11 +2,16 @@ import { feld, ruf } from "../api.js";
|
|
|
2
2
|
import { schlussFehler } from "../fehler.js";
|
|
3
3
|
import { BASIS_URL } from "../anmeldung.js";
|
|
4
4
|
import { zerlege } from "../argumente.js";
|
|
5
|
+
import { absage } from "./kontext-gemeinsam.js";
|
|
6
|
+
import { befehlszeileOhneFirma, firmenKoerperAus, ohneFirmaAusArgv } from "../projekt-neu-firma.js";
|
|
5
7
|
const OPTIONEN = [
|
|
6
8
|
"titel", "beschreibung", "symbol", "stunden", "ergebnis", "umsatz",
|
|
7
|
-
"wirkung", "wirkung-label", "link", "live-seit",
|
|
9
|
+
"wirkung", "wirkung-label", "link", "live-seit", "firma", "firma-id",
|
|
8
10
|
];
|
|
9
|
-
|
|
11
|
+
// exportiert, damit `check:cli` die HILFE als AUSGABE-Text prueft (§24
|
|
12
|
+
// erlaubt das: nicht die Anleitung, die den Text beschreibt, sondern der
|
|
13
|
+
// Text, der wirklich auf dem Bildschirm des Kunden landet).
|
|
14
|
+
export const HILFE = `
|
|
10
15
|
kimal3 projekt neu --titel "Angebots-Generator" [Optionen]
|
|
11
16
|
|
|
12
17
|
--titel Pflicht. 2–80 Zeichen.
|
|
@@ -19,6 +24,9 @@ const HILFE = `
|
|
|
19
24
|
--wirkung-label Wozu, bis 40 Zeichen, z. B. "Angebotszeit".
|
|
20
25
|
--link Vollstaendige Adresse mit http:// oder https://.
|
|
21
26
|
--live-seit Datum als JJJJ-MM-TT.
|
|
27
|
+
--firma "Name" Wenn du zu mehreren Firmen gehoerst: welche das Projekt bekommt.
|
|
28
|
+
--firma-id "…" Falls zwei deiner Firmen gleich heissen.
|
|
29
|
+
--ohne-firma Das Projekt gehoert keiner Firma (steht nur auf deinem Profil).
|
|
22
30
|
`;
|
|
23
31
|
export async function projektNeu(argv) {
|
|
24
32
|
// ⚠️ VOR dem Zerlegen abfragen, nicht danach.
|
|
@@ -30,7 +38,12 @@ export async function projektNeu(argv) {
|
|
|
30
38
|
console.log(HILFE);
|
|
31
39
|
return 0;
|
|
32
40
|
}
|
|
33
|
-
|
|
41
|
+
// ⚠️ `zerlege` kennt keine Optionen ohne Wert -- `--ohne-firma` wird
|
|
42
|
+
// deshalb VOR der Zerlegung herausgefiltert, genau wie `--ueberschreiben`
|
|
43
|
+
// in kontext-hoch.ts. Die Rechnung dahinter steht in projekt-neu-firma.ts,
|
|
44
|
+
// damit `check:cli` sie pruefen kann (Final-Review F-1).
|
|
45
|
+
const { rest, ohneFirma } = ohneFirmaAusArgv(argv);
|
|
46
|
+
const z = zerlege(rest, OPTIONEN);
|
|
34
47
|
if (!z.ok) {
|
|
35
48
|
console.error(z.meldung);
|
|
36
49
|
return 1;
|
|
@@ -40,6 +53,15 @@ export async function projektNeu(argv) {
|
|
|
40
53
|
console.error("Es fehlt --titel.\n" + HILFE);
|
|
41
54
|
return 1;
|
|
42
55
|
}
|
|
56
|
+
// 🔴 Final-Review F-3: `--ohne-firma` zusammen mit `--firma`/`--firma-id`
|
|
57
|
+
// liesse die Route den Schalter still gewinnen lassen (`firmenWunschAus` in
|
|
58
|
+
// route.ts prueft `ohne_firma` zuerst). Hier abweisen, bevor der Wunsch
|
|
59
|
+
// ueberhaupt losgeschickt wird.
|
|
60
|
+
const wunsch = firmenKoerperAus(o.firma, o["firma-id"], ohneFirma);
|
|
61
|
+
if (!wunsch.ok) {
|
|
62
|
+
console.error(wunsch.meldung);
|
|
63
|
+
return 1;
|
|
64
|
+
}
|
|
43
65
|
const antwort = await ruf("/api/cli/projekt", {
|
|
44
66
|
mitAusweis: true,
|
|
45
67
|
koerper: {
|
|
@@ -48,6 +70,7 @@ export async function projektNeu(argv) {
|
|
|
48
70
|
zeitersparnis_std_wo: o.stunden ?? "", ergebnis_monat_eur: o.ergebnis ?? "",
|
|
49
71
|
umsatz_monat_eur: o.umsatz ?? "", link_url: o.link ?? "",
|
|
50
72
|
live_seit: o["live-seit"] ?? "",
|
|
73
|
+
...wunsch.koerper,
|
|
51
74
|
},
|
|
52
75
|
});
|
|
53
76
|
if (antwort.status === 201) {
|
|
@@ -73,6 +96,13 @@ export async function projektNeu(argv) {
|
|
|
73
96
|
console.error(`${meldung} Leg es hier an: ${BASIS_URL}/profil`);
|
|
74
97
|
return 1;
|
|
75
98
|
}
|
|
99
|
+
if (antwort.status === 409) {
|
|
100
|
+
// Firmen-Absage in der Form von arbeitsplatz/kontext: `absage` druckt die
|
|
101
|
+
// Meldung und die Firmen als fertige Befehle. Der Befehl in der Zeile
|
|
102
|
+
// traegt ALLE getippten Optionen mit, nicht nur --titel (Final-Review
|
|
103
|
+
// F-2) -- sonst verliert der Kunde beim Kopieren --stunden, --ergebnis &co.
|
|
104
|
+
return absage(antwort, `projekt neu ${befehlszeileOhneFirma(o)}`);
|
|
105
|
+
}
|
|
76
106
|
// ⚠️ Hier landet auch die `503` "Konto gerade nicht prüfbar" — und sie MUSS
|
|
77
107
|
// hier landen, nicht oben bei der 402. Rueckgabewert 3 heisst "nochmal
|
|
78
108
|
// versuchen kann helfen"; 4 heisst laut SKILL.md ausdruecklich "nicht
|
package/dist/befehle/wache.js
CHANGED
|
@@ -107,9 +107,15 @@ function skillIstVeraltet() {
|
|
|
107
107
|
*/
|
|
108
108
|
async function frageServer(schluessel, heute) {
|
|
109
109
|
try {
|
|
110
|
+
// 🔴 Die Version reist mit, wie bei jedem anderen Befehl (`api.ts`). Bis
|
|
111
|
+
// 0.2.7 fehlte sie hier -- und der Server konnte nicht wissen, dass diese
|
|
112
|
+
// Fassung einen Update-Hinweis ohnehin verwirft; der belegte dann den
|
|
113
|
+
// einen Platz der Antwort, und ein Angebot kam ueber die Wache nie an
|
|
114
|
+
// (live gemessen 17.09.). Faellt die Version aus, geht der Kopf nicht mit.
|
|
115
|
+
const version = eigeneVersion();
|
|
110
116
|
const antwort = await fetch(`${BASIS_URL}/api/cli/wache`, {
|
|
111
117
|
method: "POST",
|
|
112
|
-
headers: { Authorization: `Bearer ${schluessel}
|
|
118
|
+
headers: { Authorization: `Bearer ${schluessel}`, ...(version ? { "X-Kimal3-Version": version } : {}) },
|
|
113
119
|
signal: AbortSignal.timeout(ZEITGRENZE_MS),
|
|
114
120
|
});
|
|
115
121
|
const koerper = await antwort.json().catch(() => null);
|
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) => {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Die Erfolgszeile von `kimal3 kontext hoch` -- als reine Rechnung, damit
|
|
3
|
+
* `check:cli` sie prueft. Sie nennt, was sich BEI DER FIRMA geaendert hat,
|
|
4
|
+
* nicht, was gesendet wurde (B-e, 29.08.: fuenf Dateien genannt, zwei
|
|
5
|
+
* geaendert, eine davon ohne Zutun des Menschen).
|
|
6
|
+
*/
|
|
7
|
+
export function hochZeile(uebernommen) {
|
|
8
|
+
if (uebernommen.length === 0)
|
|
9
|
+
return "✓ nichts geändert — alles war schon so";
|
|
10
|
+
return `✓ geändert bei der Firma: ${uebernommen.join(", ")}`;
|
|
11
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { alsBefehlszeile } from "./argumente.js";
|
|
2
|
+
/**
|
|
3
|
+
* Der Firmenwunsch bei `projekt neu` -- herausgeloest aus `befehle/projekt-neu.ts`,
|
|
4
|
+
* damit `check:cli` ihn als reine Rechnung pruefen kann (Final-Review F-1).
|
|
5
|
+
*
|
|
6
|
+
* 🔴 **Vorher stand hier keine Rechnung, sondern zwei Zeilen QUELLTEXT-Pruefung**
|
|
7
|
+
* in `check-cli.mts` (`quelle.includes(...)`, ein Regex auf `argv.filter(...)`).
|
|
8
|
+
* Die wurden rot, wenn jemand die Lambda-Variable umbenannte, und blieben gruen,
|
|
9
|
+
* wenn die CLI aufhoerte, `ohne_firma` zu senden -- genau das Fehlerbild aus
|
|
10
|
+
* `docs/regeln/messen-und-pruefen.md`, Abschnitt 24: Eine Wache, die Text gegen
|
|
11
|
+
* Text haelt, bewacht die Formulierung, nicht das Verhalten.
|
|
12
|
+
*
|
|
13
|
+
* Zwei Schritte, weil `--ohne-firma` ein Schalter OHNE Wert ist und `zerlege`
|
|
14
|
+
* das nicht kennt (Begruendung in argumente.ts) -- er muss deshalb VOR dem
|
|
15
|
+
* Zerlegen raus. `--firma`/`--firma-id` sind normale Optionen mit Wert und
|
|
16
|
+
* liegen erst NACH dem Zerlegen vor.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Schritt 1, vor `zerlege`: `--ohne-firma` aus der Befehlszeile herausfiltern.
|
|
20
|
+
* Das ist die Rechnung, die vorher nur als Regex auf ihren eigenen Quelltext
|
|
21
|
+
* gewacht wurde.
|
|
22
|
+
*/
|
|
23
|
+
export function ohneFirmaAusArgv(argv) {
|
|
24
|
+
return {
|
|
25
|
+
rest: argv.filter((a) => a !== "--ohne-firma"),
|
|
26
|
+
ohneFirma: argv.includes("--ohne-firma"),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Schritt 2, nach `zerlege`: aus Firmenname, Firmen-ID und dem Schalter den
|
|
31
|
+
* Rumpf fuer `/api/cli/projekt` bauen -- oder abweisen (Final-Review F-3).
|
|
32
|
+
*
|
|
33
|
+
* 🔴 **Die Route (`firmenWunschAus` in `src/app/api/cli/projekt/route.ts`)
|
|
34
|
+
* laesst `ohne_firma` GEWINNEN, wenn beides genannt wird** -- `--firma` wird
|
|
35
|
+
* dort still ignoriert, ohne dass die Firma je zu Wort kommt. Statt die Route
|
|
36
|
+
* anzufassen (0.2.7-Vertrag, ein `git push` macht sie fuer ALLE sofort neu,
|
|
37
|
+
* s. CLAUDE.md "Einer CLI-Route eine neue Rueckfrage beibringen"), weist die
|
|
38
|
+
* CLI die widerspruechliche Eingabe VORHER ab -- wie beim fehlenden `--titel`
|
|
39
|
+
* daneben.
|
|
40
|
+
*/
|
|
41
|
+
export function firmenKoerperAus(firma, firmaId, ohneFirma) {
|
|
42
|
+
if (ohneFirma && (firma || firmaId)) {
|
|
43
|
+
return {
|
|
44
|
+
ok: false,
|
|
45
|
+
meldung: 'Entweder --ohne-firma ODER --firma/--firma-id -- nenn nur eines von beiden.',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return { ok: true, koerper: { firma: firma ?? "", firma_id: firmaId ?? "", ohne_firma: ohneFirma } };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Die kopierfertige Zeile fuer die Firmen-Absage (`absage` in
|
|
52
|
+
* `kontext-gemeinsam.ts`) -- ALLE getippten Optionen, nicht nur `--titel`
|
|
53
|
+
* (Final-Review F-2).
|
|
54
|
+
*
|
|
55
|
+
* 🔴 **Vorher fiel jede weitere Option unter den Tisch:** `absage` bekam
|
|
56
|
+
* immer nur `alsBefehlszeile(["--titel", o.titel])`. Wer `projekt neu --titel
|
|
57
|
+
* X --stunden 5 --ergebnis 1200` tippte und die 409-Absage bekam, sah einen
|
|
58
|
+
* Kopierbefehl, der `--stunden` und `--ergebnis` verschluckte -- beim Kopieren
|
|
59
|
+
* landete ein Projekt ohne Zeitersparnis und ohne Ergebnis.
|
|
60
|
+
*
|
|
61
|
+
* `--firma`/`--firma-id` fliegen hier raus, weil `absage` selbst genau diese
|
|
62
|
+
* Option anhaengt (`kimal3 ${befehl} --firma …`); `--ohne-firma` kommt nie in
|
|
63
|
+
* `o` an (s. `ohneFirmaAusArgv` oben) und braucht deshalb keinen eigenen
|
|
64
|
+
* Ausschluss.
|
|
65
|
+
*/
|
|
66
|
+
export function befehlszeileOhneFirma(o) {
|
|
67
|
+
const teile = [];
|
|
68
|
+
for (const [name, wert] of Object.entries(o)) {
|
|
69
|
+
if (name === "firma" || name === "firma-id")
|
|
70
|
+
continue;
|
|
71
|
+
teile.push(`--${name}`, wert);
|
|
72
|
+
}
|
|
73
|
+
return alsBefehlszeile(teile);
|
|
74
|
+
}
|
package/package.json
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "kimal3",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Trag deine KI-Projekte dort ein, wo sie entstehen: im Terminal.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"kimal3": "dist/kimal3.js"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"dist",
|
|
11
|
-
"skill",
|
|
12
|
-
"README.md"
|
|
13
|
-
],
|
|
14
|
-
"engines": {
|
|
15
|
-
"node": ">=20"
|
|
16
|
-
},
|
|
17
|
-
"scripts": {
|
|
18
|
-
"build": "tsc -p tsconfig.json",
|
|
19
|
-
"prepublishOnly": "npm run build"
|
|
20
|
-
},
|
|
21
|
-
"keywords": [
|
|
22
|
-
"kimal3",
|
|
23
|
-
"cli"
|
|
24
|
-
],
|
|
25
|
-
"homepage": "https://app.kimal3.de/pro",
|
|
26
|
-
"license": "SEE LICENSE IN README.md"
|
|
27
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "kimal3",
|
|
3
|
+
"version": "0.2.9",
|
|
4
|
+
"description": "Trag deine KI-Projekte dort ein, wo sie entstehen: im Terminal.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"kimal3": "dist/kimal3.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"skill",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=20"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc -p tsconfig.json",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"kimal3",
|
|
23
|
+
"cli"
|
|
24
|
+
],
|
|
25
|
+
"homepage": "https://app.kimal3.de/pro",
|
|
26
|
+
"license": "SEE LICENSE IN README.md"
|
|
27
|
+
}
|
package/skill/SKILL.md
CHANGED
|
@@ -192,6 +192,17 @@ Stelle.
|
|
|
192
192
|
3. **Die Antwort in die genannte Datei schreiben** — unter ihre `## `-Überschrift, über der der
|
|
193
193
|
Anker steht. Die Hinweiszeilen mit `>` gehören uns; **lass sie stehen und schreib darunter.**
|
|
194
194
|
|
|
195
|
+
🔴 **Schreib die Antwort so, dass man sie als Rohtext lesen kann:**
|
|
196
|
+
- **Eine Zeile nie mitten im Satz umbrechen** — auch nicht, wenn sie lang wird. Ein Absatz
|
|
197
|
+
ist eine Zeile. Die `>`-Hinweise darüber sind umbrochen; **ahm sie nicht nach.**
|
|
198
|
+
- **Kein `**fett**`, keine Überschriften, keine Tabellen.**
|
|
199
|
+
- Mehrere Aussagen werden am besten eine Liste, jede Zeile beginnt mit `- `.
|
|
200
|
+
|
|
201
|
+
🔑 **Warum:** In der App (**Firma → Kontext**) steht jede Antwort in einem Eingabefeld, das
|
|
202
|
+
den Text zeigt, wie er in der Datei steht. Ein Umbruch nach ~100 Zeichen reißt dort den Satz
|
|
203
|
+
mitten durch, und `**fett**` erscheint als Sternchen — bei jeder Kollegin, die dort liest oder
|
|
204
|
+
weiterschreibt. *Aufgefallen am 25.09.2026 an unseren eigenen Antworten.*
|
|
205
|
+
|
|
195
206
|
🔴 **Die Pfade zählen ab dem Ordner, den `kontext fragen` als `Arbeitsplatz:` nennt — nicht
|
|
196
207
|
ab deinem Arbeitsverzeichnis.** Der Normalfall ist, dass beides auseinanderfällt:
|
|
197
208
|
`kimal3 arbeitsplatz neu` rät ausdrücklich, in die **Werkbank** zu wechseln und dort Claude
|
|
@@ -222,11 +233,10 @@ auf dieser einen Zahl (`cli/src/befehle/kontext-hoch.ts`): unbekannte Option ·
|
|
|
222
233
|
Arbeitsplatz gefunden · eine Datei nicht lesbar · eine Datei ohne Fragen · „jemand anderes hat
|
|
223
234
|
geändert" (Ausweg `--ueberschreiben`) · mehrere Firmen (Ausweg `--firma`) — und die Rolle.
|
|
224
235
|
|
|
225
|
-
🔴 **
|
|
226
|
-
deine Änderungen gespeichert — nur der lokale Merkzettel ließ sich nicht schreiben."*
|
|
227
|
-
gibt
|
|
228
|
-
|
|
229
|
-
*Ein Erfolg, als Absage vorgelesen — und er tippt danach alles noch einmal.*
|
|
236
|
+
🔴 **Ein Fall in `kontext-hoch.ts` (Merkzettel-Zweig) sieht wie ein Fehler aus und ist ein ERFOLG:**
|
|
237
|
+
*„Die Firma hat deine Änderungen gespeichert — nur der lokale Merkzettel ließ sich nicht schreiben."*
|
|
238
|
+
Ab 0.2.8 gibt dieser Fall **0** zurück — er ist ein Erfolg. Die Warnung auf `stderr` sagt, dass
|
|
239
|
+
nur der lokale Merkzettel fehlt; beim nächsten `kontext runter` fällt das ohnehin auf.
|
|
230
240
|
|
|
231
241
|
**Also:** Nimm den Satz, den der Befehl geschrieben hat, und sag dem Menschen, was er bedeutet.
|
|
232
242
|
Geht es wirklich um die Rolle, nenne den Admin — lief vorher `kontext runter`, kennt dessen
|
|
@@ -251,7 +261,9 @@ jemand anderem geändert wurde. **Nur auf ausdrücklichen Wunsch einsetzen** —
|
|
|
251
261
|
`kimal3 projekt liste` — steht es schon da, **nicht** noch einmal eintragen.
|
|
252
262
|
|
|
253
263
|
## Eintragen
|
|
254
|
-
`kimal3 projekt neu --titel "…" [--stunden 6] [--ergebnis 1200] [--symbol bot]`
|
|
264
|
+
`kimal3 projekt neu --titel "…" [--stunden 6] [--ergebnis 1200] [--symbol bot] [--firma "Name" | --ohne-firma]`
|
|
265
|
+
Wer zu genau einer Firma gehört, braucht `--firma` nicht — das Projekt gehört ihr. Bei zwei
|
|
266
|
+
Firmen nennt die Absage beide als fertige Befehle.
|
|
255
267
|
Alle Optionen: `kimal3 projekt neu --help`
|
|
256
268
|
|
|
257
269
|
## 🔑 Zahlen nie erfinden
|
|
@@ -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.
|
|
@@ -78,12 +80,14 @@ Sammelausgang für mindestens sechs verschiedene Lagen, und sie verlangen Gegens
|
|
|
78
80
|
| mehrere Firmen / mehrdeutig | Der Ausweg heißt `--firma "…"`. **Du wählst nicht** — leg die Liste vor. |
|
|
79
81
|
| eine Datei ist nicht lesbar oder trägt keine Fragen mehr | `kimal3 kontext runter` holt sie zurück. |
|
|
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
|
-
| **„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". |
|
|
82
|
-
|
|
83
|
-
⚠️ **Warum das hier so ausführlich steht:** Die letzte Zeile
|
|
84
|
-
als „kein Admin"
|
|
85
|
-
erfolgreich hochgeschickt
|
|
86
|
-
vorgelesen.*
|
|
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) |
|
|
84
|
+
|
|
85
|
+
⚠️ **Warum das hier so ausführlich steht:** Die letzte Zeile war bis 0.2.7 der teuerste Fall. Wer
|
|
86
|
+
die `1` als „kein Admin" deutete, sagte einem Menschen, der gerade alle Fragen beantwortet und
|
|
87
|
+
erfolgreich hochgeschickt hatte, er solle sich an seinen Admin wenden. *Ein Erfolg, als Absage
|
|
88
|
+
vorgelesen.* Ab 0.2.8 trennt schon der Rückgabewert (`0` statt `1`) diesen Fall von einer
|
|
89
|
+
echten Absage — bei einer älteren CLI gilt die alte Lesart weiter, deshalb bleibt die Meldung
|
|
90
|
+
der verlässlichere Weg.
|
|
87
91
|
|
|
88
92
|
**Rückgabewert `4`**: angemeldet, aber kein Pro-Zugang — die Meldung zeigen, den Befehl **nicht**
|
|
89
93
|
wiederholen. Alles Übrige deutest du nach `SKILL.md`, Abschnitt „Rückgabewerte".
|
|
@@ -32,8 +32,10 @@ $ARGUMENTS
|
|
|
32
32
|
Pro-Bereich kopiert und unverändert abgeschickt. Dann ist **nichts** angegeben: Frag, um welches
|
|
33
33
|
Projekt es geht, statt den Platzhalter als Titel zu nehmen.
|
|
34
34
|
|
|
35
|
-
Bau daraus `kimal3 projekt neu --titel "…"` mit den passenden
|
|
36
|
-
(`kimal3 projekt neu --help` nennt alle).
|
|
35
|
+
Bau daraus `kimal3 projekt neu --titel "…" [--firma "Name" | --ohne-firma]` mit den passenden
|
|
36
|
+
Optionen (`kimal3 projekt neu --help` nennt alle). Wer zu genau einer Firma gehört, braucht
|
|
37
|
+
`--firma` nicht — das Projekt gehört ihr. Bei zwei Firmen nennt die Absage beide als fertige
|
|
38
|
+
Befehle.
|
|
37
39
|
|
|
38
40
|
🔴 **Zeitersparnis, Umsatz und Ergebnis nie schätzen.** Diese Zahlen stehen anschließend
|
|
39
41
|
**öffentlich** auf einer Seite mit dem Namen des Menschen. Wurde eine Zahl nicht genannt:
|