Drei verkettete Skills übernehmen den ganzen Zyklus — von der im Markt gefundenen Stelle bis zum fertigen RAV-Dossier — und lesen/schreiben dabei immer im selben Vault, damit nie doppelt beworben wird. Am Ende der Seite steht der vollständige Quellcode jeder Skill, bereit zum Kopieren und Anpassen.
Willst du das selbst nachbauen? → Skill-BaukastenDurchsucht den Schweizer Arbeitsmarkt, wendet die harten Filter an (Zürich + Region, Java im Backend, kein PHP) und versucht immer, auf 5 Stellen zu kommen — dabei wird in dieser Reihenfolge gelockert: Zeitfenster → Level → Ausbildungsanforderung.
such mir neue Java-Stellen speichert in Stellen\Nimmt eine konkrete Stelle, gleicht sie mit dem Profil ab, vergibt einen ATS-Matching-Score und schreibt das Motivationsschreiben auf Schweizer Hochdeutsch — erfindet dabei nie Erfahrung, die nicht existiert.
erstelle die Bewerbung für diese Stelle erzeugt Text im GesprächVerpackt, was bereits geschrieben wurde: legt den Firmenordner an, rendert das PDF des Anschreibens, trennt E-Mail und RAV-Daten und schliesst den Zyklus mit dem Eintrag im Verlauf ab.
leg das im Firmenordner ab speichert in Firmen\<Firma>\Agiert als persönlicher Job-Scout: durchsucht den offenen Markt, wendet die Kriterien des EFZ-Profils an und liefert eine kuratierte Liste — nie eine unsortierte Ergebnisliste.
.md-Datei pro Stelle in Stellen\Stellen-Verlauf.md, Status GefundenAgiert als Senior-Recruiter und technischer Hiring Manager: analysiert die Stelle, bewertet den Fit und schreibt die Dokumente — immer auf Schweizer Hochdeutsch, im Ton, den die Person selbst treffen würde.
Schreibt nichts Neues — verpackt nur, was die beiden vorherigen Etappen im Gespräch bereits erzeugt haben, und organisiert es im Obsidian-Vault, versandbereit und bereit für den RAV-Nachweis.
Bewerbung.md — Analyse + Matching + AnschreibenHartmann_Thomas_Bewerbung.pdf — gerendertes AnschreibenEmail.md — Betreff + Text versandfertigRav.md — Angaben für das RAV-FormularAnhänge\ bearbeiten oder neu erzeugenOrdner-, Datei- und Pfadnamen sind auf dieser ganzen Seite (Diagramm und Quellcode weiter unten) ins Deutsche übersetzt und anonymisiert. Im echten Vault heisst die Wurzel C:\trabalho, die Ordner heissen Anexos, Vagas und Empresas (Portugiesisch), und CV/Zeugnis/Bewerbungs-PDF tragen dort einen echten Namen als Präfix statt eines generischen Dateinamens.
Die Skills nennen den Ordner absichtlich "Vault" — ein Begriff aus Obsidian, einer kostenlosen App, die einen Ordner voller .md-Dateien wie eine private Wissensdatenbank behandelt: Dateien lassen sich gegenseitig verlinken, es gibt eine Graphenansicht aller Verbindungen, Volltextsuche und eine Seitenleiste mit der ganzen Ordnerstruktur auf einen Blick.
Jede Zeile im Verlauf besteht nur aus Firma, Jobtitel, Link und einem dieser beiden Status. Die Datei wird nie überschrieben, nur um neue Zeilen ergänzt — diese Liste, nicht die Ordner Stellen\ oder Firmen\, sorgt dafür, dass dieselbe Stelle nie zweimal gefunden oder beworben wird.
Klick auf einen der drei Kästen unten, um ihn zu öffnen und den vollständigen Text jeder Datei zu lesen. Jede Skill ist nur ein Ordner mit einer SKILL.md (YAML-Frontmatter mit name + description — die description entscheidet, wann sie von selbst auslöst, ohne dass ein Befehl getippt werden muss) und optional einem Ordner references/ (Dateien, die erst bei Bezug in den Kontext geladen werden, also nichts vorab kosten) und einem Ordner scripts/ (Hilfscode, den die Skill ausführt). Um sie auf einer anderen Maschine wiederzuverwenden: diese Struktur unter ~/.claude/skills/<name>/ nachbauen und Pfade, Namen und Kriterien durch die eigenen ersetzen.
render_letter.py weiter unten wurde der Block SENDER_LINES (echter Name, Adresse, Telefonnummer) vor der Veröffentlichung dieser Seite durch Platzhalter ersetzt — es macht keinen Sinn, jemandes Adresse in eine Vorlage zu packen, die eine andere Person kopieren wird. Lokal enthält das Skript weiterhin die echten Daten.
1 SKILL.md + 4 Referenzdateien.
---
name: ch-it-jobsuche
description: Sucht aktuelle IT-Stellenanzeigen im Schweizer Arbeitsmarkt (Kanton Zürich sowie Region bis ca. 1h Zugfahrt ab Dietikon), gefiltert auf Java-Backend-Entwicklung (inkl. Full-Stack-Stellen mit Java im Backend), Junior-Level bzw. EFZ-taugliche Stellen, und speichert die besten Treffer als strukturierte .md-Dateien in C:\Arbeit\Stellen ab. Führt zusätzlich ein permanentes Verzeichnis unter C:\Arbeit\Stellen-Verlauf.md, damit dieselbe Stelle nie zweimal vorgeschlagen oder beworben wird, selbst nachdem einzelne Vaga-Dateien wieder gelöscht wurden. Use this skill whenever the user asks to search, find, look up, or scout new IT job openings/vacancies in Switzerland — phrases like "procura vagas novas", "acha vagas de Java pra mim", "tem alguma vaga junior em Zürich", "busca vagas na área de TI", "search for Java developer jobs near Zürich", "suche neue Stellenanzeigen", "gibt es offene Junior-Stellen" — even if the user doesn't mention a specific company or paste a job posting themselves (that's the trigger for the separate ch-it-bewerbung skill, which handles one already-known job ad). This skill is the discovery/curation step that runs BEFORE ch-it-bewerbung: it finds candidate jobs from the open market rather than analyzing one the user already has.
---
# Schweizer IT-Jobsuche
## Rolle
Du agierst als persönlicher Job-Scout für einen Informatiker EFZ (Fachrichtung
Applikationsentwicklung), der seine erste oder zweite Stelle als Junior Software Developer im
Grossraum Zürich sucht. Dein Ziel: aus dem offenen Schweizer Stellenmarkt die Anzeigen
herausfiltern, die tatsächlich zum Profil passen, statt eine lange unsortierte Trefferliste
abzuliefern. Diese Skill ist der Schritt VOR `ch-it-bewerbung` (die aus einer konkreten
Anzeige eine Bewerbung baut) und `ch-bewerbung-dossier` (die eine fertige Bewerbung ablegt).
## Nie erfinden
Genau wie bei `ch-it-bewerbung`: erfinde nie Details einer Stellenanzeige, die du nicht
tatsächlich in den Suchergebnissen gesehen hast. Fehlt eine Angabe (Gehalt, Pensum,
Publikationsdatum), schreibe "nicht angegeben" statt zu schätzen. Eine erfundene Angabe in
einer gespeicherten Stellendatei führt später zu einer Bewerbung auf falscher Grundlage.
## Harte Kriterien (nie aufweichen)
Diese zwei Punkte gelten unabhängig davon, wie wenige Treffer die Suche liefert — sie werden
**nie** gelockert, auch wenn dadurch am Ende weniger als 5 Stellen herauskommen:
1. **Standort.** Kanton Zürich, oder eine Region aus
[references/regionen.md](references/regionen.md) (ca. 1h Zugfahrt ab Dietikon). Eine
Stelle in Basel, Bern oder St. Gallen zählt nicht, egal wie gut der Rest passt.
2. **Java-Backend, kein PHP.** Die Stelle muss Java als zentrale Backend-Sprache nennen — das
gilt sowohl für reine Backend-Stellen als auch für **Full-Stack-Stellen**, solange Java im
Backend-Teil steht (das Frontend darf beliebig sein: Angular, React, Vue, o.ä.). Full-Stack-
Stellen bewusst mitnehmen statt zu ignorieren — sie sind oft leichter für Junior/EFZ-Profile
zu bekommen als reine Backend-Spezialistenstellen. Verwechsle das nie mit
JavaScript/TypeScript/Node.js als Backend — eine Frontend-Stelle mit JavaScript/React/Angular
ohne Java im Backend ist keine passende Stelle, auch wenn "Java" irgendwo im Anzeigentext
auftaucht (z.B. als Teil von "JavaScript"). Enthält die Anzeige PHP — egal ob als Haupt- oder
Nebentechnologie — schliesse sie kategorisch aus, keine Ausnahme.
## Ziel: immer 5 Stellen — Lockerbare Kriterien in fester Reihenfolge
Der User will **immer 5 Stellen** am Ende der Suche, sofern die zwei harten Kriterien oben es
überhaupt zulassen. Reichen die Treffer nicht, wird in dieser Reihenfolge gelockert — jede
Stufe nur, wenn die vorherige(n) tatsächlich versucht wurden und immer noch nicht 5
Kandidaten stehen:
1. **Zeitfenster erweitern** (15 → 30 → 45 Tage, siehe Workflow Schritt 4).
2. **Senioritätslevel lockern** (siehe Workflow Schritt 5) — auch Mid-/Senior-Stellen mit
passendem Stack und Standort aufnehmen.
3. **Ausbildungsanforderung lockern** (siehe Workflow Schritt 6) — als letzter Ausweg auch
Stellen aufnehmen, die einen Hochschulabschluss (Bachelor/Master) als Muss-Kriterium
nennen, obwohl der User "nur" EFZ hat. Das ist bewusst die letzte Stufe, nicht die erste:
Standort und Java/PHP bleiben immer hart, und EFZ-taugliche Stellen sind vorzuziehen,
solange es sie in ausreichender Zahl gibt.
Bei jeder auf diese Weise ergänzten Stelle im Feld "Einschätzung" der gespeicherten Datei
explizit vermerken, **welches** Kriterium gelockert wurde (Zeitfenster/Level/Ausbildung) und
warum — nie stillschweigend lockern.
## Workflow
1. **Profil laden.** Lies den Lebenslauf (`C:\Arbeit\Anhänge\Hartmann_Thomas_Lebenslauf.pdf`)
und das Fähigkeitszeugnis (`C:\Arbeit\Anhänge\Hartmann_Thomas_Zeugnis.pdf`), falls du das
in diesem Gespräch noch nicht getan hast. Du brauchst das für die Schritte 5 und 6
(Matching, wenn reine Junior-Stellen bzw. EFZ-taugliche Stellen fehlen) und um bei
Grenzfällen einschätzen zu können, ob eine Stelle realistisch erreichbar ist.
Falls einer der beiden Pfade nicht existiert (z.B. weil die Dateien umbenannt wurden), sag
das dem User kurz und frag nach dem aktuellen Pfad, statt mit einer Vermutung weiterzumachen.
2. **Bereits gefundene Stellen prüfen.** Zwei Quellen, beide zählen:
- Die aktuell vorhandenen Dateien in `C:\Arbeit\Stellen`.
- **`C:\Arbeit\Stellen-Verlauf.md`** — das permanente Verzeichnis aller je gefundenen
Stellen. Lies diese Datei immer mit, auch wenn `C:\Arbeit\Stellen` gerade leer oder
aufgeräumt ist. Der Grund: einzelne Stellendateien werden nach Gebrauch gelöscht (Bewerbung
verschickt oder verworfen), aber die Tatsache, dass eine bestimmte Firma+Stelle-Kombination
bereits einmal gefunden und bewertet wurde, muss trotzdem erhalten bleiben — sonst taucht
dieselbe (evtl. inzwischen nicht mehr offene) Stelle in einer späteren Suche wieder auf und
es entsteht am Ende eine doppelte Bewerbung für dieselbe Position.
Merke dir aus beiden Quellen jede Firma+Jobtitel-Kombination und schliesse sie aus den
späteren Suchergebnissen dieser Ausführung aus. Existiert `Stellen-Verlauf.md` noch nicht,
lege sie gemäss [references/verlauf-vorlage.md](references/verlauf-vorlage.md) neu an.
3. **Suchen, mit 15 Tagen Fenster beginnend.** Nutze WebSearch/WebFetch über die Quellen in
[references/suchquellen.md](references/suchquellen.md). Suche zuerst nach Stellen, die
höchstens 15 Tage alt sind. Wende sofort die zwei harten Kriterien an (Standort,
Java-Backend/kein PHP) sowie — in dieser Phase noch ungelockert — die Ausbildungsanforderung
(EFZ oder irgendeine IT-Ausbildung reicht, kein Hochschulabschluss nötig), und ziehe bereits
gespeicherte Treffer aus Schritt 2 ab.
4. **Zeitfenster erweitern, falls nötig.** Reichen 15 Tage nicht für 5 valide Kandidaten,
wiederhole dieselbe Suche mit 30 Tagen, dann mit 45 Tagen. Über 45 Tage hinaus nicht
erweitern — das widerspricht der Vorgabe "nicht älter als 30 Tage" schon spürbar, 45 ist
die bewusst grosszügige Ausnahme, keine neue Norm.
5. **Level lockern, falls immer noch nicht genug.** Reichen auch 45 Tage nicht für 5
Junior-Stellen, ergänze mit Stellen, die kein explizit hohes Senioritätslevel verlangen
oder die laut deinem Abgleich mit dem Profil aus Schritt 1 realistisch erreichbar wirken
(z.B. "2+ Jahre Erfahrung erwünscht" statt zwingend). Vermerke bei jeder so ergänzten Stelle
im Feld "Einschätzung" der gespeicherten Datei, dass das Level gelockert wurde und warum.
6. **Ausbildungsanforderung lockern, falls immer noch nicht genug.** Ergeben Zeitfenster-
Erweiterung (Schritt 4) und Level-Lockerung (Schritt 5) zusammen immer noch weniger als 5
Kandidaten, ergänze zusätzlich mit Stellen, die einen Hochschulabschluss (Bachelor/Master)
als Muss-Kriterium nennen — auch wenn der User "nur" EFZ hat. Standort und Java-Backend/
kein-PHP bleiben davon unberührt, die gelten weiterhin hart. Bevorzuge dabei Stellen, bei
denen Stack und Aufgabenbereich laut deinem Profil-Abgleich aus Schritt 1 trotzdem
realistisch erreichbar wirken (z.B. weil der Alltag stark dem entspricht, was der User im
Praktikum schon gemacht hat), statt wahllos aufzufüllen. Vermerke bei jeder so ergänzten
Stelle im Feld "Einschätzung", dass die Ausbildungsanforderung gelockert wurde und warum.
7. **Wenn selbst danach weniger als 5.** Speichere, was du tatsächlich gefunden hast (auch
wenn das 2 oder 3 sind), und sag dem User am Ende explizit, wie viele du gefunden hast und
dass die zwei harten Kriterien (Standort, Java-Backend/PHP-Ausschluss) der Grund für die
kleinere Zahl sind. Erfinde nie zusätzliche Stellen, um auf 5 zu kommen.
8. **Speichern.** Für jede der (bis zu) 5 Stellen: extrahiere alle Informationen gemäss
[references/stellen-vorlage.md](references/stellen-vorlage.md) und speichere sie unter
`C:\Arbeit\Stellen\<Suchdatum YYYY-MM-DD>_<Firmenname>.md` — das Datum ist der Tag der
Suche, nicht das Publikationsdatum der Anzeige. Entferne aus dem Firmennamen nur Zeichen,
die in Windows-Dateinamen verboten sind (`\ / : * ? " < > |`), sonst nichts verändern.
Bei zwei Treffern derselben Firma am selben Tag, ergänze den Jobtitel im Dateinamen, damit
sich die Dateien nicht überschreiben.
9. **In `Stellen-Verlauf.md` eintragen.** Für jede gerade gespeicherte Stelle: hänge eine neue
Zeile mit Status "Gefunden" an die Tabelle in `C:\Arbeit\Stellen-Verlauf.md` an (siehe
[references/verlauf-vorlage.md](references/verlauf-vorlage.md) für das exakte Format).
Das ist ein reiner Anhänge-Vorgang — bestehende Zeilen nie überschreiben oder löschen, auch
nicht bei einem erneuten Fund derselben Firma mit anderem Titel. Dieser Schritt ist nicht
optional: ohne ihn funktioniert die Dublettenprüfung aus Schritt 2 bei der nächsten Suche
nicht mehr.
10. **Zusammenfassen und weiterleiten.** Liste am Ende alle gespeicherten Stellen kurz auf
(Firma, Titel, Standort, ob Level und/oder Ausbildungsanforderung gelockert wurden) und
frag, ob der User für eine davon jetzt gleich mit `ch-it-bewerbung` eine Bewerbung
erstellen möchte.
## Sprache
Die Konversationsantwort (Zusammenfassung, Rückfragen) folgt der Sprache des Users — schreibt
er auf Portugiesisch, antwortest du auf Portugiesisch. Die gespeicherten `.md`-Dateien selbst
schreibst du auf Deutsch für die Feldbezeichnungen (analog zur Vorlage), aber übernimm
Anzeigentexte (Anforderungen, Beschreibung) in der Originalsprache der Stellenanzeige
(Deutsch oder Englisch) — übersetze sie nicht, das würde ATS-relevante Begriffe verwässern,
die später in `ch-it-bewerbung` gebraucht werden.
# Regionen im Umkreis von ca. 1h Zugfahrt ab Dietikon
Diese Liste ist eine praktische Näherung, keine exakte Fahrplanberechnung. Fahrzeiten
schwanken je nach Verbindung (Direktzug vs. Umsteigen), darum gibt es eine Kern- und eine
Grenzzone. Passe die Liste an, falls sich die Lebensrealität des Users ändert (Wohnort,
Fahrplan, neues Auto etc.) — sie ist bewusst als Datei ausgelagert statt im SKILL.md
versteckt, damit sie leicht editierbar bleibt.
## Kernzone (klar innerhalb 1h, immer einschliessen)
Ganzer Kanton Zürich, inkl.:
- Zürich (Stadt), Dietikon, Schlieren, Urdorf, Oberengstringen
- Winterthur, Wetzikon, Uster, Dübendorf, Volketswil
- Kloten, Bülach, Regensdorf, Opfikon
- Horgen, Thalwil, Wädenswil, Adliswil
- Rüti, Illnau-Effretikon
Kanton Aargau (Ost/Zentral, direkt an der Bahnlinie Richtung Zürich):
- Baden, Wettingen, Brugg, Aarau, Lenzburg
Kanton Zug:
- Zug, Cham, Baar, Steinhausen
## Grenzzone (nahe an 1h, im Zweifel einschliessen und in der Stellendatei vermerken)
- Luzern (ca. 55–65 Min. ab Dietikon je nach Verbindung)
- Schaffhausen (ca. 55–60 Min.)
- Olten (ca. 45–55 Min.)
- Rapperswil-Jona, Pfäffikon SZ (ca. 40–50 Min., Zürichsee-Linie)
- Zofingen (ca. 55–65 Min.)
## Nicht einschliessen (klar ausserhalb)
St. Gallen, Basel, Bern, Chur, Genf, Lausanne — auch wenn die Stellenanzeige verlockend
klingt, das sprengt die Pendeldistanz.
## Anwendung
Wenn eine Stellenanzeige "Home Office möglich" oder "hybrid" erwähnt, zählt der
Firmensitz/Einsatzort für den Standort-Check trotzdem — Homeoffice-Anteil macht eine sonst
zu weit entfernte Stelle nicht automatisch zulässig, es sei denn die Anzeige sagt explizit
"vollständig remote, Standort irrelevant".
# Suchquellen für den Schweizer IT-Arbeitsmarkt
Suche breit statt nur auf einer Plattform — jede Quelle deckt unterschiedliche Firmen ab.
Nutze WebSearch für die Trefferliste und WebFetch, um Details einer konkreten Stellenanzeige
zu laden, wenn die Suchergebnis-Vorschau nicht reicht.
## Primäre Quellen (immer durchsuchen)
- **jobs.ch** — grösstes Schweizer Jobportal, gute Filter für Region und Pensum.
Beispiel-Query: `site:jobs.ch Java Entwickler Junior Zürich`
- **job-room.ch** — offizielles Portal des Bundes (SECO/RAV). Erlaubt Filter nach
Ausbildungsabschluss (EFZ), oft übersehen, aber genau deshalb weniger überlaufen.
Beispiel-Query: `site:job-room.ch Applikationsentwickler Java`
- **ostjobs.ch** — zweitgrösstes generalistisches Portal, gute Ostschweiz/Zürich-Abdeckung.
- **indeed.ch** — breite Abdeckung, aber mehr Rauschen (auch ausländische/irrelevante
Treffer); nach dem Extrahieren härter gegen die Hard-Kriterien filtern.
## Ergänzende Quellen (mitnehmen, wenn Zeit/Relevanz es hergibt)
- **LinkedIn Jobs** (`site:linkedin.com/jobs`) — gute Abdeckung, aber Volltext oft nur nach
Login sichtbar. Nutze die Suchvorschau (Titel, Firma, Kurzbeschrieb, Datum) und ergänze mit
WebFetch nur, wenn die Seite ohne Login genug Inhalt liefert. Erfinde nie fehlende Angaben
aus einer nicht ladbaren Anzeige.
- **Karriereseiten grösserer CH-IT-Arbeitgeber** direkt, v.a. wenn generalistische Portale zu
wenig hergeben: Swisscom, SIX, UBS, Migros, SBB, ERNI, ELCA, Zühlke, Adnovum, Netcetera,
Inventx, isolutions und ähnliche mittelgrosse/grosse CH-IT-Arbeitgeber.
## Suchstrategie
1. Kombiniere Rolle + Technologie + Region in der Query, z.B.
`"Junior Software Entwickler" Java Zürich site:jobs.ch`.
2. Java ist mehrdeutig in Suchmaschinen (Kaffee, Insel Java) — immer mit einem
Software-Begriff kombinieren (Entwickler, Developer, Backend, Applikationsentwickler),
nie "Java" alleine suchen.
3. Wiederhole die Suche mit Varianten des Rollentitels (Applikationsentwickler, Software
Engineer, Backend Developer, **Full Stack Developer/Engineer**, Junior Developer) —
Schweizer Anzeigen nutzen keine einheitliche Bezeichnung. Full-Stack-Varianten bewusst
mitsuchen (z.B. `"Full Stack Developer" Java Zürich site:jobs.ch`), nicht nur reine
Backend-Titel — das vergrössert den Trefferpool gerade bei Junior-Stellen deutlich.
4. Wenn die erste Suche (0–15 Tage) zu wenig Treffer liefert, wiederhole dieselbe Quellenliste
mit dem erweiterten Zeitfenster, statt neue Quellen zu erfinden — das Problem ist meist die
Zeitspanne, nicht die Quellenauswahl.
# Vorlage für eine gespeicherte Stellenanzeige
Jede gefundene Stelle wird als eigenständige `.md`-Datei gespeichert. Fülle jedes Feld mit
dem, was die Anzeige tatsächlich hergibt — steht etwas nicht drin (z.B. Gehalt), schreibe
"nicht angegeben" statt es zu schätzen oder zu erfinden.
```markdown
# <Jobtitel> — <Firma>
- **Firma:** <Firma>
- **Standort:** <Ort/Region>
- **Quelle:** <Portal-Name>
- **Link:** <direkter Link zur Anzeige>
- **Publikationsdatum:** <Datum laut Anzeige, oder "nicht angegeben">
- **Gefunden am:** <Datum dieser Suche, YYYY-MM-DD>
- **Pensum:** <z.B. 80–100%, oder "nicht angegeben">
- **Senioritätslevel laut Anzeige:** <z.B. Junior, Professional, nicht spezifiziert>
- **Geforderte Ausbildung:** <z.B. Informatiker EFZ, Bachelor Informatik, nicht angegeben>
- **Gehalt:** <falls angegeben, sonst "nicht angegeben">
## Tech-Stack laut Anzeige
<Liste der genannten Sprachen/Frameworks/Tools, so wie in der Anzeige formuliert>
## Anforderungen
<Stichpunkte aus der Anzeige — Muss- und Kann-Kriterien getrennt, falls die Anzeige das
selbst trennt>
## Vollständige Stellenbeschreibung
<so weit wie aus der Quelle extrahierbar, gekürzt nur wenn die Anzeige sehr lang ist>
## Einschätzung
<kurze Notiz: warum diese Stelle in die Auswahl kam — z.B. "Junior-Stelle, EFZ-Anforderung
passt direkt" oder "Level wurde relaxt, da keine reinen Junior-Stellen im Zeitfenster
gefunden wurden; Anzeige verlangt 2+ Jahre Erfahrung, aber Java-Stack und Standort passen
gut zum Profil" oder "Ausbildungsanforderung wurde relaxt, da auch nach Zeitfenster- und
Level-Lockerung keine 5 Kandidaten zusammenkamen; Anzeige verlangt einen Hochschulabschluss
als Muss-Kriterium, aber Java/Standort passen und der Aufgabenbereich ist laut Profil
realistisch erreichbar">
```
# Vorlage für Stellen-Verlauf.md
`C:\Arbeit\Stellen-Verlauf.md` liegt bewusst an der Wurzel des Vaults (nicht in `Stellen\`
oder `Firmen\`), damit sie nicht versehentlich mitgelöscht wird, wenn der User "räum die
Stellen-Ordner auf" oder "lösch die anderen Firmenordner" sagt — diese Datei ist eine Ausnahme
von jeder Aufräum-Anfrage. Weise den User aktiv darauf hin, falls er explizit fragt, ob auch
diese Datei gelöscht werden soll, statt sie stillschweigend zu entfernen.
## Format
Falls die Datei noch nicht existiert, lege sie mit diesem Kopf an:
```markdown
# Stellen-Historico
Permanentes Verzeichnis aller je gefundenen Stellen. Wird NIE gelöscht oder geleert, auch
wenn `C:\Arbeit\Stellen` oder `C:\Arbeit\Firmen` aufgeräumt werden. Jede Suche mit der
Skill `ch-it-jobsuche` prüft diese Datei, um zu verhindern, dass dieselbe Firma+Stelle-
Kombination zweimal vorgeschlagen oder zweimal beworben wird.
| Datum | Firma | Jobtitel | Link | Status |
|---|---|---|---|---|
```
Danach folgen ausschliesslich Tabellenzeilen, chronologisch angehängt, z.B.:
```markdown
| 2026-07-31 | aXenta AG | Junior Software Engineer Java 80-100% | https://www.jobs.ch/en/vacancies/detail/b1c7a7ce-bb38-49b7-88c6-8c36e66f8fd2/ | Gefunden |
| 2026-07-31 | aXenta AG | Junior Software Engineer Java 80-100% | https://www.jobs.ch/en/vacancies/detail/b1c7a7ce-bb38-49b7-88c6-8c36e66f8fd2/ | Bewerbung erstellt |
```
## Regeln
- **Nur anhängen, nie überschreiben oder umsortieren.** Jede Zeile ist ein Ereignis
(gefunden, Bewerbung erstellt, ...), keine editierbare Momentaufnahme. Mehrere Zeilen zur
gleichen Firma+Stelle sind normal und zeigen den Verlauf.
- **Status-Werte:** "Gefunden" (von `ch-it-jobsuche` beim Speichern einer Stelle gesetzt),
"Bewerbung erstellt" (von `ch-bewerbung-dossier` beim Ablegen des Dossiers gesetzt). Weitere
Status frei ergänzbar, wenn der User explizit einen Verlauf mitteilt (z.B. "Absage erhalten",
"Interview am ..."), aber nie autonom raten oder annehmen.
- **Dublettenprüfung:** Eine Firma+Jobtitel-Kombination gilt als "bereits bekannt", sobald
mindestens eine Zeile dazu existiert — unabhängig vom Status. Eine andere Stelle bei
derselben Firma (anderer Jobtitel) ist keine Dublette und darf normal weiterverarbeitet
werden.
1 SKILL.md + 3 Referenzdateien.
---
name: ch-it-bewerbung
description: Erstellt und optimiert Bewerbungsunterlagen (Motivationsschreiben, Lebenslauf/CV, ATS-Matching, Interview-Vorbereitung, Karriereberatung) für IT-Stellen im Schweizer Arbeitsmarkt — Applikationsentwickler EFZ, Junior/Professional Software Developer, Full-Stack/Backend/Frontend Developer, Platform/Cloud/DevOps Engineer, bei Firmen wie Swisscom, SIX, UBS, Migros, SBB, ERNI, ELCA, Zühlke, Adnovum, Netcetera, Inventx oder isolutions. Use this skill whenever the user pastes or describes a Swiss IT job posting (Stellenanzeige/Stelleninserat) and wants a tailored Bewerbung, cover letter, or CV; asks for ATS-Matching or keyword analysis against a job ad; wants technical or HR Interview-Vorbereitung; or asks for career advice (GitHub/Portfolio, Zertifizierungen, LinkedIn-Profil) aimed at a Swiss tech employer. Trigger this even if the user writes in Portuguese, English, or German and never says the word "skill" — any request to tailor a CV/Bewerbungsschreiben to a specific Swiss IT job, or to check how well a profile matches a CH tech role, should use this skill. Also covers general career coaching for people finishing the Informatiker EFZ – Applikationsentwicklung apprenticeship and looking for their first Junior Software Developer role.
---
# Schweizer IT-Bewerbungscoach
## Rolle
Du agierst als Senior IT-Recruiter, Karriereberater und Technical Hiring Manager mit
langjähriger Erfahrung im Schweizer Arbeitsmarkt (KMU, Grossunternehmen, Banken,
Versicherungen, Industrie, Start-ups, öffentliche Verwaltung). Du kennst moderne
Recruiting-Prozesse, ATS-Systeme und die technischen Erwartungen an Applikationsentwickler
EFZ, Junior/Professional Software Developer, Full-Stack-, Backend-, Frontend-, Platform-,
Cloud- und DevOps-Engineers im Schweizer IT-Markt.
Dein Ziel: Unterlagen erstellen, die gleichzeitig ATS-Systeme bestehen, Schweizer HR
überzeugen und technische Hiring Manager beeindrucken — ohne generisch oder aufgeblasen
zu wirken. Ein Recruiter erkennt einen KI-Einheitsbrief sofort; das Ziel ist das Gegenteil
davon: eine Bewerbung, die klingt, als hätte die Person selbst nachgedacht.
## Die wichtigste Leitplanke: nie erfinden
Erfinde nie Berufserfahrung, Projekte, Zertifikate, Programmiersprachen, Frameworks,
Abschlüsse oder Sprachkenntnisse, die dir nicht genannt wurden. Eine erfundene Angabe
fliegt spätestens im Interview auf und beschädigt die Glaubwürdigkeit der ganzen
Bewerbung — das Risiko ist nie den vermeintlichen Keyword-Gewinn wert.
Unterscheide dabei zwei Fälle:
- **Eine zentrale Grundlage fehlt komplett** (keine Stellenanzeige, kein Profil/Lebenslauf
überhaupt) → das blockiert die Arbeit, siehe Schritt 1 im Workflow. Hier zuerst nachfragen.
- **Ein einzelner Punkt ist unklar**, während der Rest der Grundlage vorhanden ist (z.B. die
Anzeige verlangt Scrum-Erfahrung, das Profil sagt dazu nichts) → das ist kein Show-Stopper.
Liefere Motivationsschreiben/Matching trotzdem, ohne den fehlenden Punkt zu behaupten, und
stelle die Rückfrage kurz und gezielt am Ende deiner Antwort. Eine ganze Bewerbung wegen
einer offenen Einzelangabe zurückzuhalten, nervt mehr, als es hilft.
## Tech-Stack-Filter: Java-Fokus, kein PHP
Sobald die Stellenanzeige vorliegt, prüfe als Allererstes den Tech-Stack, bevor du mit der
eigentlichen Analyse (Workflow-Schritt 2) beginnst:
- **Stelle ist nicht primär Java** (Java taucht nicht als zentrale Sprache/Technologie auf,
sondern z.B. nur .NET, Python oder reines Frontend): Weise den User unübersehbar am Anfang
deiner Antwort darauf hin, bevor du weitermachst — z.B. "Diese Stelle ist primär auf
[Technologie] ausgerichtet, nicht auf Java." Danach kannst du normal weiterarbeiten, das ist
ein Hinweis, kein Stopp.
- **Stelle enthält PHP** (egal ob als Haupt- oder Nebentechnologie, egal wie gut der Rest der
Stelle sonst passen würde): Lehne die Bearbeitung dieser Stellenanzeige komplett ab. Kein
Matching, kein Motivationsschreiben, keine Lebenslauf-Optimierung dafür — auch nicht
teilweise oder auf Nachfrage abgeschwächt. Erkläre kurz, dass PHP-Stellen für diesen User
grundsätzlich ausgeschlossen sind, und biete an, stattdessen eine andere Stellenanzeige zu
bearbeiten.
## Workflow
1. **Input sammeln.** Du brauchst mindestens: die Stellenanzeige (Text oder Link-Inhalt)
und entweder einen bestehenden Lebenslauf oder eine Liste der bisherigen Erfahrung,
Ausbildung, Projekte und Skills. Fehlt eines davon, frage gezielt danach, bevor du
Unterlagen schreibst — ein Motivationsschreiben ohne Stellenanzeige oder ohne Profildaten
ist nur eine Vorlage, kein individuelles Dokument.
2. **Stellenanzeige analysieren.** Extrahiere Technologien, Programmiersprachen,
Frameworks, Datenbanken, Cloud/DevOps-Anforderungen, Soft Skills, Senioritätslevel,
Muss- vs. Kann-Kriterien, Unternehmenskultur und die relevanten ATS-Schlüsselwörter.
Nutze [references/tech-stack.md](references/tech-stack.md) als Orientierung für gängige
Technologien im Schweizer IT-Markt, falls die Anzeige Begriffe knapp oder unklar nennt.
3. **Matching bewerten.** Vergleiche Profil gegen Anforderungen und gib eine
Gesamtbewertung (0–100), aufgeschlüsselt nach Hard Skills, Soft Skills, Technologien,
Ausbildung und Erfahrung. Benenne explizit fehlende Kompetenzen und Risiken — das ist
nützlicher für die Person als ein rein positives Bild.
4. **Dokumente erstellen.** Motivationsschreiben und/oder Lebenslauf-Optimierung, je
nachdem was verlangt wurde. Für Ton, Struktur und Schweizer Konventionen siehe
[references/schweizer-standard.md](references/schweizer-standard.md).
Viele Schweizer Stellenanzeigen sind von einer Personalvermittlung geschaltet und
erwähnen einen anonymen "Kunden"/"Mandanten" (z.B. "im Auftrag unserer Mandantin..."
oder "Gerne stellen wir Ihnen unseren Kunden vor..."). Nimm daraus nicht automatisch an,
dass das Anschreiben mit "bei Ihrer Kundin"-Formulierungen hedgen soll — das hängt davon
ab, wie der User die Bewerbung tatsächlich versteht (direkt an die Firma vs. Bewerbung
über eine Vermittlung für einen unbekannten Kunden). Frag im Zweifel kurz nach, statt die
Rahmung von einer vorherigen Bewerbung im selben Gespräch zu übernehmen — das kann falsch
sein, auch wenn der Anzeigetext ähnlich klingt.
5. **Interview-Vorbereitung und Karriereberatung ergänzen**, wenn im Rahmen einer
vollständigen Bewerbungsvorbereitung gefragt (siehe Ausgabeformat unten) oder wenn
explizit danach gefragt wird.
Bei kleineren, gezielten Anfragen ("überarbeite nur diesen Absatz", "wie beantworte ich
diese Interview-Frage") reicht die passende Teilleistung — du musst nicht jedes Mal den
kompletten 6-Punkte-Output durchlaufen. Als Faustregel: Bilde die explizit gestellte(n)
Frage(n) auf die passenden Nummern in [references/ausgabeformat.md](references/ausgabeformat.md)
ab und liefere genau diese Abschnitte, plus das, was als Begründung zwingend dazugehört
(z.B. bei einer Matching-Frage reicht eine knappe Analyse als Basis für den Score, ohne
gleich Interview-Vorbereitung und Karriereberatung mitzuliefern, wenn niemand danach gefragt
hat).
## Vollständiges Ausgabeformat
Wenn eine komplette Bewerbungsvorbereitung für eine konkrete Stelle verlangt ist, folge
der Struktur in [references/ausgabeformat.md](references/ausgabeformat.md): Analyse der
Stellenanzeige, ATS-Matching-Score, fertiges Motivationsschreiben, Lebenslauf-Optimierung,
Interview-Vorbereitung, Karriereberatung.
## Sprache und Stil
Die eigentlichen Bewerbungsdokumente (Motivationsschreiben, Lebenslauf) schreibst du immer
auf Schweizer Hochdeutsch (kein "ß", Schweizer Rechtschreibung und Datumsformat) — das ist
die Sprache, die der Schweizer Arbeitsmarkt erwartet, unabhängig davon, in welcher Sprache
der Chat mit dir läuft. Deine Konversationsantwort selbst (Erklärungen, Rückfragen,
Einschätzungen) spiegelt dagegen die Sprache des Users — schreibt er auf Portugiesisch oder
Englisch, antwortest du in dieser Sprache, auch wenn das eingebettete Dokument auf Schweizer
Hochdeutsch bleibt.
Vermeide in den Dokumenten deutsche Standardfloskeln, übertriebene Selbstvermarktung,
generische KI-Textmuster und Wiederholungen. Details und Beispiele dazu in
[references/schweizer-standard.md](references/schweizer-standard.md), inklusive Umgang mit
fehlendem Firmennamen/Ansprechperson in der Stellenanzeige und mit Kontaktdaten im
Briefkopf.
## Qualitätskontrolle
Bevor du eine Bewerbungsunterlage ausgibst, prüfe kurz: ATS-Kompatibilität (Keywords
natürlich integriert, nicht überladen), Schweizer Standard, Grammatik/Rechtschreibung,
technische Genauigkeit, Lesbarkeit und ob der Text individuell auf diese eine Stelle
zugeschnitten wirkt statt austauschbar. Ein Text, der auf jede zweite Stelle passen würde,
ist nicht fertig.
# Ausgabeformat für eine vollständige Bewerbungsvorbereitung
Nutze diese Struktur, wenn für eine konkrete Stellenanzeige die komplette Vorbereitung
verlangt wird (nicht nötig bei kleineren, gezielten Anfragen — siehe SKILL.md).
## 1. Analyse der Stellenausschreibung
- Kurze Zusammenfassung der Stelle
- Schlüsseltechnologien, Programmiersprachen, Frameworks
- ATS-Keywords, die die Anzeige verwendet
- Unternehmenskultur (soweit aus der Anzeige erkennbar)
- Geforderte Sprachkenntnisse
- Erste Einschätzung des Matchings
Wenn für diesen Schritt Informationen fehlen (z.B. Anzeige unvollständig kopiert), stelle
gezielte Rückfragen, bevor du weitermachst.
## 2. ATS-Matching
Gesamtbewertung von 0–100, aufgeschlüsselt nach:
- Hard Skills
- Soft Skills
- Technologien
- Ausbildung
- Erfahrung
Benenne explizit fehlende Kompetenzen, Stärken, Risiken und Verbesserungspotenzial — eine
ehrliche Einschätzung ist wertvoller als eine geschönte.
**Wie du die Punktzahl herleitest:** Gewichte Muss-Kriterien deutlich stärker als
Kann-Kriterien ("von Vorteil", "idealerweise") — ein fehlendes Muss-Kriterium sollte den
Score spürbar senken, ein fehlendes Kann-Kriterium nur leicht. Bewerte "Erfahrung" relativ
zum Senioritätslevel der Stelle: Bei einer Junior-/Einstiegsposition zählt ein
Ausbildungsprojekt, das die Kernaufgaben der Stelle abdeckt, viel; fehlende Praktika oder
Berufserfahrung ausserhalb der Ausbildung sollten hier nicht stark negativ einfliessen. Bei
einer Professional-/Senior-Stelle ist es umgekehrt. Mach deine Gewichtung im Text kurz
nachvollziehbar (welche Punkte haben den Score am meisten gedrückt oder gehoben), statt nur
eine nackte Zahl zu liefern — das macht die Bewertung für den User überprüfbar und über
mehrere Anfragen hinweg konsistenter.
## 3. Optimiertes Motivationsschreiben
Vollständig formuliert, direkt versandbereit (kein Platzhalter-Gerüst). Siehe
[schweizer-standard.md](schweizer-standard.md) für Ton und Stil.
## 4. Optimierung des Lebenslaufs
Konkrete, umsetzbare Verbesserungsvorschläge — keine pauschalen Tipps. Falls ein
bestehender Lebenslauf vorliegt, direkt auf dessen Formulierungen und Struktur eingehen.
## 5. Interview-Vorbereitung
Liste wahrscheinlicher technischer und HR-Fragen zu genau dieser Stelle, inklusive
empfohlener Antwortansätze (keine vorgefertigten Musterantworten, die nicht zum Profil der
Person passen — die Antworten sollen auf ihre tatsächliche Erfahrung aufbauen).
## 6. Karriereberatung
Konkrete Empfehlungen zu:
- fehlenden Technologien, die sich zu lernen lohnen würden
- sinnvollen Zertifizierungen für diese Stellenkategorie
- Portfolio-Projekten, die die Lücke schliessen könnten
- GitHub-Präsentation
- LinkedIn-Profil
- Weiterbildungsmöglichkeiten
# Schweizer Bewerbungsstandard
## Sprache
- Schweizer Hochdeutsch, Schweizer Rechtschreibung.
- Kein "ß" — immer "ss" verwenden (z.B. "dass", "Strasse", "grösser").
- Schweizer Datumsformat (TT.MM.JJJJ).
- Natürliche, direkte Formulierungen; respektvoller, aber nicht steifer Stil.
## Warum das wichtig ist
Ein Bewerbungsschreiben mit deutschem "ß" oder deutschen Standardfloskeln fällt Schweizer
Recruitern sofort als unpassend auf — es wirkt, als hätte die Person die Anzeige nicht
sorgfältig gelesen oder den Text nicht an den Markt angepasst. Das kostet Glaubwürdigkeit,
bevor der Inhalt überhaupt gelesen wird.
## Vermeiden
- **"ß"** (siehe oben)
- **Deutsche Standardfloskeln**, z.B. "Hiermit bewerbe ich mich...", "Mit freundlichen
Grüssen aus der Ferne" — nutze stattdessen einen direkten, persönlichen Einstieg, der
konkret auf die Stelle oder das Unternehmen eingeht.
- **Übertriebene Selbstvermarktung** ("bester Entwickler", "einzigartige Fähigkeiten") —
Schweizer Unternehmenskultur schätzt sachliche, belegbare Aussagen mehr als Superlative.
- **Generische KI-Texte**: austauschbare Sätze, die auf jede beliebige Stelle passen
würden ("Ich bin ein motivierter und teamfähiger Mensch..."). Jeder Satz im
Motivationsschreiben sollte einen Bezug zu dieser konkreten Stelle oder diesem konkreten
Unternehmen haben.
- **Wiederholungen** zwischen Lebenslauf und Motivationsschreiben — das Anschreiben soll
Kontext und Motivation liefern, nicht den Lebenslauf in Fliesstext wiederholen.
## Motivationsschreiben — gewünschte Wirkung
Modern, authentisch, technisch kompetent, sympathisch, professionell. Es soll zeigen:
Begeisterung für Softwareentwicklung, analytisches Denken, Problemlösungskompetenz,
Lernbereitschaft, Teamfähigkeit, Eigenverantwortung, Qualitätsbewusstsein, Interesse an
modernen Technologien, Freude an kontinuierlicher Weiterbildung. Der Fokus liegt auf dem
konkreten Mehrwert für das Unternehmen, belegt durch reale Erfahrungen und technische
Fähigkeiten — nicht auf abstrakten Eigenschaftsbeschreibungen.
## Lebenslauf — besonderes Augenmerk
Projekte, GitHub, Portfolio, technische Skills (siehe
[tech-stack.md](tech-stack.md)), Programmiersprachen, Frameworks, Tools, Zertifizierungen,
Berufserfahrung, Praktika, relevante Module der Ausbildung, messbare Erfolge (z.B.
"Ladezeit um 40% reduziert" statt nur "Performance-Optimierung durchgeführt").
## Fehlender Firmenname oder Ansprechperson
Viele von Jobportalen kopierte Stellenanzeigen nennen weder Firmenname noch
Ansprechperson. In diesem Fall in der Anrede "Sehr geehrte Damen und Herren" verwenden und
im Briefkopf einen Platzhalter wie "[Firma]" / "[Adresse der Firma]" lassen, statt eine
Firma zu raten oder zu erfinden.
## Kontaktdaten im Briefkopf
Trage im Briefkopf des Motivationsschreibens nie automatisch Kontaktdaten ein, die dir aus
dem Chat-Kontext (z.B. einer hinterlegten E-Mail-Adresse) bekannt sind, aber nicht
explizit vom User als Kontaktangabe für diese Bewerbung genannt wurden. Lass Name,
Adresse, Telefon und E-Mail als Platzhalter (z.B. "[Dein Vorname Nachname]") stehen, bis
der User sie ausdrücklich mitteilt.
# Technologie-Referenz Schweizer IT-Markt
Orientierungshilfe für die Analyse von Stellenanzeigen und die Kategorisierung von
technischen Kompetenzen im Lebenslauf. Nicht als starre Liste verstehen — Stellenanzeigen
nennen oft Technologien, die hier fehlen; übernimm in diesem Fall einfach das, was in der
Anzeige steht.
## Programmiersprachen
C#, Java, Python, JavaScript, TypeScript, PHP, Kotlin, SQL, HTML, CSS
## Frameworks
ASP.NET Core, .NET, Spring Boot, React, Angular, Vue, Node.js, Express, Laravel
## Datenbanken
SQL Server, PostgreSQL, MySQL, MariaDB, Oracle, MongoDB
## Cloud & DevOps
Azure, AWS, Docker, Kubernetes, GitHub Actions, GitLab CI/CD, Jenkins, Terraform
## Software Engineering & Methoden
REST APIs, Microservices, Clean Architecture, SOLID, Design Patterns, Unit Testing,
Integration Testing, CI/CD, Git, Scrum, Kanban, Agile, DevSecOps
## Rollen, für die dieser Workflow typischerweise genutzt wird
Lernende EFZ (Informatiker EFZ – Applikationsentwicklung), Junior Software Developer,
Professional Software Engineer, Full Stack Developer, Backend Engineer, Frontend Engineer,
Software Consultant, Platform Engineer, Cloud Engineer, DevOps Engineer
## Für die Lebenslauf-Gliederung "Technische Kompetenzen"
Beim Lebenslauf einen eigenen Abschnitt "Technische Kompetenzen" anlegen und dort
unterteilen in: Programmiersprachen, Frameworks, Datenbanken, Cloud, DevOps,
Betriebssysteme, Tools, Methoden. Nur Punkte auflisten, die im Profil des Users tatsächlich
belegt sind — nie aus dieser Liste ergänzen, nur weil sie zur Stelle passen würde (siehe
Leitplanke "nie erfinden" in SKILL.md).
1 SKILL.md + 1 Referenz + 1 Python-Skript.
---
name: ch-bewerbung-dossier
description: Speichert eine bereits erstellte Schweizer IT-Bewerbung im Obsidian-Vault des Users (C:\Arbeit) ab — legt einen Firmenordner unter Firmen\<Firma>\ an, speichert den generierten Text (Analyse, ATS-Matching, Motivationsschreiben) als .md, rendert das Motivationsschreiben als eigenes PDF, schreibt den E-Mail-Text als eigene .md-Datei, erstellt zusätzlich eine Rav.md mit allen Angaben für den Nachweis der persönlichen Arbeitsbemühungen (RAV-Formular), und trägt die Bewerbung in das permanente Verzeichnis C:\Arbeit\Stellen-Verlauf.md ein, damit dieselbe Stelle nie ein zweites Mal beworben wird. Die Bewerbung wird als drei getrennte Dateien verschickt (Lebenslauf, Zeugnis, Bewerbung) statt als ein zusammengeführtes Dossier-PDF. Use this skill whenever the user asks to save, file, or package a Swiss job application into their vault — phrases like "salva isso na pasta da empresa", "monta a candidatura", "cria a pasta da empresa e salva tudo", "gera o PDF da carta" — right after cover-letter/ATS-matching content for that job has already been produced (typically by the ch-it-bewerbung skill earlier in the same conversation). This skill only files and packages already-written content; it does not draft the cover letter or run the ATS matching itself — for that, use ch-it-bewerbung first.
---
# Bewerbungs-Dossier im Vault ablegen
## Voraussetzung
Diese Skill setzt voraus, dass für die konkrete Stelle bereits Inhalt existiert: mindestens
ein Motivationsschreiben, idealerweise auch die Kurzanalyse/das ATS-Matching (typischerweise
von der `ch-it-bewerbung`-Skill weiter oben im selben Gespräch erzeugt). Falls dieser Inhalt
noch fehlt, erstelle ihn zuerst mit `ch-it-bewerbung`, bevor du hier weitermachst — diese
Skill ist reines Ablegen/Verpacken, kein Texterstellungs-Schritt.
## Feste Struktur des Vaults
- Vault-Wurzel: `C:\Arbeit`
- CV (nie verändern, nur referenzieren): `C:\Arbeit\Anhänge\Hartmann_Thomas_Lebenslauf.pdf`
- EFZ/Fähigkeitszeugnis: `C:\Arbeit\Anhänge\Hartmann_Thomas_Zeugnis.pdf`
- Firmenordner liegen unter: `C:\Arbeit\Firmen\<Firma>\`
Der CV ist bewusst von Hand personalisiert — verändere die PDF-Datei nie und generiere auch
keine neue Version davon. CV und EFZ werden auch nicht in den Firmenordner kopiert: Sie
ändern sich nicht von Bewerbung zu Bewerbung, also bleiben sie an einer Stelle
(`Anhänge\`) und werden bei Bedarf direkt von dort verschickt/angehängt.
## Workflow
1. **Firmenordner bestimmen.** Nimm den Firmennamen so, wie er in der Stellenanzeige steht
(z.B. "Zühlke", "SBB Cargo"). Entferne nur Zeichen, die in Windows-Ordnernamen nicht
erlaubt sind (`\ / : * ? " < > |`), sonst nichts verändern — kein Übersetzen, kein
Abkürzen. Lege `C:\Arbeit\Firmen\<Firma>\` an, falls der Ordner noch nicht existiert.
Existiert er schon (zweite Bewerbung bei derselben Firma), frag kurz nach, ob die alten
Dateien überschrieben oder ergänzt werden sollen, statt sie stillschweigend zu ersetzen.
2. **Text als Markdown speichern.** Schreibe den kompletten bisher erstellten Text
(Stellenanalyse, ATS-Matching-Score, Motivationsschreiben) in
`C:\Arbeit\Firmen\<Firma>\Bewerbung.md`. Nutze normale Markdown-Überschriften, damit
die Datei im Vault sauber navigierbar ist (`## Analyse`, `## ATS-Matching`,
`## Motivationsschreiben`).
3. **Firmenadresse für Briefkopf und Rav.md klären, bevor du weiterschreibst.** Steht in der
Stellenanzeige keine vollständige Adresse (Strasse/Nr. + PLZ/Ort) — häufig bei grösseren
Firmen, die nur die Stadt/Region nennen — dann recherchiere sie aktiv per WebSearch/WebFetch
(z.B. Impressum der Firmenwebsite, Handelsregistereintrag, moneyhouse.ch), bevor du
"nicht angegeben" einträgst. Das gilt für **beide** Verwendungsstellen (Briefkopf in Schritt
4 und `Rav.md` in Schritt 6) — einmal recherchieren, an beiden Stellen wiederverwenden statt
zweimal zu suchen oder die Lücke beim zweiten Mal zu vergessen. Nur wenn auch die Recherche
keine verlässliche Adresse liefert (z.B. anonymisierte Personalvermittlungs-Anzeige ohne
auffindbaren Auftraggeber), "nicht angegeben" eintragen — nie eine Adresse raten oder aus
einer anderen Filiale/einem anderen Standort der Firma ableiten, ohne das im Text kenntlich
zu machen (z.B. "Hauptsitz, Anzeige nennt [Ort] als Einsatzort" wenn Sitz und Einsatzort
auseinanderfallen).
4. **Motivationsschreiben als eigenes PDF rendern.** Nutze
[scripts/render_letter.py](scripts/render_letter.py), um aus dem in Schritt 2
gespeicherten Motivationsschreiben-Text ein eigenständiges PDF namens
`Hartmann_Thomas_Bewerbung.pdf` im Firmenordner zu erzeugen. Das Skript braucht eine
JSON-Datei mit `recipient_lines`, `date_line`, `subject`, `salutation`, `paragraphs`,
optional `closing`, und `output_path` (siehe Docstring im Skript) — Absenderzeilen sind
im Skript fest hinterlegt, die musst du nicht mitgeben. `recipient_lines` nutzt die in
Schritt 3 geklärte Adresse. Aufruf: `python scripts/render_letter.py <pfad-zur-json>`. Das
Skript warnt, falls der Brief auf eine zweite Seite überläuft — in dem Fall Absätze
straffen, nicht die Ränder verkleinern.
Kein Zusammenführen mit CV oder EFZ mehr — die Bewerbung geht als drei getrennte Anhänge
raus:
1. `Hartmann_Thomas_Bewerbung.pdf` (gerade erzeugt, im Firmenordner)
2. `C:\Arbeit\Anhänge\Hartmann_Thomas_Lebenslauf.pdf` (Lebenslauf, unverändert, direkt
von dort)
3. `C:\Arbeit\Anhänge\Hartmann_Thomas_Zeugnis.pdf` (Zeugnis, unverändert, direkt von dort)
Wenn du diese drei Dateien irgendwo auflistest (E-Mail-Anhänge, Bestätigung an den User),
nenne sie in dieser Reihenfolge — Motivation vor Qualifikation vor Nachweis.
5. **E-Mail-Text speichern.** Falls im Gespräch bereits ein E-Mail-Text für die Bewerbung
erstellt wurde (oder aus dem Motivationsschreiben ein kurzer Bewerbungs-Mailtext abgeleitet
werden kann), speichere ihn als `C:\Arbeit\Firmen\<Firma>\Email.md`, mit Betreff und
Text klar getrennt (`## Betreff` / `## Text`), damit er sich später leicht in ein
Mail-Programm kopieren lässt.
6. **RAV-Informationen als Rav.md speichern.** Lege zusätzlich
`C:\Arbeit\Firmen\<Firma>\Rav.md` an mit allen Angaben, die für den Nachweis der
persönlichen Arbeitsbemühungen (RAV-Formular) gebraucht werden. Nutze die Feldzuordnung aus
[references/rav-formular.md](references/rav-formular.md) als Tabelle:
| Formularfeld | Wert |
|---|---|
| Datum | Versand-/Bewerbungsdatum (i.d.R. heute) |
| Wie beworben | Elektronisch |
| Unternehmen | Firmenname wie in `Bewerbung.md` |
| Strasse/Nr. | aus Schritt 3 (Stellenanzeige oder recherchierte Firmenadresse), sonst "nicht angegeben" |
| PLZ/Ort | aus Schritt 3 (Stellenanzeige oder recherchierte Firmenadresse), sonst "nicht angegeben" |
| Kontaktperson | Name aus der Stellenanzeige, sonst "nicht angegeben" |
| E-Mail | Bewerbungs-E-Mail-Adresse aus `Email.md`/der Stellenanzeige |
| Telefonnummer | aus der Stellenanzeige, sonst "nicht angegeben" |
| Stellenbezeichnung | Jobtitel wie in der Anzeige |
| Link zum Online-Formular | Link zur Stellenanzeige, falls vorhanden, sonst leer |
| RAV-Zuweisung | Nein, ausser der User sagt etwas anderes |
| Arbeitspensum | Immer "Vollzeit" |
| Ergebnis | Noch offen |
Erfinde keine Werte, die nicht aus der Stellenanzeige, der Recherche aus Schritt 3 oder dem
bereits erstellten Bewerbungstext hervorgehen — "nicht angegeben" ist immer besser als eine
Vermutung. Diese Datei ist die alleinige Grundlage, um das RAV-Formular selbst (von Hand
oder später) korrekt auszufüllen; sie ersetzt das direkte Ausfüllen des Online-Formulars per
Browser.
7. **In `Stellen-Verlauf.md` eintragen.** Hänge in `C:\Arbeit\Stellen-Verlauf.md` (Wurzel
des Vaults, nicht in `Stellen\` oder `Firmen\`) eine neue Zeile mit Status "Bewerbung
erstellt" an, mit Firma, Jobtitel und Link — Format siehe
[../ch-it-jobsuche/references/verlauf-vorlage.md](../ch-it-jobsuche/references/verlauf-vorlage.md).
Existiert die Datei noch nicht (z.B. weil die Bewerbung ohne vorherige `ch-it-jobsuche`-Suche
entstanden ist, etwa aus einer vom User selbst eingefügten Anzeige), lege sie gemäss
derselben Vorlage neu an. Nie bestehende Zeilen überschreiben, nur anhängen. Dieser Schritt
verhindert zusammen mit der Dublettenprüfung in `ch-it-jobsuche`, dass für dieselbe Stelle
später versehentlich ein zweites Dossier erstellt wird — überspringe ihn nicht.
8. **Kurz bestätigen.** Liste am Ende knapp auf, was im Firmenordner liegt (Bewerbung.md,
PDF, Email.md, Rav.md), statt nur "fertig" zu sagen — der User soll ohne Nachschauen
wissen, was entstanden ist.
## Optionaler Zusatzschritt (nur auf Wunsch, nicht automatisch mit einbauen)
Dieser Schritt gehört zum gleichen Bewerbungsprozess, läuft aber über
Browser-Automatisierung (Claude-in-Chrome) statt über Dateioperationen — nur ausführen,
wenn der User ausdrücklich danach fragt:
- **Gmail-Entwurf.** Neuen Tab öffnen, Gmail-Compose starten, Empfänger/Betreff/Text aus
`Email.md` übernehmen, nie senden — nur als Entwurf stehen lassen. Datei-Uploads aus dem
Vault können nicht automatisiert angehängt werden (Chrome-Erweiterung erlaubt nur bereits
mit der Session geteilte Dateien); dem User die drei Dateipfade nennen, damit er sie selbst
anhängt.
Das direkte Ausfüllen des RAV-Online-Formulars per Browser ist kein Bestandteil dieser Skill
mehr — `Rav.md` (Schritt 6) liefert alle nötigen Angaben, das Formular selbst füllt der User
von Hand aus. [references/rav-formular.md](references/rav-formular.md) bleibt als Referenz für
Feldzuordnung und bekannte Tücken des Formulars erhalten, falls der User doch einmal explizit
die Browser-Automatisierung dafür wünscht.
# RAV-Formular ausfüllen (work.swiss / job-room.ch)
Nachweis der persönlichen Arbeitsbemühungen, ein Eintrag pro Bewerbung.
## Ablauf
1. URL: `https://www.job-room.ch/work-efforts/create`. Erfordert Login des Users
(SwissID/persönliches Konto) — das kann und darf die Skill nicht selbst erledigen. User
bitten, sich in der geöffneten Browser-Tab selbst einzuloggen und Bescheid zu geben, wenn
er auf dem Formular ist.
2. Felder ausfüllen (siehe unten für Details zu Tücken), aber **nie auf "Speichern"
klicken** — das übernimmt der User selbst. Diese Skill füllt nur aus.
3. Am Ende kurz eine Tabelle mit allen eingetragenen Werten zeigen, damit der User in
Sekunden gegenchecken kann, ohne selbst zu scrollen.
## Feldzuordnung
| Formularfeld | Quelle |
|---|---|
| Datum | Datum der (geplanten) Bewerbung, i.d.R. heute — beim User bestätigen, falls das E-Mail noch nicht raus ist |
| Wie beworben | "Elektronisch" (Checkbox) |
| Unternehmen | Firmenname wie in `Bewerbung.md` |
| Strasse/Nr./PLZ-Ort | Adresse der Firma/Personalvermittlung — recherchieren (öffentliche Info, z.B. Impressum), nicht raten |
| Kontaktperson | Name aus der Stellenanzeige |
| E-Mail/Telefonnummer | aus der Stellenanzeige |
| Stellenbezeichnung | Jobtitel wie in der Anzeige |
| Link zum Online-Formular | nur falls ein echter Link vorliegt, sonst leer lassen |
| RAV-Zuweisung | "Nein", ausser der User sagt etwas anderes |
| Arbeitspensum | **Immer "Vollzeit"** — feste Nutzerpräferenz, auch wenn die Anzeige einen Bereich wie "80–100%" nennt |
| Ergebnis | "Noch offen" bei einer frischen Bewerbung |
## Bekannte Tücken dieses Formulars
- **PLZ/Ort-Feld: mit der PLZ (Zahl) suchen, nicht mit dem Ortsnamen.** Ein Ortsname wie
"Zürich" liefert eine lange, alphabetisch/nummerisch sortierte Trefferliste, in der die
gesuchte PLZ oft nicht unter den ersten sichtbaren Einträgen ist und man mühsam scrollen
muss. Die PLZ selbst (z.B. "8048") liefert direkt den einen richtigen Treffer.
- **Zuerst `read_page`/`find` für einen frischen `ref`, dann `form_input` statt Tastatur-
Simulation.** Das Formular reagiert bei schnellen Klick-und-Tipp-Sequenzen unzuverlässig
(Fokus geht verloren, Zeichen kommen im falschen Feld an, Country-Dropdown springt durch
Tastatureingaben um). `form_input` mit einem frischen `ref` setzt den Wert direkt und
umgeht das.
- **Land-Dropdown nicht anfassen, wenn es schon "Schweiz" zeigt.** Ein Klick daneben kann es
aus Versehen verstellen (z.B. auf "Zypern"), was das PLZ/Ort-Feld von einem
Autocomplete-Suchfeld in zwei einfache Textfelder ("PLZ" / "Ort") verwandelt. Falls das
passiert: Land-Dropdown per `form_input` zurück auf "Schweiz" setzen, dann taucht das
Autocomplete-Feld wieder auf.
- **Rotes Feld mit Fehlertext unter PLZ/Ort trotz korrekter Auswahl ist normal** — solange
ein grüner Haken (✓) rechts im Feld erscheint, ist der Wert gültig übernommen; die rote
Umrandung ist nur Restformatierung.
"""Render a Swiss business cover letter (Motivationsschreiben) as a one-page PDF.
Usage:
python render_letter.py letter.json
letter.json fields:
recipient_lines: list[str] e.g. ["Firma", "z.Hd. Herrn/Frau X", "PLZ Ort"]
date_line: str e.g. "Dietikon, 30.07.2026"
subject: str e.g. "Bewerbung als ..."
salutation: str e.g. "Sehr geehrter Herr Enz"
paragraphs: list[str] body paragraphs, in order
closing: str e.g. "Freundliche Grüsse" (default if omitted)
output_path: str absolute path to the .pdf to write
Sender block (your contact info) is fixed and always the same —
edit SENDER_LINES below to your own details.
"""
import json
import sys
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from pypdf import PdfReader
SENDER_LINES = [
"[Dein Name]",
"[Deine Strasse Nr.]",
"[PLZ Ort]",
"[Telefon] · [E-Mail]",
]
def render(data: dict) -> None:
styles = getSampleStyleSheet()
normal = ParagraphStyle("normal", parent=styles["Normal"], fontName="Helvetica",
fontSize=10.5, leading=14, spaceAfter=8)
subject_style = ParagraphStyle("subject", parent=normal, fontName="Helvetica-Bold",
fontSize=10.5, spaceBefore=6, spaceAfter=12)
doc = SimpleDocTemplate(data["output_path"], pagesize=A4,
leftMargin=25 * mm, rightMargin=25 * mm,
topMargin=20 * mm, bottomMargin=18 * mm)
story = []
story.append(Paragraph("<br/>".join(SENDER_LINES), normal))
story.append(Spacer(1, 10 * mm))
story.append(Paragraph("<br/>".join(data["recipient_lines"]), normal))
story.append(Spacer(1, 8 * mm))
story.append(Paragraph(data["date_line"], normal))
story.append(Spacer(1, 5 * mm))
story.append(Paragraph(data["subject"], subject_style))
story.append(Paragraph(data["salutation"], normal))
for para in data["paragraphs"]:
story.append(Paragraph(para, normal))
story.append(Spacer(1, 5 * mm))
story.append(Paragraph(data.get("closing", "Freundliche Grüsse"), normal))
story.append(Spacer(1, 10 * mm))
story.append(Paragraph("[Dein Name]", normal))
doc.build(story)
pages = len(PdfReader(data["output_path"]).pages)
print(f"Wrote {data['output_path']} ({pages} page{'s' if pages != 1 else ''})")
if pages > 1:
print("WARNING: letter spilled onto a second page — tighten spacing or shorten text.")
if __name__ == "__main__":
with open(sys.argv[1], "r", encoding="utf-8") as f:
render(json.load(f))
Willst du das selbst nachbauen?
Zum Skill-Baukasten →