kimal3 0.4.0-durchstich.1 → 0.4.0
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/README.md +2 -0
- package/claude-plugins/.claude-plugin/marketplace.json +8 -0
- package/claude-plugins/README.md +7 -0
- package/claude-plugins/kimal3-logo/.claude-plugin/plugin.json +6 -0
- package/claude-plugins/kimal3-logo/hooks/hooks.json +1 -0
- package/claude-plugins/kimal3-logo/hooks/register.tsx +80 -0
- package/coach/de/kimal3-coach.md +167 -0
- package/coach/en/kimal3-coach.md +167 -0
- package/dist/arbeitsplatz-dateien.js +1 -1
- package/dist/arbeitsplatz-finden.js +115 -0
- package/dist/arbeitsplatz-suche.js +176 -0
- package/dist/befehle/einrichten.js +311 -32
- package/dist/befehle/kurs.js +77 -0
- package/dist/befehle/login.js +8 -1
- package/dist/befehle/skill-install.js +16 -2
- package/dist/befehle-katalog-en.js +12 -0
- package/dist/befehle-katalog.js +12 -0
- package/dist/befehlswoerter.js +4 -0
- package/dist/coach-ablegen.js +130 -0
- package/dist/coach-rechnung.js +40 -0
- package/dist/einstellungen-mischen.js +68 -28
- package/dist/einstellungen-schreiben.js +48 -12
- package/dist/kimal3.js +6 -3
- package/dist/logo-ablegen.js +117 -0
- package/dist/plugins-mischen.js +78 -0
- package/dist/texte/coach.js +27 -0
- package/dist/texte/einrichten-marken.js +2 -2
- package/dist/texte/einrichten.js +73 -2
- package/dist/texte/kurs.js +21 -0
- package/dist/wache-schalter.js +30 -5
- package/package.json +29 -27
- package/skill/SKILL.md +7 -3
- package/skill/commands/k3feierabend.md +2 -3
- package/skill/commands/k3kurs.md +41 -53
- package/skill/commands/k3start.md +4 -3
- package/skill/en/SKILL.md +7 -3
- package/skill/en/commands/k3course.md +41 -54
- package/skill/en/commands/k3start.md +4 -3
- package/skill/en/commands/k3wrapup.md +3 -4
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { cpSync, existsSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { basename, dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
/**
|
|
6
|
+
* Legt den Plugin-Katalog mit dem Logo-Mod in `~/.kimal3/claude-plugins` ab und setzt dort die
|
|
7
|
+
* Sprache des Kontos. Claude Code liest den Mod aus genau diesem Ordner (Katalog `kimal3`,
|
|
8
|
+
* `plugins-mischen.ts`).
|
|
9
|
+
*
|
|
10
|
+
* 🔑 Warum ein fester Ordner im Benutzerordner und nicht der Ordner im installierten npm-Paket:
|
|
11
|
+
* Der hängt am Installationsort von Node.js und wechselt mit ihm -- der Eintrag in Claudes
|
|
12
|
+
* Einstellungen zeigte dann ins Leere.
|
|
13
|
+
* 🔑 Der Ordner gehört `kimal3` (seine README sagt es): Jeder Lauf ersetzt ihn ganz (Lage P-11).
|
|
14
|
+
*/
|
|
15
|
+
export function katalogOrdner() {
|
|
16
|
+
return join(homedir(), ".kimal3", "claude-plugins"); // kein-anzeigetext: Ordnername
|
|
17
|
+
}
|
|
18
|
+
/** Die Zeile im Mod, die die Sprache festlegt -- `check:logo` prüft, dass es sie genau einmal gibt. */
|
|
19
|
+
export const SPRACH_ZEILE = "const SPRACHE: 'de' | 'en' = 'de'"; // kein-anzeigetext: Quelltext des Mods
|
|
20
|
+
/** Reine Rechnung: der Mod-Text in der Sprache des Kontos, oder `null`, wenn die Zeile fehlt. */
|
|
21
|
+
export function mitSprache(quelltext, sprache) {
|
|
22
|
+
if (quelltext.split(SPRACH_ZEILE).length !== 2)
|
|
23
|
+
return null;
|
|
24
|
+
return quelltext.replace(SPRACH_ZEILE, `const SPRACHE: 'de' | 'en' = '${sprache}'`); // kein-anzeigetext: Quelltext des Mods
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 🔴 NIE EIN HALBER ORDNER (Durchsicht-Funde 2 und 9): Claudes Einstellungen zeigen auf `katalogOrdner()`,
|
|
28
|
+
* und eine laufende Claude-Sitzung hat den Mod daraus geladen. Deshalb:
|
|
29
|
+
* 1. Sprache setzen, BEVOR irgendetwas angefasst wird -- fehlt die Zeile, bleibt alles, wie es war.
|
|
30
|
+
* 2. Steht schon genau das da, was entstehen soll: nichts anfassen (Lage P-8). Das ist auch der Normalfall
|
|
31
|
+
* eines zweiten Laufs, und so kommt er gar nicht erst in die Nähe der Windows-Sperren unten.
|
|
32
|
+
* 3. Den neuen Ordner daneben fertig bauen (`….neu`), dann tauschen: alten Ordner wegschieben, neuen an
|
|
33
|
+
* seinen Platz, alten löschen.
|
|
34
|
+
* 🔑 Der weggeschobene Ordner bekommt bei JEDEM Lauf einen frischen Namen (Durchsicht 2, Funde 2 und 4):
|
|
35
|
+
* Ein Rest, den Windows festhält, blockiert so keinen späteren Lauf, und zurückgeholt wird nur, was
|
|
36
|
+
* DIESER Lauf weggeschoben hat -- nie ein veralteter Rest von früher.
|
|
37
|
+
* Lässt sich der alte nicht wegschieben (Claude hält ihn manchmal fest), bleibt er unversehrt stehen und
|
|
38
|
+
* gilt weiter: ein Erfolg mit `alterStand`, den `kimal3 einrichten` in einer Zeile nennt.
|
|
39
|
+
*/
|
|
40
|
+
export function logoAblegen(sprache) {
|
|
41
|
+
// `dist/logo-ablegen.js` -> `../claude-plugins` im installierten Paket (`files` in package.json).
|
|
42
|
+
const quelle = fileURLToPath(new URL("../claude-plugins", import.meta.url));
|
|
43
|
+
const ziel = katalogOrdner();
|
|
44
|
+
const neu = `${ziel}.neu`; // kein-anzeigetext: Ordnername
|
|
45
|
+
const modDatei = (ordner) => join(ordner, "kimal3-logo", "hooks", "register.tsx");
|
|
46
|
+
try {
|
|
47
|
+
const text = mitSprache(readFileSync(modDatei(quelle), "utf8"), sprache);
|
|
48
|
+
if (text === null)
|
|
49
|
+
return { ok: false, detail: modDatei(quelle) };
|
|
50
|
+
if (stehtSchonDa(quelle, ziel, text)) {
|
|
51
|
+
// Auch im Normalfall aufräumen, samt einem halb gebauten `….neu`: sonst blieben Reste für immer (Durchsicht 3/4).
|
|
52
|
+
rmSync(neu, { recursive: true, force: true });
|
|
53
|
+
resteWegraeumen(ziel);
|
|
54
|
+
return { ok: true, ordner: ziel };
|
|
55
|
+
}
|
|
56
|
+
rmSync(neu, { recursive: true, force: true });
|
|
57
|
+
cpSync(quelle, neu, { recursive: true });
|
|
58
|
+
writeFileSync(modDatei(neu), text, "utf8");
|
|
59
|
+
if (!existsSync(ziel)) {
|
|
60
|
+
renameSync(neu, ziel);
|
|
61
|
+
return { ok: true, ordner: ziel };
|
|
62
|
+
}
|
|
63
|
+
const alt = `${ziel}.alt-${Date.now()}`; // kein-anzeigetext: Ordnername
|
|
64
|
+
try {
|
|
65
|
+
renameSync(ziel, alt);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
rmSync(neu, { recursive: true, force: true });
|
|
69
|
+
return { ok: true, ordner: ziel, alterStand: true };
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
renameSync(neu, ziel);
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
renameSync(alt, ziel);
|
|
76
|
+
return { ok: false, detail: e.message };
|
|
77
|
+
}
|
|
78
|
+
resteWegraeumen(ziel);
|
|
79
|
+
return { ok: true, ordner: ziel };
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
return { ok: false, detail: e.message };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** Gleiche Dateien, gleicher Inhalt -- der Mod mit der Sprache des Kontos, alles andere wie im Paket. */
|
|
86
|
+
function stehtSchonDa(quelle, ziel, modText) {
|
|
87
|
+
if (!existsSync(ziel))
|
|
88
|
+
return false;
|
|
89
|
+
const dateien = (ordner) => alleDateien(ordner).sort();
|
|
90
|
+
const soll = dateien(quelle);
|
|
91
|
+
if (JSON.stringify(soll) !== JSON.stringify(dateien(ziel)))
|
|
92
|
+
return false;
|
|
93
|
+
const mod = join("kimal3-logo", "hooks", "register.tsx");
|
|
94
|
+
return soll.every((d) => (d === mod ? Buffer.from(modText, "utf8") : readFileSync(join(quelle, d))).equals(readFileSync(join(ziel, d))));
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Alle Dateien unter `ordner`, als Pfade relativ dazu. 🔑 Von Hand statt `readdirSync(…, { recursive: true })`: Das kann
|
|
98
|
+
* Node.js erst ab 20.1, und unter 20.0 fände der Vergleich gar keine Datei -- „gleich“, und das Logo würde nie erneuert
|
|
99
|
+
* (Durchsicht 3, Fund 7; `engines` erlaubt 20).
|
|
100
|
+
*/
|
|
101
|
+
function alleDateien(ordner, unter = "") {
|
|
102
|
+
return readdirSync(join(ordner, unter), { withFileTypes: true }).flatMap((e) => e.isDirectory() ? alleDateien(ordner, join(unter, e.name)) : e.isFile() ? [join(unter, e.name)] : []);
|
|
103
|
+
}
|
|
104
|
+
/** Weggeschobene Ordner früherer Läufe (`claude-plugins.alt…`); was Windows noch festhält, bleibt bis zum nächsten Lauf. */
|
|
105
|
+
function resteWegraeumen(ziel) {
|
|
106
|
+
const name = `${basename(ziel)}.alt`; // kein-anzeigetext: Ordnername
|
|
107
|
+
for (const eintrag of readdirSync(dirname(ziel))) {
|
|
108
|
+
if (!eintrag.startsWith(name))
|
|
109
|
+
continue;
|
|
110
|
+
try {
|
|
111
|
+
rmSync(join(dirname(ziel), eintrag), { recursive: true, force: true });
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
/* festgehalten -- der nächste Lauf versucht es wieder */
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { istObjekt, leseEinstellungen } from "./einstellungen-mischen.js";
|
|
2
|
+
/**
|
|
3
|
+
* Traegt superpowers und das KImal3-Logo in Claudes Einstellungen ein -- als Katalog plus
|
|
4
|
+
* Einschalter, so wie Anthropic Firmen-Mods auf jeden Rechner verteilt (Bauplan 2026-10-15,
|
|
5
|
+
* „Warum anders als die Spec"). Beim naechsten Start laedt Claude Code beides selbst.
|
|
6
|
+
*
|
|
7
|
+
* 🔴 DIESE DATEI FASST KEINE DATEI AN -- dieselbe Bauform wie `einstellungen-mischen.ts`, aus
|
|
8
|
+
* demselben Grund: In `~/.claude/settings.json` steht der Arbeitsplatz des Menschen.
|
|
9
|
+
* Geschrieben wird ueber `einstellungen-schreiben.ts` (Sicherung, Zuruecklesen).
|
|
10
|
+
*/
|
|
11
|
+
export const KATALOG = "kimal3"; // kein-anzeigetext: Name des Plugin-Katalogs in Claudes Einstellungen
|
|
12
|
+
export const LOGO = `kimal3-logo@${KATALOG}`; // kein-anzeigetext: Plugin-Kennung
|
|
13
|
+
const OFFIZIELL = "claude-plugins-official"; // kein-anzeigetext: Anthropics Katalog
|
|
14
|
+
export const SUPERPOWERS = `superpowers@${OFFIZIELL}`; // kein-anzeigetext: Plugin-Kennung
|
|
15
|
+
/**
|
|
16
|
+
* 🔑 Jede Entscheidung des Menschen bleibt stehen (Lagen P-5 bis P-7, P-10):
|
|
17
|
+
* - Ein Eintrag fuer das Logo -- auch `false` -- heisst: Er hat schon entschieden. Wir setzen
|
|
18
|
+
* nur, was fehlt.
|
|
19
|
+
* - superpowers aus IRGENDEINEM Katalog (`superpowers@…`, an oder aus) heisst: nicht noch eins.
|
|
20
|
+
* Zwei superpowers gaeben jede Faehigkeit doppelt.
|
|
21
|
+
* - Den offiziellen Katalog tragen wir nur ein, wenn er fehlt und wir superpowers einschalten.
|
|
22
|
+
* Nur der Katalog `kimal3` gehoert uns: Er zeigt immer auf unseren Ordner (P-9, Umzug).
|
|
23
|
+
* 🔑 `katalogPfad` ist `null`, wenn der Logo-Ordner nicht angelegt werden konnte: Dann bleiben Katalog und
|
|
24
|
+
* Logo-Eintrag, wie sie sind, und superpowers kommt trotzdem -- es braucht den Ordner nicht (Durchsicht 2, Fund 1).
|
|
25
|
+
* 🔑 `mitSuperpowers` ist `false`, wenn Git fehlt: Claude Code klont Anthropics Katalog mit Git und scheiterte sonst bei
|
|
26
|
+
* jedem Start (Durchsicht 3, Fund 5). Was schon drinsteht, bleibt -- auch ein früher eingetragenes superpowers.
|
|
27
|
+
*/
|
|
28
|
+
export function mischePlugins(alt, katalogPfad, mitSuperpowers = true) {
|
|
29
|
+
const lesen = leseEinstellungen(alt);
|
|
30
|
+
if (!lesen.ok)
|
|
31
|
+
return { art: "abgelehnt", grund: lesen.grund };
|
|
32
|
+
const { objekt, leer } = lesen;
|
|
33
|
+
const kataloge = objekt.extraKnownMarketplaces ?? {};
|
|
34
|
+
const plugins = objekt.enabledPlugins ?? {};
|
|
35
|
+
if (!istObjekt(kataloge) || !istObjekt(plugins))
|
|
36
|
+
return { art: "abgelehnt", grund: "fremde-form" };
|
|
37
|
+
// Nur die Quelle gehört uns; was Claude Code selbst in den Eintrag schreibt (`autoUpdate`, wenn
|
|
38
|
+
// Sabine es unter /plugin umschaltet), bleibt stehen (QA-Fund 7). Zeigt die Quelle schon auf unseren
|
|
39
|
+
// Ordner, bleibt der Eintrag Zeichen für Zeichen, wie er ist -- auch in anderer Reihenfolge der
|
|
40
|
+
// Schlüssel; sonst schriebe jeder Lauf die Datei neu (Durchsicht-Fund 6, Lage P-8).
|
|
41
|
+
const alterEintrag = istObjekt(kataloge[KATALOG]) ? kataloge[KATALOG] : {};
|
|
42
|
+
const alteQuelle = istObjekt(alterEintrag.source) ? alterEintrag.source : {};
|
|
43
|
+
const zeigtSchonHin = alteQuelle.source === "directory" && alteQuelle.path === katalogPfad;
|
|
44
|
+
const neueKataloge = { ...kataloge };
|
|
45
|
+
const neuePlugins = { ...plugins };
|
|
46
|
+
if (katalogPfad !== null) {
|
|
47
|
+
neueKataloge[KATALOG] = zeigtSchonHin ? alterEintrag : { ...alterEintrag, source: { source: "directory", path: katalogPfad } };
|
|
48
|
+
if (!(LOGO in plugins))
|
|
49
|
+
neuePlugins[LOGO] = true;
|
|
50
|
+
}
|
|
51
|
+
if (mitSuperpowers && !Object.keys(plugins).some((k) => k.startsWith("superpowers@"))) {
|
|
52
|
+
neuePlugins[SUPERPOWERS] = true;
|
|
53
|
+
if (!(OFFIZIELL in kataloge)) {
|
|
54
|
+
neueKataloge[OFFIZIELL] = { source: { source: "github", repo: "anthropics/claude-plugins-official" } };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const neu = { ...objekt, extraKnownMarketplaces: neueKataloge, enabledPlugins: neuePlugins };
|
|
58
|
+
// Wie bei der Wache: Wer nichts zu tun hat, fasst die Datei nicht an (P-8).
|
|
59
|
+
if (!leer && JSON.stringify(neu) === JSON.stringify(objekt))
|
|
60
|
+
return { art: "unveraendert" };
|
|
61
|
+
return { art: "geschrieben", inhalt: JSON.stringify(neu, null, 2) + "\n" };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Was nach dem Eintragen wirklich gilt -- fuer die Zeile `Plugins:`, die Claude der Kundin weitersagt.
|
|
65
|
+
* 🔑 Aus der Datei gelesen, nicht aus dem, was wir eingetragen haben: Hat sie superpowers selbst
|
|
66
|
+
* ausgeschaltet, muss die Zeile das sagen, damit die Anleitung sie nicht ins Menue schickt (Durchsicht-Fund 1).
|
|
67
|
+
*/
|
|
68
|
+
export function pluginStand(inhalt) {
|
|
69
|
+
const lesen = leseEinstellungen(inhalt);
|
|
70
|
+
const plugins = lesen.ok ? lesen.objekt.enabledPlugins : undefined;
|
|
71
|
+
if (!istObjekt(plugins))
|
|
72
|
+
return { superpowers: "fehlt", logo: "fehlt" };
|
|
73
|
+
const superpowers = Object.entries(plugins).filter(([k]) => k.startsWith("superpowers@")).map(([, v]) => v);
|
|
74
|
+
return {
|
|
75
|
+
superpowers: superpowers.includes(true) ? "an" : superpowers.length > 0 ? "aus" : "fehlt",
|
|
76
|
+
logo: plugins[LOGO] === true ? "an" : LOGO in plugins ? "aus" : "fehlt",
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { EINRICHTEN_MARKEN } from "./einrichten-marken.js";
|
|
2
|
+
const M = EINRICHTEN_MARKEN;
|
|
3
|
+
const de = {
|
|
4
|
+
setUp: (pfad) => ` ${M.de.coach} eingerichtet (${pfad}).`,
|
|
5
|
+
upToDate: ` ${M.de.coach} ist aktuell.`,
|
|
6
|
+
updated: ` ${M.de.coach} aktualisiert — deine gelernten Regeln sind geblieben.`,
|
|
7
|
+
foreign: (pfad) => ` ${M.de.coach} Unter ${pfad} liegt schon eine Datei, die nicht von KImal3 stammt — ich lasse sie, wie sie ist.`,
|
|
8
|
+
noSeparator: (pfad, neu) => ` ${M.de.coach} nicht aktualisiert — in ${pfad} fehlt die Zeile, ab der deine gelernten Regeln stehen. Die neue Fassung liegt unter ${neu}.`,
|
|
9
|
+
failed: (grund) => ` ${M.de.coach} konnte nicht abgelegt werden — ${grund}`,
|
|
10
|
+
// Der Grund zu `failed`, wenn der Vorlage im Programm selbst die Trenn-Marke fehlt (ein Paketfehler, `coach-rechnung.ts`).
|
|
11
|
+
templateWithoutSeparator: "der Vorlage im Programm fehlt die Zeile, ab der die gelernten Regeln stehen. Das ist ein Fehler in kimal3 — bitte melde ihn uns.",
|
|
12
|
+
// Die Zeile spricht immer die Sprache, in die umgestellt wurde -- deshalb steht der Sprachname fest im Satz.
|
|
13
|
+
languageSwitched: "✓ Dein Coach ist jetzt auf Deutsch — deine gelernten Regeln sind geblieben.",
|
|
14
|
+
oldCourseCoach: (pfad, ablage) => ` ${M.de.alterKursCoach} Du hast im alten Mini-Kurs schon einmal einen Coach eingerichtet (${pfad}). Jetzt gibt es einen neuen, und zwei gleichzeitig würden sich widersprechen. Soll ich den alten beiseitelegen? Du findest ihn danach unter ${ablage}.`,
|
|
15
|
+
};
|
|
16
|
+
const en = {
|
|
17
|
+
setUp: (pfad) => ` ${M.en.coach} set up (${pfad}).`,
|
|
18
|
+
upToDate: ` ${M.en.coach} up to date.`,
|
|
19
|
+
updated: ` ${M.en.coach} updated — your learned rules are still there.`,
|
|
20
|
+
foreign: (pfad) => ` ${M.en.coach} There's already a file at ${pfad} that doesn't come from KImal3 — I'll leave it as it is.`,
|
|
21
|
+
noSeparator: (pfad, neu) => ` ${M.en.coach} not updated — ${pfad} is missing the line your learned rules start below. The new version is at ${neu}.`,
|
|
22
|
+
failed: (grund) => ` ${M.en.coach} couldn't be put in place — ${grund}`,
|
|
23
|
+
templateWithoutSeparator: "the program's template is missing the line your learned rules start below. That's a bug in kimal3 — please tell us.",
|
|
24
|
+
languageSwitched: "✓ Your coach is now in English — your learned rules are still there.",
|
|
25
|
+
oldCourseCoach: (pfad, ablage) => ` ${M.en.alterKursCoach} You set up a coach in the old mini course (${pfad}). There's a new one now, and two at once would contradict each other. Shall I put the old one aside? You'll find it at ${ablage} afterwards.`,
|
|
26
|
+
};
|
|
27
|
+
export const COACH_TEXTE = { de, en };
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
* Programm druckt sie, die Anleitung nennt sie, `check:kurs` haelt beide gleich.
|
|
5
5
|
*/
|
|
6
6
|
export const EINRICHTEN_MARKEN = {
|
|
7
|
-
de: { code: "Anmelde-Code:", adresse: "Adresse:", arbeitsplatz: "Arbeitsplatz:", werkbank: "Werkbank:", angemeldet: "Angemeldet als" },
|
|
8
|
-
en: { code: "Sign-in code:", adresse: "Address:", arbeitsplatz: "Workplace:", werkbank: "Workbench:", angemeldet: "Signed in as" },
|
|
7
|
+
de: { code: "Anmelde-Code:", adresse: "Adresse:", arbeitsplatz: "Arbeitsplatz:", werkbank: "Werkbank:", angemeldet: "Angemeldet als", plugins: "Plugins:", naechster: "Als Nächstes:", coach: "Coach:", alterKursCoach: "Alter Kurs-Coach:" },
|
|
8
|
+
en: { code: "Sign-in code:", adresse: "Address:", arbeitsplatz: "Workplace:", werkbank: "Workbench:", angemeldet: "Signed in as", plugins: "Plugins:", naechster: "Next:", coach: "Coach:", alterKursCoach: "Old course coach:" },
|
|
9
9
|
};
|
package/dist/texte/einrichten.js
CHANGED
|
@@ -5,31 +5,102 @@ const de = {
|
|
|
5
5
|
addressLine: (url) => ` ${M.de.adresse} ${url}`,
|
|
6
6
|
browserOpened: " Ich öffne die Seite gerade in deinem Browser. Bestätige dort nur, wenn derselbe Code dasteht.",
|
|
7
7
|
browserNotOpened: " Öffne die Adresse oben in deinem Browser. Bestätige dort nur, wenn derselbe Code dasteht.",
|
|
8
|
-
help: "\n kimal3 einrichten [--firma \"Name\" | --firma-id \"…\"]\n\n Meldet dich an (der Browser öffnet sich mit deinem Code),
|
|
8
|
+
help: "\n kimal3 einrichten [--firma \"Name\" | --firma-id \"…\"] [--arbeitsplatz \"<pfad>\"] [--werkbank <name>]\n\n Meldet dich an (der Browser öffnet sich mit deinem Code), sucht deinen\n KI-Arbeitsplatz oder legt ihn in deinem Benutzerordner an, richtet die\n /k3-Befehle und die Wache ein und hakt die Schritte im Kurs ab. Ein\n vorhandener Arbeitsplatz wird benutzt, nicht verändert.\n\n --arbeitsplatz wo dein Arbeitsplatz liegt oder neu entstehen soll\n --werkbank welche Werkbank darin deine ist\n",
|
|
9
9
|
start: "\nIch richte deinen KI-Arbeitsplatz ein.",
|
|
10
10
|
filesWritten: (neu, schonDa) => `\n✓ ${neu} Dateien angelegt, ${schonDa} lagen schon da.`,
|
|
11
11
|
workplaceLine: (pfad) => ` ${M.de.arbeitsplatz} ${pfad}`,
|
|
12
12
|
workbenchLine: (name) => ` ${M.de.werkbank} ${name}`,
|
|
13
|
+
// Was Sabine in der nächsten Sitzung schreibt (Spec 2026-10-16, Z-15): Steht die Anleitung für die erste
|
|
14
|
+
// Sitzung noch in ihrer Werkbank, der Startsatz der Vorlage; sonst der Befehl für jeden weiteren Tag.
|
|
15
|
+
nextLine: (offen) => ` ${M.de.naechster} ${offen ? "„Lass uns einrichten“" : "/k3start"}`,
|
|
16
|
+
// Vorhandener Arbeitsplatz (Spec 2026-10-16, „Neue Sätze“). Jede Rückfrage endet mit fertigen Befehlen.
|
|
17
|
+
foundWorkplace: (pfad) => `\nDein Arbeitsplatz liegt schon unter ${pfad} — ich benutze diesen.`,
|
|
18
|
+
severalFound: "\nIch habe mehrere Arbeitsplätze gefunden. Welchen soll ich benutzen?",
|
|
19
|
+
foreignFolder: (pfad) => `\nUnter ${pfad} liegt schon ein Ordner, der nicht von KImal3 stammt. Ich lege dort nichts ab.`,
|
|
20
|
+
searchIncomplete: "\nIch konnte nicht überall nachsehen. Hast du schon einen Arbeitsplatz?",
|
|
21
|
+
rememberedGone: (pfad) => `\nDein Arbeitsplatz lag unter ${pfad}, dort ist er nicht mehr. Wo liegt er jetzt?`,
|
|
22
|
+
noMatchingWorkbench: (pfad) => `\nIn ${pfad} finde ich keine Werkbank für dich.`,
|
|
23
|
+
confirmWorkbench: (name) => `\nIst ${name} deine Werkbank?`,
|
|
24
|
+
noWorkbenchInWorkplace: (pfad) => `\nIn ${pfad} gibt es noch keine Werkbank. Leg deine an und starte die Einrichtung danach noch einmal:`,
|
|
25
|
+
// Die Überschriften über den Befehlen der Rückfragen.
|
|
26
|
+
existingWorkplace: " Er liegt hier (Pfad einsetzen):",
|
|
27
|
+
newWorkplace: " Leg einen neuen an:",
|
|
28
|
+
otherPlace: " Nimm einen anderen Ort, leer oder mit deinem Arbeitsplatz:",
|
|
29
|
+
yes: " Ja:",
|
|
30
|
+
noOther: " Nein, es ist eine andere:",
|
|
31
|
+
oneOfThese: " Ist eine davon deine:",
|
|
32
|
+
ownWorkbench: " Noch keine eigene? Leg sie an und starte die Einrichtung danach noch einmal:",
|
|
33
|
+
pathPlaceholder: "<pfad>",
|
|
34
|
+
// Ein mitkopierter Platzhalter in `--arbeitsplatz` -- Claude fragt dann nach dem echten Ort.
|
|
35
|
+
placeholderPath: (wert) => `\n${wert} ist ein Platzhalter, kein Ordner. Setz dort den echten Pfad deines Arbeitsplatzes ein; ich habe nichts angelegt.`,
|
|
36
|
+
commandLine: (rest) => ` kimal3 ${rest}`,
|
|
37
|
+
cdLine: (pfad) => ` cd ${pfad}`,
|
|
13
38
|
courseMarked: "✓ Im Kurs abgehakt.",
|
|
14
39
|
courseNotMarked: " Die Haken im Kurs konnte ich gerade nicht setzen — der nächste Lauf holt das nach.",
|
|
15
40
|
done: "\n✓ Fertig eingerichtet.",
|
|
16
41
|
unsafeFolder: (name) => `Der Server hat einen Ordnernamen geschickt, den ich nicht anlege: ${name}. Bitte melde das an kimal3.`,
|
|
17
42
|
noWorkbank: "In der Lieferung steckt keine Werkbank. Bitte melde das an kimal3.",
|
|
43
|
+
// Plugins (Bauplan 2026-10-15): Claude liest die Zeile und sagt der Kundin, was nach dem Neustart erscheint.
|
|
44
|
+
logoName: "KImal3-Logo",
|
|
45
|
+
// `an`: eingeschaltet · `aus`: von ihr selbst ausgeschaltet (bleibt so, die Anleitung schickt sie dann nicht ins Menü)
|
|
46
|
+
// · `neu`: gerade eingetragen (kommt mit dem Neustart) oder stand schon da (Durchsicht-Funde 1 und 7).
|
|
47
|
+
pluginsLine: (an, aus, neu) => ` ${M.de.plugins} ${an.length > 0 ? `${an.join(", ")} — ${neu ? "erscheinen, sobald Claude ganz beendet und neu geöffnet ist" : "sind schon eingetragen"}.` : "nichts eingeschaltet."}` +
|
|
48
|
+
(aus.length > 0 ? ` Selbst ausgeschaltet, bleibt aus: ${aus.join(", ")}.` : ""),
|
|
49
|
+
pluginsNotWritten: (grund) => ` ${M.de.plugins} nicht eingetragen — ${grund}`,
|
|
50
|
+
settingsInvalid: "deine Claude-Einstellungen (~/.claude/settings.json) sind kein gültiges JSON. Ich habe sie nicht angefasst.",
|
|
51
|
+
settingsForeign: "in deinen Claude-Einstellungen (~/.claude/settings.json) steht etwas in einer Form, die ich nicht kenne. Ich habe sie nicht angefasst.",
|
|
52
|
+
settingsFailed: (ursache) => `deine Claude-Einstellungen (~/.claude/settings.json): ${ursache}.`,
|
|
53
|
+
// Logo (Durchsicht 2, Funde 1 und 3): Scheitert der Ordner, kommt superpowers trotzdem; hält Claude ihn fest, gilt die alte Fassung.
|
|
54
|
+
logoNotWritten: (detail) => ` Den Ordner für das KImal3-Logo konnte ich nicht anlegen oder erneuern (${detail}).`,
|
|
55
|
+
// Ohne Git kein superpowers (Durchsicht 3, Fund 5); die Anleitung zitiert den Anfang dieser Zeile.
|
|
56
|
+
superpowersNeedsGit: " superpowers braucht Git — es kommt mit dem nächsten `kimal3 einrichten`, sobald Git da ist.",
|
|
57
|
+
logoOldVersion: " Das KImal3-Logo bleibt vorerst in der bisherigen Fassung, weil Claude den Ordner gerade benutzt. Beende Claude ganz und starte danach `kimal3 einrichten` noch einmal.",
|
|
18
58
|
};
|
|
19
59
|
const en = {
|
|
20
60
|
codeLine: (code) => `\n ${M.en.code} ${code}`,
|
|
21
61
|
addressLine: (url) => ` ${M.en.adresse} ${url}`,
|
|
22
62
|
browserOpened: " Opening the page in your browser now. Only confirm there if it shows the same code.",
|
|
23
63
|
browserNotOpened: " Open the address above in your browser. Only confirm there if it shows the same code.",
|
|
24
|
-
help: "\n kimal3 setup [--company \"Name\" | --company-id \"…\"]\n\n Signs you in (your browser opens with your code),
|
|
64
|
+
help: "\n kimal3 setup [--company \"Name\" | --company-id \"…\"] [--workplace \"<path>\"] [--workbench <name>]\n\n Signs you in (your browser opens with your code), finds your AI Workplace\n or creates it in your user folder, sets up the /k3 commands and the watch,\n and ticks off the course steps. An existing workplace is used, not changed.\n\n --workplace where your workplace is, or where a new one should go\n --workbench which workbench in it is yours\n",
|
|
25
65
|
start: "\nSetting up your AI Workplace.",
|
|
26
66
|
filesWritten: (neu, schonDa) => `\n✓ ${neu} files created, ${schonDa} were already there.`,
|
|
27
67
|
workplaceLine: (pfad) => ` ${M.en.arbeitsplatz} ${pfad}`,
|
|
28
68
|
workbenchLine: (name) => ` ${M.en.werkbank} ${name}`,
|
|
69
|
+
// The start sentence of the English template (workbench-your-name/CLAUDE.md, anleitung-en.ts) -- exactly that one.
|
|
70
|
+
nextLine: (offen) => ` ${M.en.naechster} ${offen ? "“Let's get set up”" : "/k3start"}`,
|
|
71
|
+
foundWorkplace: (pfad) => `\nYour workplace already exists at ${pfad} — I'll use that one.`,
|
|
72
|
+
severalFound: "\nI found more than one workplace. Which one should I use?",
|
|
73
|
+
foreignFolder: (pfad) => `\nThere's already a folder at ${pfad} that doesn't come from KImal3. I won't put anything there.`,
|
|
74
|
+
searchIncomplete: "\nI couldn't look everywhere. Do you already have a workplace?",
|
|
75
|
+
rememberedGone: (pfad) => `\nYour workplace was at ${pfad} and isn't there anymore. Where is it now?`,
|
|
76
|
+
noMatchingWorkbench: (pfad) => `\nI can't find a workbench for you in ${pfad}.`,
|
|
77
|
+
confirmWorkbench: (name) => `\nIs ${name} your workbench?`,
|
|
78
|
+
noWorkbenchInWorkplace: (pfad) => `\nThere's no workbench in ${pfad} yet. Create yours, then run the setup again:`,
|
|
79
|
+
existingWorkplace: " It's here (fill in the path):",
|
|
80
|
+
newWorkplace: " Create a new one:",
|
|
81
|
+
otherPlace: " Choose another place, empty or with your workplace in it:",
|
|
82
|
+
yes: " Yes:",
|
|
83
|
+
noOther: " No, it's another one:",
|
|
84
|
+
oneOfThese: " If one of these is yours:",
|
|
85
|
+
ownWorkbench: " None of your own yet? Create it, then run the setup again:",
|
|
86
|
+
pathPlaceholder: "<path>",
|
|
87
|
+
placeholderPath: (wert) => `\n${wert} is a placeholder, not a folder. Put the real path of your workplace there; I haven't created anything.`,
|
|
88
|
+
commandLine: (rest) => ` kimal3 ${rest}`,
|
|
89
|
+
cdLine: (pfad) => ` cd ${pfad}`,
|
|
29
90
|
courseMarked: "✓ Ticked off in the course.",
|
|
30
91
|
courseNotMarked: " I couldn't tick off the course steps just now — the next run will catch up.",
|
|
31
92
|
done: "\n✓ All set up.",
|
|
32
93
|
unsafeFolder: (name) => `The server sent a folder name I won't create: ${name}. Please report this to kimal3.`,
|
|
33
94
|
noWorkbank: "The delivery contains no workbench. Please report this to kimal3.",
|
|
95
|
+
logoName: "KImal3 logo",
|
|
96
|
+
pluginsLine: (an, aus, neu) => ` ${M.en.plugins} ${an.length > 0 ? `${an.join(", ")} — ${neu ? "will appear once Claude is fully quit and reopened" : "already added"}.` : "nothing switched on."}` +
|
|
97
|
+
(aus.length > 0 ? ` Switched off by you, stays off: ${aus.join(", ")}.` : ""),
|
|
98
|
+
pluginsNotWritten: (grund) => ` ${M.en.plugins} not added — ${grund}`,
|
|
99
|
+
settingsInvalid: "your Claude settings (~/.claude/settings.json) are not valid JSON. I left them untouched.",
|
|
100
|
+
settingsForeign: "your Claude settings (~/.claude/settings.json) contain something in a form I don't know. I left them untouched.",
|
|
101
|
+
settingsFailed: (ursache) => `your Claude settings (~/.claude/settings.json): ${ursache}.`,
|
|
102
|
+
logoNotWritten: (detail) => ` I couldn't create or renew the folder for the KImal3 logo (${detail}).`,
|
|
103
|
+
superpowersNeedsGit: " superpowers needs Git — it comes with the next `kimal3 setup` once Git is there.",
|
|
104
|
+
logoOldVersion: " The KImal3 logo stays on its previous version for now, because Claude is using the folder. Quit Claude completely, then run `kimal3 setup` again.",
|
|
34
105
|
};
|
|
35
106
|
export const EINRICHTEN_TEXTE = { de, en };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const de = {
|
|
2
|
+
beatFertig: (nummer) => `Beat ${nummer} ✓`,
|
|
3
|
+
beatTeil: (nummer, erledigt, gesamt) => `Beat ${nummer} — ${erledigt} von ${gesamt}`,
|
|
4
|
+
uebersicht: (beats) => `Kurs: ${beats}`,
|
|
5
|
+
alleErledigt: (anzahl) => `Kurs: abgeschlossen ✓ — alle ${anzahl} Schritte erledigt.`,
|
|
6
|
+
naechster: (text, claude) => `Als Nächstes: ${text} (${claude ? "setzt Claude" : "du hakst ab"})`,
|
|
7
|
+
nochOffen: "Noch offen:",
|
|
8
|
+
offenZeile: (beat, text, claude) => ` ○ Beat ${beat}: ${text} (${claude ? "setzt Claude" : "du hakst ab"})`,
|
|
9
|
+
imBrowser: (url) => `Im Browser: ${url}/kurs`,
|
|
10
|
+
};
|
|
11
|
+
const en = {
|
|
12
|
+
beatFertig: (nummer) => `Part ${nummer} ✓`,
|
|
13
|
+
beatTeil: (nummer, erledigt, gesamt) => `Part ${nummer} — ${erledigt} of ${gesamt}`,
|
|
14
|
+
uebersicht: (beats) => `Course: ${beats}`,
|
|
15
|
+
alleErledigt: (anzahl) => `Course: complete ✓ — all ${anzahl} steps done.`,
|
|
16
|
+
naechster: (text, claude) => `Next: ${text} (${claude ? "Claude sets it" : "you tick it off"})`,
|
|
17
|
+
nochOffen: "Still open:",
|
|
18
|
+
offenZeile: (beat, text, claude) => ` ○ Part ${beat}: ${text} (${claude ? "Claude sets it" : "you tick it off"})`,
|
|
19
|
+
imBrowser: (url) => `In the browser: ${url}/kurs`,
|
|
20
|
+
};
|
|
21
|
+
export const KURS_TEXTE = { de, en };
|
package/dist/wache-schalter.js
CHANGED
|
@@ -32,6 +32,8 @@ export function leseWacheDatei() {
|
|
|
32
32
|
if (Array.isArray(inhalt.sitzungen)) {
|
|
33
33
|
raus.sitzungen = inhalt.sitzungen.filter((s) => typeof s === "string");
|
|
34
34
|
}
|
|
35
|
+
if (typeof inhalt.eingerichtet === "string")
|
|
36
|
+
raus.eingerichtet = inhalt.eingerichtet;
|
|
35
37
|
return raus;
|
|
36
38
|
}
|
|
37
39
|
catch {
|
|
@@ -116,6 +118,22 @@ export function merkeSitzung(sitzung) {
|
|
|
116
118
|
return;
|
|
117
119
|
schreibeWacheDatei(mitSitzung(leseWacheDatei() ?? {}, sitzung));
|
|
118
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Merken, in welcher Claude-Sitzung die Wache gerade eingetragen wurde. Wirft nie.
|
|
123
|
+
*
|
|
124
|
+
* 🔴 NICHT `merkeSitzung` (Sandbox-Lauf 14.10., Befund S-3): Der Eintrag greift erst beim
|
|
125
|
+
* naechsten Start -- ohne Merkzettel meldete der naechste Befehl in derselben Sitzung sofort
|
|
126
|
+
* "hat nicht nachgesehen". Bis 0.4.0-durchstich.1 stempelte `skill install` deshalb die
|
|
127
|
+
* Sitzung als NACHGESEHEN. Das hielt den Fehlalarm still, aber auch die Wache selbst: Wer im
|
|
128
|
+
* selben Gespraech weitermacht, hoerte sie am ersten Tag nie (gemessen: das Pro-Angebot lag
|
|
129
|
+
* bereit, `cli_nachrichten_gezeigt` blieb leer). Ein eigenes Feld trennt beides --
|
|
130
|
+
* `wacheAusgefallen` liest es, `schonFuerDieseSitzung` nicht.
|
|
131
|
+
*/
|
|
132
|
+
export function merkeEinrichtung(sitzung) {
|
|
133
|
+
if (sitzung === null)
|
|
134
|
+
return;
|
|
135
|
+
schreibeWacheDatei({ ...(leseWacheDatei() ?? {}), eingerichtet: sitzung });
|
|
136
|
+
}
|
|
119
137
|
/** Wie viele Sitzungen der Merkzettel sich merkt -- genug fuer mehrere Fenster ueber Tage. */
|
|
120
138
|
const MERKE_SITZUNGEN = 20;
|
|
121
139
|
/**
|
|
@@ -171,7 +189,10 @@ function gesehen(inhalt, jetzt) {
|
|
|
171
189
|
* Terminalfenster tippt, will die Antwort jetzt -- ein Merkzettel von gestern
|
|
172
190
|
* darf ihn nicht zum Schweigen bringen.
|
|
173
191
|
*/
|
|
174
|
-
export function schonFuerDieseSitzung(
|
|
192
|
+
export function schonFuerDieseSitzung(
|
|
193
|
+
// `eingerichtet` steht im Typ, damit der ganze Merkzettel hereinpasst -- gelesen wird es
|
|
194
|
+
// hier ABSICHTLICH nicht: Eingerichtet heisst nicht nachgesehen (S-3, `merkeEinrichtung`).
|
|
195
|
+
inhalt, jetzt) {
|
|
175
196
|
return jetzt !== null && inhalt !== null && gesehen(inhalt, jetzt);
|
|
176
197
|
}
|
|
177
198
|
/**
|
|
@@ -186,9 +207,13 @@ export function schonFuerDieseSitzung(inhalt, jetzt) {
|
|
|
186
207
|
* dann aus wie an einem guten Tag. *Eine Wache, die still stirbt, ist
|
|
187
208
|
* schlimmer als keine: Sie kauft Vertrauen und deckt nichts mehr.*
|
|
188
209
|
*
|
|
189
|
-
* 🔴
|
|
210
|
+
* 🔴 FUENF MAL SCHWEIGEN, EINMAL SPRECHEN:
|
|
190
211
|
* - Keine Sitzungsnummer -> der Mensch sitzt im Terminalfenster, die Wache
|
|
191
212
|
* hatte nie einen Anlass zu laufen. "Nicht gelaufen" heisst hier nichts.
|
|
213
|
+
* - Kein Merkzettel -> die Wache war nie eingerichtet; `skill install` legt ihn an.
|
|
214
|
+
* Bis 0.4.0-durchstich.1 meldete das hier -- die allererste Ausgabe einer neuen
|
|
215
|
+
* Kundin war ein Fehlalarm (Sandbox-Lauf 14.10., Befund S-2).
|
|
216
|
+
* - In dieser Sitzung eingerichtet -> sie greift erst beim naechsten Start (S-3).
|
|
192
217
|
* - Abgeschaltet -> wer `kimal3 wache aus` getippt hat, will nicht taeglich
|
|
193
218
|
* daran erinnert werden. Sonst waere der Ausschalter keiner.
|
|
194
219
|
* - Dieselbe Nummer -> sie hat fuer diese Sitzung nachgesehen.
|
|
@@ -201,9 +226,9 @@ export function wacheAusgefallen(
|
|
|
201
226
|
// Fassung traegt genau das und sonst nichts, und dieser Fall gehoert
|
|
202
227
|
// geprueft. Ein Typ, der ihn verbietet, verbietet auch seine Pruefung.
|
|
203
228
|
inhalt, jetzt) {
|
|
204
|
-
if (jetzt === null)
|
|
229
|
+
if (jetzt === null || inhalt === null)
|
|
205
230
|
return false;
|
|
206
|
-
if (inhalt
|
|
231
|
+
if (inhalt.aus === true)
|
|
207
232
|
return false;
|
|
208
|
-
return
|
|
233
|
+
return !gesehen(inhalt, jetzt) && inhalt.eingerichtet !== jetzt;
|
|
209
234
|
}
|
package/package.json
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "kimal3",
|
|
3
|
-
"version": "0.4.0
|
|
4
|
-
"description": "Trag deine KI-Projekte dort ein, wo sie entstehen: im Terminal. · Log your AI projects where they happen: in the terminal.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"kimal3": "dist/kimal3.js"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"dist",
|
|
11
|
-
"skill",
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "kimal3",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Trag deine KI-Projekte dort ein, wo sie entstehen: im Terminal. · Log your AI projects where they happen: in the terminal.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"kimal3": "dist/kimal3.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"skill",
|
|
12
|
+
"claude-plugins",
|
|
13
|
+
"coach",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=20"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json",
|
|
21
|
+
"prepublishOnly": "npm run build"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"kimal3",
|
|
25
|
+
"cli"
|
|
26
|
+
],
|
|
27
|
+
"homepage": "https://app.kimal3.de/pro",
|
|
28
|
+
"license": "SEE LICENSE IN README.md"
|
|
29
|
+
}
|
package/skill/SKILL.md
CHANGED
|
@@ -24,7 +24,7 @@ den du erkennst.
|
|
|
24
24
|
| `/k3` | Wo er steht — und alle kimal3-Befehle auf einen Blick |
|
|
25
25
|
| `/k3start` | Sitzung starten: wo das Projekt steht und was als Nächstes dran ist |
|
|
26
26
|
| `/k3feierabend` | Sitzung sauber beenden: Stand sichern, aufräumen, zusammenfassen |
|
|
27
|
-
| `/k3kurs` | Zurück in den Mini-Kurs — da weiter, wo er aufgehört hat |
|
|
27
|
+
| `/k3kurs` | Zurück in den Mini-Kurs — holt den Stand mit `kimal3 kurs` und macht da weiter, wo er aufgehört hat |
|
|
28
28
|
| `/k3projekt` | Ein fertiges Projekt ins Erfolgsprofil eintragen |
|
|
29
29
|
| `/k3liste` | Seine eingetragenen Projekte zeigen |
|
|
30
30
|
| `/k3analyse` | Firmendaten holen und seine Frage dazu beantworten |
|
|
@@ -158,8 +158,7 @@ gemeinsam ausfüllen — es sind vier verschiedene. Such nach eckigen Klammern,
|
|
|
158
158
|
zu folgen: Eine abgetippte Liste veraltet in dem Moment, in dem die Vorlage wächst. Frag nach,
|
|
159
159
|
statt zu raten.
|
|
160
160
|
|
|
161
|
-
⚠️ `[FIRMA]` findest du meist schon ausgefüllt — den Namen setzt der Server beim Ausliefern ein.
|
|
162
|
-
`[DATUM]` ebenso. Was übrig bleibt, sind die Angaben über den **Menschen** vor dir.
|
|
161
|
+
⚠️ `[FIRMA]` findest du meist schon ausgefüllt — den Namen setzt der Server beim Ausliefern ein. Was übrig bleibt, sind die Angaben über den **Menschen** vor dir.
|
|
163
162
|
|
|
164
163
|
🔴 **Nur in der Werkbank — nirgends sonst.** Die oberste `CLAUDE.md` und alles in `kontext/` (in einer englischen Firma `context/`)
|
|
165
164
|
gehören der **Firma**, nicht dem Menschen vor dir. Den Firmennamen setzt der Server beim
|
|
@@ -360,6 +359,11 @@ mitbestimmungspflichtig. Das entscheidet die Firma, nicht dieses Werkzeug.
|
|
|
360
359
|
- „Was würdest du als Geschäftsführung als Nächstes automatisieren, gemessen an dem, was bisher
|
|
361
360
|
funktioniert hat — und was davon lässt sich auf andere Abteilungen übertragen?"
|
|
362
361
|
|
|
362
|
+
## Kursstand lesen (`kimal3 kurs`)
|
|
363
|
+
Zeigt, wo der Mensch im Mini-Kurs steht: eine Zeile je Beat, `Als Nächstes:` mit dem nächsten Schritt und dahinter, wer
|
|
364
|
+
ihn abhakt — „(du hakst ab)" oder „(setzt Claude)". Rückgabewert `2` heißt nicht angemeldet, `3` nicht erreichbar —
|
|
365
|
+
dann **keinen Kurs aus dem Gedächtnis erzählen**. Der Slash-Befehl `/k3kurs` führt dadurch.
|
|
366
|
+
|
|
363
367
|
## Rückgabewerte
|
|
364
368
|
`0` erledigt · `1` **Wiederholen hilft nicht — LIES DIE MELDUNG** · `2` Anmeldung fehlt ·
|
|
365
369
|
`3` vorübergehende Störung, einmal wiederholen · `4` angemeldet, aber kein Pro-Zugang —
|
|
@@ -24,10 +24,9 @@ Die Status-Datei (`WEITER-HIER.md` oder `ROADMAP.md`) ist der Zettel für den n
|
|
|
24
24
|
taugt nur, solange man sie in einem Atemzug lesen kann. **Jeder Feierabend schreibt etwas dazu —
|
|
25
25
|
also muss auch jeder Feierabend etwas wegräumen**, sonst wächst sie, bis niemand sie mehr liest.
|
|
26
26
|
|
|
27
|
-
**
|
|
27
|
+
**Wo der Statuszettel liegt und wie er heißt.** Die Projektregel gilt **nur innerhalb eines Arbeitsplatzes**: Liegt ein Ordner `projekte/` oder `projects/` direkt in einem Ordner `werkbank-…` oder `workbench-…` (beide Schreibweisen kommen vor, auch gemischt) und steht die Sitzung in oder unter einem Ordner darin, ist dieser **Projektordner** der Ort. Name dort: unter `projekte/` `WEITER-HIER.md`, unter `projects/` `NEXT-STEPS.md`. **Überall sonst** (Starter-Paket, eigene Repos, auch ein Ordner `~/projects/mein-repo`) bleibt es wie bisher: Der Zettel liegt im Startordner, liegt einer da, nimm ihn; muss einer neu entstehen, heißt er `WEITER-HIER.md` — oder `NEXT-STEPS.md`, wenn der Ordner englisch angelegt wurde. Liegen beide da, frag, welcher gilt, und schreib in keinen, bevor die Antwort da ist. **Welcher gilt (im Arbeitsplatz):** Hat das Projekt einen, gilt der des Projekts. Sonst gilt ein vorhandener Werkbank-Zettel (`werkbank-…/WEITER-HIER.md` oder `workbench-…/NEXT-STEPS.md` aus der alten Vorlage) — den liest und pflegst du weiter. Gibt es keinen von beiden, entsteht er **im Projekt**. **Leg nie einen neuen Zettel in der Werkbank an.**
|
|
28
28
|
|
|
29
|
-
Gibt es keine Status-Datei und die Arbeit wächst über eine Sitzung hinaus
|
|
30
|
-
dann weiter mit Schritt 3.
|
|
29
|
+
**Im Arbeitsplatz** schreibst du in den Zettel des Projekts, an dem heute gearbeitet wurde — fehlt er und liegt auch kein Werkbank-Zettel, leg ihn im Projekt an. **Nach einer reinen Profil-Sitzung** („Wer hier arbeitet“ ausgefüllt, noch kein Projekt) schreibst du **keinen** Zettel, sondern sagst, dass es beim nächsten Mal mit „Erste Sitzung“ in der Werkbank-`CLAUDE.md` weitergeht — dann weiter mit Schritt 3. **Außerhalb eines Arbeitsplatzes** gilt wie bisher: Gibt es keine Status-Datei und die Arbeit wächst über eine Sitzung hinaus, schlag eine vor, dann weiter mit Schritt 3.
|
|
31
30
|
|
|
32
31
|
1. **Nachziehen:** „Wo wir stehen" und „nächster Schritt" auf das setzen, was heute passiert ist.
|
|
33
32
|
2. **Wegräumen, was nicht mehr gilt.** Ins Archiv wandert:
|