Files
linkme/CLAUDE.md
T
rodado bcb6ae5ea3 Add content-level language filter, recheck command, expanded keywords
- isEnglishContent() fetches each job page and drops descriptions with ≥6 German or French indicator words; called for every new job in index.ts before writing to CSV
- New `bun recheck` command (recheck.ts) runs searches in raw mode, lists filtered-out jobs, and prints word-frequency suggestions for SOFTWARE_TITLE_RE
- Expanded KEYWORDS and SOFTWARE_TITLE_RE to cover ML/AI, system/applications engineer, director, informatics, and more title variants
- Added `raw` flag to fetchJobs() to bypass the software-role filter
- Add CLAUDE.md with project workflow docs; add CV files and city temp scripts
2026-05-12 13:42:27 +02:00

4.0 KiB

linkme — Claude skill

This project scrapes LinkedIn jobs and filters/ranks them for the user's job search. The user's CV is at polo.md. Always use it when ranking opportunities.


Commands

command what it does
bun fetch scrape Basel area (3 searches), append new jobs to jobs.csv
bun recheck fetch in raw mode, list filtered-out jobs + word-frequency keyword suggestions

Searching any city temporarily

Write a throwaway script (e.g. bern-temp.ts) — never touch config.ts unless the user explicitly asks to save the change.

import { KEYWORDS } from "./config.ts";
import { fetchJobs } from "./fetch.ts";
import type { SearchConfig } from "./config.ts";

const searches: SearchConfig[] = [
  { label: "City Name", keywords: KEYWORDS, location: "City, Switzerland", workType: ["onsite", "hybrid"], timePosted: "month" },
];
// collect, deduplicate, print

Use location: "City, Switzerland" (no geoId) when the geoId is unknown — LinkedIn resolves by name.

Known Swiss geoIds:

  • Basel city: 103383283
  • Basel Metropolitan Area: 90009885
  • Basel-Country: 107117530

Filtering job descriptions by language

Use the bern-langcheck.ts pattern: fetch each job page, extract the description, count German/French indicator words, drop anything with ≥ 6 matches.

const DE_CONTENT_RE = /\b(Sie|Ihre?|Ihnen|Wir|wir|und\s|für|mit\s|von\s|bei\s|das\s|ist\s|sind\s|haben\s|werden\s|können|suchen|bieten|Kenntnisse|Erfahrung|Anforderungen|Aufgaben|Stellenbeschreibung|Stellenangebot|Bewerbung|Ausbildung|Berufserfahrung|Teamarbeit|Quereinsteiger|Vollzeit|Teilzeit|unbefristet|Abschluss|gesucht|Deutsch|Englisch|Schweizer)\b/g;
const FR_CONTENT_RE = /\b(vous|nous|votre|notre|pour\s|avec\s|profil|poste|emploi|entreprise|compétences|expérience|formation|équipe|rejoindre|recherchons|offrons|missions|candidature|CDI|CDD|temps\s+plein|temps\s+partiel)\b/g;

Extract description from class="show-more-less-html__markup", fall back to stripping all HTML. Add 350 ms delay between requests.

Title-only filtering runs during scraping via NON_ENGLISH_RE in fetch.ts. Content-level filtering via isEnglishContent() is now always applied in index.ts before writing to CSV — every new job has its description page fetched and checked.


Ranking jobs against the CV

Read polo.md for the full profile. Key signals to match against:

  • Seniority: Senior / Staff / Principal / Lead / Architect — weight titles accordingly
  • Core stack: Python · TypeScript · Ruby on Rails · React · Node.js
  • Domain strengths: platform engineering · data pipelines · AI/LLM integrations · DevOps (Docker, Kubernetes, CI/CD, AWS)
  • Background edges: fintech/CBDC (Moedax), civic tech (Tactical Tech / GFOSS), independent consulting (ExtraPolo, 40+ projects)
  • Languages: English (full) · German B1 TELC certified · Spanish (full) — flag roles that require C1+ German
  • Location: based in Basel, open to Basel / Bern / Zürich; EU citizen, no permit needed

Output format

Always present jobs as a markdown table with columns: #, Title, Company, Why it fits, Link.

Links use just the job ID as the anchor text:

[4392954199](https://www.linkedin.com/jobs/view/4392954199/)

Workflow for "find jobs in X city"

  1. Write a temp script for that city, run it, collect all passing jobs.
  2. If the user says "English only" or "filter language": run the content-language check script against the results.
  3. Rank survivors against polo.md, present top N as a table.
  4. Delete the temp scripts after the session unless the user asks to keep them.

Workflow for "check if new keywords should be added"

  1. Run bun recheck.
  2. Review the filtered-out list manually — identify false negatives (real software roles that got dropped).
  3. Check the word-frequency suggestions but ignore generic terms (engineer, development, senior).
  4. Propose specific additions to SOFTWARE_TITLE_RE in fetch.ts or words to NON_ENGLISH_RE.