mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-09-17 08:36:25 +00:00
Every PR to this repo is currently verified by hand. This adds the checks
a machine can do:
- latex-smoke: compiles cv/main_example.tex (lualatex) and the new
cover_letters/cover_example.tex (xelatex) in the texlive/texlive
container, failing on any LaTeX error. Exact page-count assertions
(CV=2, cover letter=1) run on the upstream repo only
- lint (tools/lint_skills.py, also runnable locally): every SKILL.md has
parseable YAML frontmatter with name+description (frontmatter breakage
happened before - 37a0eed), allowed-tools 'bun run <path>' targets
exist, command files start with a '# /<name>' title, settings.json is
valid JSON with a permissions.allow list
- cli-typecheck: bun install + tsc --noEmit for all five portal CLIs
(matrix, fail-fast off)
- placeholder-integrity (upstream only): tracked template files still
carry their placeholder tokens, catching accidental personal-data
commits before they land
Fork-friendly by design: /setup personalizes CLAUDE.md, the skill files,
and main_example.tex in forks, so placeholder checks and exact page
counts are guarded with github.repository == upstream; compile success
and lint run everywhere. Live CLI smoke tests are deliberately excluded:
network-flaky, and linkedin-search is personal-use-only per its own ToS
warning - CI-automated requests would violate it. CLIs are typechecked
instead.
The cover letter previously had no tracked example (cover_*.tex is
gitignored), so cover_example.tex is new: a placeholder letter following
the documented 06 structure, demonstrating the correct itemize-outside-
lettercontent pattern. It doubles as the structural reference /apply
Step 2 looks for on fresh clones, which until now matched nothing. The
gitignore exception is ordered after Cover_*.tex because case-insensitive
filesystems match that pattern against cover_example.tex too.
Writing it surfaced a latent bug in the documented template itself:
06-cover-letter-templates.md's structure ends with \closing{Kind
regards,\} - but cover.cls appends its own \, and the doubled break
produces '! LaTeX Error: There's no line here to end.' on every compile
(nonstopmode swallows it, so it went unnoticed). Fixed in 06 and noted
in the example.
62 lines
2.4 KiB
TeX
62 lines
2.4 KiB
TeX
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Cover Letter - [Company], [Role]
|
|
%
|
|
% Example cover letter with placeholder content. This is the structural
|
|
% reference for /apply (see 06-cover-letter-templates.md) and the CI smoke
|
|
% test for cover.cls: it must always compile with xelatex to exactly 1 page.
|
|
% It demonstrates the correct itemize pattern: the list sits OUTSIDE
|
|
% \lettercontent{} (whose trailing \\ errors on \end{itemize}) and is
|
|
% wrapped in Raleway-Medium so the bullet font matches the body.
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
\documentclass[]{cover}
|
|
\usepackage{fancyhdr}
|
|
|
|
\pagestyle{fancy}
|
|
\fancyhf{}
|
|
|
|
\rfoot{Page \thepage \hspace{0pt}}
|
|
\thispagestyle{empty}
|
|
\renewcommand{\headrulewidth}{0pt}
|
|
\begin{document}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% TITLE NAME
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\namesection{}{\Huge{[YOUR NAME]}}{ \href{mailto:your.email@example.com}{your.email@example.com} | [+XX XXXXXXXXXX] | \urlstyle{same}\href{https://www.linkedin.com/in/yourprofile}{LinkedIn}
|
|
}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% MAIN COVER LETTER CONTENT
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
\currentdate{\today}
|
|
\lettercontent{Dear [Hiring Manager / Team],}
|
|
|
|
\lettercontent{[Opening paragraph: name the role and where you found it, state your strongest connection to it in one sentence, and preview why you are a fit. Keep it to 2--3 sentences.]}
|
|
|
|
\lettercontent{[Body paragraph: your most relevant experience, framed toward the tasks in the posting. Follow with 3--5 concrete bullets:]}
|
|
|
|
{\raggedright\fontspec[Path = OpenFonts/fonts/raleway/]{Raleway-Medium}\fontsize{11pt}{13pt}\selectfont
|
|
\begin{itemize}
|
|
\item \textbf{[Achievement 1]:} [concrete result with a number where possible]
|
|
\item \textbf{[Achievement 2]:} [skill or project mapped to a posting requirement]
|
|
\item \textbf{[Achievement 3]:} [evidence for a nice-to-have requirement]
|
|
\end{itemize}\par}
|
|
\vspace{6pt}
|
|
|
|
\lettercontent{[Connection paragraph: why this company specifically. Reference a verified specific: a product, a stated priority, a team. Never generic.]}
|
|
|
|
\lettercontent{[Personal fit paragraph: behavioral strengths and what you bring to the team, 2--3 sentences.]}
|
|
|
|
\lettercontent{I look forward to hearing from you.}
|
|
|
|
\begin{flushright}
|
|
% Note: no trailing \\ inside \closing{} - cover.cls appends its own \\, and a
|
|
% doubled break triggers "There's no line here to end."
|
|
\closing{Kind regards,}
|
|
|
|
\signature{[YOUR NAME]}
|
|
\end{flushright}
|
|
\end{document}
|