mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-09-17 00:26:26 +00:00
feat(add-template): make /add-template engine-agnostic (#238)
* feat(add-template): make /add-template engine-agnostic so Typst can register alongside LaTeX /add-template hardcoded a lualatex|xelatex|pdflatex engine enum and .tex assumptions, so custom templates could only be LaTeX. Replace the enum with a declared source extension + compile command, so any toolchain (Typst via `typst compile`, or others) registers the same way stock LaTeX templates did. Stock CV/cover-letter pipeline stays LaTeX and untouched (per #181). Also fixes a latent bug this surfaced: apply.md's compile step ignored the ACTIVE-TEMPLATE block and always ran lualatex/xelatex on .tex regardless of the active template, and .gitignore's cv/main_*.tex pattern would not have ignored a non-.tex draft (personal-data leak). Both now resolve from the declared extension/command. * fix(add-template): satisfy security_guards on the .gitignore Typst fix security_guards.py pins the personal-data ignore rules by exact string and gates negations through an allowlist, so broadening cv/main_*.tex and cover_letters/cover_*.tex to *.* (for .typ drafts) needed a matching update to REQUIRED_IGNORE_RULES. Also tighten the .gitignore itself per review: keep the re-include negations at .tex instead of widening them to *.* too. The stock example files are always LaTeX, so .tex is enough to re-include them, and a wildcard negation would have also re-included build artifacts (main_example.pdf/.aux) that should stay ignored. ALLOWED_IGNORE_NEGATIONS needs no change since the negations are unchanged. Also adds a CHANGELOG entry under Unreleased for the Typst/custom-template support.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# /add-template - Register a Custom CV or Cover Letter Template
|
||||
|
||||
You are helping the user register their own LaTeX template with the AI Job Search framework. The framework ships with moderncv (banking style) for CVs and a custom `cover.cls` for cover letters. This command lets the user swap in their own template: store the template files, capture usage instructions (compile engine, fonts, style rules, page limits), verify the template compiles, and wire it into the `/apply` workflow so every future application uses it.
|
||||
You are helping the user register their own CV or cover letter template with the AI Job Search framework — LaTeX, Typst, or any other toolchain that compiles to PDF from the command line. The framework ships with moderncv (banking style) for CVs and a custom `cover.cls` for cover letters. This command lets the user swap in their own template: store the template files, capture usage instructions (source extension, compile command, fonts, style rules, page limits), verify the template compiles, and wire it into the `/apply` workflow so every future application uses it.
|
||||
|
||||
`$ARGUMENTS` may contain a subcommand, a file path, or nothing.
|
||||
|
||||
@@ -22,9 +22,9 @@ Use Glob with `templates/**/TEMPLATE.md` to find registered templates. For each,
|
||||
```
|
||||
## Registered Templates
|
||||
|
||||
| Name | Type | Engine | Fonts | Active |
|
||||
|------|------|--------|-------|--------|
|
||||
| <name> | CV / Cover letter | lualatex/xelatex/pdflatex | <main font> | yes/no |
|
||||
| Name | Type | Source | Toolchain | Fonts | Active |
|
||||
|------|------|--------|-----------|-------|--------|
|
||||
| <name> | CV / Cover letter | .tex/.typ/... | lualatex/typst/... | <main font> | yes/no |
|
||||
```
|
||||
|
||||
A template is **active** if `05-cv-templates.md` (CV) or `06-cover-letter-templates.md` (cover letter) contains an `ACTIVE-TEMPLATE` managed block naming it. If no custom templates exist, say so and explain that `/add-template` registers one. Stop here.
|
||||
@@ -39,14 +39,16 @@ If `$ARGUMENTS` contains `--use <name>`:
|
||||
4. If more than one manifest matches, stop and list the matching manifest paths. Ask the user to rename one of the templates; activation must be unambiguous.
|
||||
5. Read the matching `TEMPLATE.md` and extract:
|
||||
- **Type:** `CV` or `Cover letter`
|
||||
- **Engine:** `lualatex`, `xelatex`, or `pdflatex`
|
||||
- **Source extension:** e.g. `.tex`, `.typ`
|
||||
- **Compile command:** the full declared command
|
||||
- **Engine/toolchain:** e.g. `lualatex`, `typst` (display label)
|
||||
- **Page limit:** `<N> page(s)`
|
||||
- **Fonts:** the full font summary line
|
||||
6. Derive the template folder from the manifest path and verify `template.tex` exists in the same folder. If it is missing, stop with an error; the template registration is incomplete.
|
||||
6. Derive the template folder from the manifest path and verify `template<source-extension>` exists in the same folder. If it is missing, stop with an error; the template registration is incomplete.
|
||||
7. Derive `<type>` for Step 5 from the manifest path:
|
||||
- `templates/cv/<name>/TEMPLATE.md` -> `cv`
|
||||
- `templates/cover_letters/<name>/TEMPLATE.md` -> `cover_letters`
|
||||
8. Continue to Step 5 using the resolved `<name>`, `<type>`, `<engine>`, font summary, page limit, template skeleton path, and manifest path. Do not re-run Steps 1-4; `--use` switches an already-registered template.
|
||||
8. Continue to Step 5 using the resolved `<name>`, `<type>`, `<source-extension>`, `<compile-command>`, engine/toolchain label, font summary, page limit, template skeleton path, and manifest path. Do not re-run Steps 1-4; `--use` switches an already-registered template.
|
||||
|
||||
---
|
||||
|
||||
@@ -56,28 +58,32 @@ Ask the user (skip anything already answered by `$ARGUMENTS`):
|
||||
|
||||
1. **Type:** Is this a **CV** template or a **cover letter** template?
|
||||
2. **Source:** Where is the template? Accept any of:
|
||||
- A path or @-mention of a `.tex` file (plus optional `.cls`/`.sty` files)
|
||||
- Pasted LaTeX content
|
||||
- A directory containing the template and its assets (class files, fonts, images)
|
||||
- A path or @-mention of a source file in any toolchain (`.tex` plus optional `.cls`/`.sty`, `.typ` plus optional local packages, or another compile-to-PDF format)
|
||||
- Pasted template content
|
||||
- A directory containing the template and its assets (class/package files, fonts, images)
|
||||
|
||||
Read every provided file. If the template references a document class or package that is not part of standard TeX distributions (e.g. a custom `.cls`), confirm the user has the file and ask for it if missing — the template cannot compile without it.
|
||||
Read every provided file. If the template references an include the declared toolchain doesn't ship by default — a custom `.cls`/`.sty` not part of standard TeX distributions, a Typst package imported via a local `#import`, or an equivalent for another toolchain — confirm the user has the file and ask for it if missing — the template cannot compile without it.
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Capture Template Instructions
|
||||
|
||||
Interview the user for the metadata that `/apply` needs to use the template correctly. Infer as much as possible from the LaTeX source first (documentclass, `\fontspec` calls, geometry, colors) and present your inferences for confirmation rather than asking blind questions.
|
||||
Interview the user for the metadata that `/apply` needs to use the template correctly. Infer as much as possible from the source first (LaTeX: documentclass, `\fontspec` calls, geometry, colors; Typst: `#set`/`#show` rules, `#import`s; other toolchains: whatever the format exposes) and present your inferences for confirmation rather than asking blind questions.
|
||||
|
||||
Collect:
|
||||
|
||||
1. **Name** - short kebab-case identifier (e.g. `awesome-cv`, `classic-serif`). Must not collide with an existing folder in `templates/`.
|
||||
2. **Compile engine** - `lualatex`, `xelatex`, or `pdflatex`. If the source uses `fontspec` or loads font files by path, it requires `xelatex` or `lualatex`; tell the user this rather than letting them pick `pdflatex`.
|
||||
3. **Fonts** - which font(s) the template uses and where they come from:
|
||||
- **Bundled font files** (`.ttf`/`.otf` shipped with the template): copy them into the template folder in Step 3 and record the relative `Path` used in `\fontspec` calls.
|
||||
- **System / TeX-distribution fonts**: record the font name and note that the user's machine must have it installed.
|
||||
4. **Style rules** - anything the drafter must preserve when filling the template: color scheme, section order, heading style, spacing conventions, bullet formatting, date format.
|
||||
5. **Page limit** - hard page count for the compiled PDF. Default: **2 pages** for a CV, **1 page** for a cover letter. `/apply`'s compile-and-inspect loop enforces this.
|
||||
6. **Known pitfalls** (optional) - macros that break with certain content (like the stock template's `\lettercontent{}`/`itemize` interaction), characters that need escaping, sections that must not be reordered.
|
||||
2. **Source extension** - the main file's extension (`.tex`, `.typ`, ...), inferred from the provided source file.
|
||||
3. **Compile command** - the full command `/apply` and Step 4's test compile will run, using `<file>` (no extension) as the placeholder for the output basename:
|
||||
- **`.tex` source**: infer the engine the same way as before - if the source uses `fontspec` or loads font files by path, it requires `xelatex` or `lualatex`; tell the user this rather than letting them pick `pdflatex`. Render as `lualatex -interaction=nonstopmode <file>.tex` (or the appropriate engine).
|
||||
- **`.typ` source**: default to `typst compile <file>.typ <file>.pdf` - Typst has a single binary, no engine choice.
|
||||
- **Anything else**: no built-in guidance; ask the user for the exact compile command.
|
||||
4. **Fonts** - which font(s) the template uses and where they come from:
|
||||
- **Bundled font files** (`.ttf`/`.otf` shipped with the template): copy them into the template folder in Step 3 and record the relative path used to load them (LaTeX `\fontspec` `Path`, Typst `#import`/font path, or equivalent).
|
||||
- **System / distribution fonts**: record the font name and note that the user's machine must have it installed.
|
||||
5. **Style rules** - anything the drafter must preserve when filling the template: color scheme, section order, heading style, spacing conventions, bullet formatting, date format.
|
||||
6. **Page limit** - hard page count for the compiled PDF. Default: **2 pages** for a CV, **1 page** for a cover letter. `/apply`'s compile-and-inspect loop enforces this.
|
||||
7. **Known pitfalls** (optional) - macros/rules that break with certain content (like the stock template's `\lettercontent{}`/`itemize` interaction), characters that need escaping, sections that must not be reordered.
|
||||
|
||||
---
|
||||
|
||||
@@ -90,23 +96,24 @@ Create the template folder:
|
||||
|
||||
Write into it:
|
||||
|
||||
1. **`template.tex`** - the template skeleton. Replace all personal data in the source with `[PLACEHOLDER]` tokens (`[YOUR_NAME]`, `[YOUR_EMAIL]`, `[YOUR_PHONE]`, `[YOUR_LINKEDIN_URL]`, ...) so the template is shareable and profile-agnostic. Keep the structure, preamble, and styling exactly as provided.
|
||||
2. **Class/style files** - copy any `.cls`/`.sty` files alongside `template.tex`.
|
||||
3. **`fonts/`** - copy bundled font files here, preserving any directory layout the `\fontspec` `Path` options expect. Adjust `Path` values in `template.tex` to be relative to the template folder.
|
||||
1. **`template<source-extension>`** (e.g. `template.tex`, `template.typ`) - the template skeleton. Replace all personal data in the source with `[PLACEHOLDER]` tokens (`[YOUR_NAME]`, `[YOUR_EMAIL]`, `[YOUR_PHONE]`, `[YOUR_LINKEDIN_URL]`, ...) so the template is shareable and profile-agnostic. Keep the structure, preamble, and styling exactly as provided.
|
||||
2. **Class/style/package files** - copy any companion files (`.cls`/`.sty` for LaTeX, local Typst packages, or equivalents) alongside the skeleton.
|
||||
3. **`fonts/`** - copy bundled font files here, preserving any directory layout the toolchain's font-loading mechanism expects (LaTeX `\fontspec` `Path`, Typst font path, ...). Adjust those path values in the skeleton to be relative to the template folder.
|
||||
4. **`TEMPLATE.md`** - the manifest. Use exactly this format:
|
||||
|
||||
```markdown
|
||||
# Template: <name>
|
||||
|
||||
- **Type:** CV | Cover letter
|
||||
- **Engine:** lualatex | xelatex | pdflatex
|
||||
- **Source extension:** .tex | .typ | ...
|
||||
- **Engine/toolchain:** lualatex | xelatex | pdflatex | typst | <other> (display label only)
|
||||
- **Page limit:** <N> page(s)
|
||||
- **Fonts:** <main font> (<bundled in fonts/ | system font - must be installed>)
|
||||
- **Class/packages:** <documentclass and any non-standard packages, or "standard">
|
||||
- **Class/packages:** <documentclass/imports and any non-standard packages, or "standard">
|
||||
|
||||
## Compile command
|
||||
|
||||
cd <output dir> && <engine> -interaction=nonstopmode <file>.tex
|
||||
cd <output dir> && <the full declared command, e.g. lualatex -interaction=nonstopmode <file>.tex or typst compile <file>.typ <file>.pdf>
|
||||
|
||||
## Style rules
|
||||
|
||||
@@ -122,16 +129,16 @@ Write into it:
|
||||
|
||||
## Step 4: Verify the Template Compiles (MANDATORY)
|
||||
|
||||
Never register a template without a successful test compile. LaTeX templates that "look fine" routinely fail on missing fonts, missing classes, or engine mismatches.
|
||||
Never register a template without a successful test compile. Templates that "look fine" routinely fail on missing fonts, missing classes/packages, or a wrong compile command.
|
||||
|
||||
1. Copy `template.tex` to a scratch file in the same folder (e.g. `_compile_test.tex`) and fill every `[PLACEHOLDER]` with realistic dummy data (name, contact line, one education entry, one job entry with 3 bullets — enough content to exercise the layout).
|
||||
2. Compile with the declared engine:
|
||||
1. Copy `template<source-extension>` to a scratch file in the same folder (e.g. `_compile_test.tex` or `_compile_test.typ`) and fill every `[PLACEHOLDER]` with realistic dummy data (name, contact line, one education entry, one job entry with 3 bullets — enough content to exercise the layout).
|
||||
2. Compile with the declared compile command, substituting `_compile_test` for `<file>`:
|
||||
```bash
|
||||
cd templates/<type>/<name> && <engine> -interaction=nonstopmode _compile_test.tex
|
||||
cd templates/<type>/<name> && <declared compile command with <file> -> _compile_test>
|
||||
```
|
||||
3. If the compile fails: show the user the relevant error lines, diagnose (missing font file, wrong engine, missing class), fix what you can (e.g. font `Path` values), and re-compile. If the fix needs input only the user has (a missing font file, a license-restricted class), ask for it and wait.
|
||||
4. On success, Read the PDF and confirm the layout renders sensibly (no overlapping text, fonts loaded, page count plausible for dummy content). Record any surprises in the manifest's "Known pitfalls".
|
||||
5. Delete the scratch files and generated artifacts for the test compile: `_compile_test.tex`, `_compile_test.pdf`, `_compile_test.aux`, `_compile_test.log`, `_compile_test.out`, `_compile_test.fls`, `_compile_test.fdb_latexmk`, `_compile_test.synctex.gz`, and any other `_compile_test.*` byproducts.
|
||||
3. If the compile fails: show the user the relevant error lines, diagnose (missing font file, wrong engine/command, missing class or package), fix what you can (e.g. font path values), and re-compile. If the fix needs input only the user has (a missing font file, a license-restricted class), ask for it and wait.
|
||||
4. On success, confirm a PDF was produced and Read it to check the layout renders sensibly (no overlapping text, fonts loaded, page count matches the declared page limit for the dummy content). Record any surprises in the manifest's "Known pitfalls".
|
||||
5. Delete the scratch source file, the scratch PDF, and any other intermediate files the compile command produced (LaTeX toolchains typically leave `_compile_test.aux`/`.log`/`.out`/`.fls`/`.fdb_latexmk`/`.synctex.gz`; other toolchains may leave nothing beyond the PDF — check what actually landed in the folder and remove all `_compile_test.*` byproducts).
|
||||
|
||||
Do not proceed to Step 5 until the test compile passes.
|
||||
|
||||
@@ -139,7 +146,7 @@ Do not proceed to Step 5 until the test compile passes.
|
||||
|
||||
## Step 5: Activate the Template
|
||||
|
||||
Activation wires the template into `/apply` by adding a **managed block** to the top of the relevant guidance file — `05-cv-templates.md` for CVs, `06-cover-letter-templates.md` for cover letters. `/apply` reads these files in its drafting step, so the block is all it takes.
|
||||
Activation wires the template into `/apply` by adding a **managed block** to the top of the relevant guidance file — `05-cv-templates.md` for CVs, `06-cover-letter-templates.md` for cover letters. `/apply` reads these files in both its drafting step and its compile step, so the block is all it takes.
|
||||
|
||||
If Step 5 was reached from Switch Mode, use the template metadata resolved from `TEMPLATE.md`. If Step 5 was reached after registering a new template, use the metadata collected and verified in Steps 2-4.
|
||||
|
||||
@@ -151,12 +158,13 @@ Insert (or replace, if one exists) this block immediately after the file's H1 ti
|
||||
>
|
||||
> A custom template is active. Where this block conflicts with the stock guidance below, this block wins. Structural advice below (tailoring, page-budget, cutting rules) still applies.
|
||||
>
|
||||
> - **Template skeleton:** `templates/<type>/<name>/template.tex` — use this as the structural reference instead of the stock template
|
||||
> - **Template skeleton:** `templates/<type>/<name>/template<source-extension>` — use this as the structural reference instead of the stock template
|
||||
> - **Manifest:** `templates/<type>/<name>/TEMPLATE.md` — read this for style rules and known pitfalls before drafting
|
||||
> - **Compile with:** `<engine>` (not the engine named in the stock guidance below)
|
||||
> - **Fonts:** <font summary, including any Path note for bundled fonts>
|
||||
> - **Source extension:** `<source-extension>` (not `.tex` unless the template's own toolchain is LaTeX)
|
||||
> - **Compile command:** `<the full declared command>` (not the command named in the stock guidance below — `/apply`'s compile step must use this instead)
|
||||
> - **Fonts:** <font summary, including any path note for bundled fonts>
|
||||
> - **Page limit:** exactly <N> page(s)
|
||||
> - **Output file:** unchanged (`cv/main_<company>_<role>.tex` / `cover_letters/cover_<company>_<role>.tex`); copy any class/font files the template needs into the output directory, or reference them by relative path
|
||||
> - **Output file:** `cv/main_<company>_<role><source-extension>` / `cover_letters/cover_<company>_<role><source-extension>`; copy any class/package/font files the template needs into the output directory, or reference them by relative path
|
||||
<!-- END ACTIVE-TEMPLATE -->
|
||||
```
|
||||
|
||||
@@ -174,8 +182,8 @@ Present a summary:
|
||||
|
||||
> **Template `<name>` registered and activated.**
|
||||
>
|
||||
> - Files: `templates/<type>/<name>/` (skeleton, manifest<, class files><, fonts>)
|
||||
> - Test compile: passed with `<engine>` (<N> page(s))
|
||||
> - Files: `templates/<type>/<name>/` (skeleton, manifest<, class/package files><, fonts>)
|
||||
> - Test compile: passed with `<compile command>` (<N> page(s))
|
||||
> - `/apply` will now draft <CVs | cover letters> from this template.
|
||||
>
|
||||
> Useful follow-ups:
|
||||
|
||||
+23
-18
@@ -14,7 +14,7 @@ This rule is the input side of the Step 3 Factual Grounding Audit, not a competi
|
||||
- Never re-Read a file whose contents are already in your context from an earlier step. If you read it in Step 1, it is still available in Step 2.
|
||||
- When dispatching the reviewer agent, pass draft content **inline in the agent prompt** rather than asking the agent to Read files you already have in memory.
|
||||
- Run the full verification checklist exactly once, at the end (Step 6). The reviewer focuses on content critique, not verification.
|
||||
- Step 5 (compile and inspect PDFs) is mandatory and non-skippable — LaTeX page-break decisions are unpredictable, and `.tex` files that look fine often produce broken PDFs (orphaned entry titles, cover letters spilling to page 2, bullet fonts mismatching).
|
||||
- Step 5 (compile and inspect PDFs) is mandatory and non-skippable — page-break decisions are unpredictable, and source files that look fine often produce broken PDFs (orphaned entry titles, cover letters spilling to page 2, bullet fonts mismatching).
|
||||
|
||||
---
|
||||
|
||||
@@ -66,9 +66,11 @@ Read only the reference files you do not yet have:
|
||||
- `.claude/skills/job-application-assistant/05-cv-templates.md`
|
||||
- `.claude/skills/job-application-assistant/06-cover-letter-templates.md`
|
||||
|
||||
**Resolve the active template (do this once, reuse everywhere below):** if `05-cv-templates.md` or `06-cover-letter-templates.md` opens with an `ACTIVE-TEMPLATE` managed block (inserted by `/add-template`), read its declared **source extension** and **compile command** — these override the stock `.tex`/lualatex (CV) and `.tex`/xelatex (cover letter) defaults for the rest of this workflow. Call these `<CV_EXT>`/`<CV_COMPILE>` and `<COVER_EXT>`/`<COVER_COMPILE>`; where no block is present, they default to `.tex`, the stock lualatex command, and the stock xelatex command respectively. Every `.tex` reference below is really `<CV_EXT>` or `<COVER_EXT>` — stock behavior is unchanged, this only matters when a custom template is active.
|
||||
|
||||
Also read the most recent existing CV and cover letter files for concrete structural reference (one of each is enough):
|
||||
- Read any existing `cv/main_*.tex` file as a LaTeX template reference
|
||||
- Read any existing `cover_letters/cover_*.tex` or `cover_letters/Cover_*.tex` file as a template reference
|
||||
- Read any existing `cv/main_*<CV_EXT>` file as a structural reference
|
||||
- Read any existing `cover_letters/cover_*<COVER_EXT>` or `cover_letters/Cover_*<COVER_EXT>` file as a structural reference
|
||||
|
||||
*The master candidate profile (`01-candidate-profile.md`), the master CV (`cv/main_example.tex`), and CLAUDE.md's Candidate Profile section are the sole source of truth for facts; existing tailored CVs may be read for structure and phrasing only, never as a source of claims.*
|
||||
|
||||
@@ -77,7 +79,7 @@ Also read the most recent existing CV and cover letter files for concrete struct
|
||||
- **Engage nice-to-haves by name** where the profile supports honest adjacency (e.g. "conceptually aligned with <named tool>"), and use the posting's own term over a synonym wherever it is truthfully applicable - including in CV section headings (a posting hiring for "MLOps" should find a heading containing "MLOps", not only a paraphrase).
|
||||
- **Address stated logistics and prerequisites** in the cover letter where the posting raises them: security clearance willingness, start date or availability, commute or location fit, and the posting's reference/job ID where one exists. When the employer operates across several countries, a truthful language-capabilities sentence mapped to their footprint is high-value targeting.
|
||||
|
||||
### CV (`cv/main_<company>_<role>.tex`)
|
||||
### CV (`cv/main_<company>_<role><CV_EXT>`)
|
||||
- In the **CV language from the profile** (the `CV language:` line in CLAUDE.md's Identity section). When the profile does not set one, default to **English**. Never switch language per posting - the CV language is a profile-level choice, so all CVs stay consistent and reusable
|
||||
- Follow the moderncv/banking format from `05-cv-templates.md`
|
||||
- Tailor the profile statement and experience bullets to the specific role
|
||||
@@ -85,7 +87,7 @@ Also read the most recent existing CV and cover letter files for concrete struct
|
||||
- Keep to 2 pages
|
||||
- **Grounding Audit:** Before writing to disk, audit all tailored bullet points against the union of three sources: `.claude/skills/job-application-assistant/01-candidate-profile.md` + the master CV (`cv/main_example.tex`) + `CLAUDE.md`'s Candidate Profile section to verify that all dates, roles, and metrics match exactly (zero profile drift or fabrication).
|
||||
|
||||
### Cover Letter (`cover_letters/cover_<company>_<role>.tex`)
|
||||
### Cover Letter (`cover_letters/cover_<company>_<role><COVER_EXT>`)
|
||||
- **Match the language of the job posting** (Danish posting -> Danish cover letter, English posting -> English cover letter)
|
||||
- Follow the structure from `06-cover-letter-templates.md`
|
||||
- Use the `cover.cls` template
|
||||
@@ -100,7 +102,7 @@ Write both files to disk. Keep the exact text of both drafts in working memory
|
||||
|
||||
## Step 3: REVIEWER - Research & Critique
|
||||
|
||||
Use the **Agent tool** to spawn a `general-purpose` reviewer agent. The reviewer gets a fresh context, so pass the drafts **inline in the prompt** below (do not make the reviewer Read them). Scope the reviewer's file reads to content-critique essentials only — the reviewer does not need the LaTeX template files (`05`, `06`) to critique content, since those govern structural/LaTeX concerns the drafter already applied.
|
||||
Use the **Agent tool** to spawn a `general-purpose` reviewer agent. The reviewer gets a fresh context, so pass the drafts **inline in the prompt** below (do not make the reviewer Read them). Scope the reviewer's file reads to content-critique essentials only — the reviewer does not need the template structure files (`05`, `06`) to critique content, since those govern structural/toolchain concerns the drafter already applied.
|
||||
|
||||
Replace `<COMPANY>`, `<ROLE>`, `<INSERT_JOB_POSTING_TEXT_HERE>`, `<INSERT_CV_DRAFT_HERE>`, and `<INSERT_COVER_LETTER_DRAFT_HERE>` with actual values before dispatching.
|
||||
|
||||
@@ -128,7 +130,7 @@ Read these reference files — and only these — to ground your critique:
|
||||
- The master CV baseline template (`cv/main_example.tex`)
|
||||
- The workspace root `CLAUDE.md` file (specifically the Candidate Profile section)
|
||||
|
||||
Do NOT read `05-cv-templates.md` or `06-cover-letter-templates.md` — those govern LaTeX structure the drafter already applied and are not needed for content critique.
|
||||
Do NOT read `05-cv-templates.md` or `06-cover-letter-templates.md` — those govern template structure the drafter already applied and are not needed for content critique.
|
||||
|
||||
### 3. Factual Grounding Audit
|
||||
Compare every date, employer, job title, and quantitative metric in both drafts against the union of three sources: `.claude/skills/job-application-assistant/01-candidate-profile.md` + the master CV baseline template (`cv/main_example.tex`) + `CLAUDE.md`'s Candidate Profile section. A claim is grounded if ANY of these sources supports it. Mismatches between these three sources themselves must be reported to the user as a profile-consistency warning rather than treated as draft drift. Draft mismatches must be flagged as Part A edits with `"reason": "grounding"` so they can be distinguished from style changes. Keep the tolerance honest: reframed emphasis is fine; changed facts and escalated numbers are not.
|
||||
@@ -136,11 +138,11 @@ Compare every date, employer, job title, and quantitative metric in both drafts
|
||||
### 4. Drafts to Review
|
||||
Both drafts are provided inline below. Do NOT use the Read tool on the draft files — use these exact texts.
|
||||
|
||||
<CV_DRAFT file="cv/main_<COMPANY>_<ROLE>.tex">
|
||||
<CV_DRAFT file="cv/main_<COMPANY>_<ROLE><CV_EXT>">
|
||||
<INSERT_CV_DRAFT_HERE>
|
||||
</CV_DRAFT>
|
||||
|
||||
<COVER_LETTER_DRAFT file="cover_letters/cover_<COMPANY>_<ROLE>.tex">
|
||||
<COVER_LETTER_DRAFT file="cover_letters/cover_<COMPANY>_<ROLE><COVER_EXT>">
|
||||
<INSERT_COVER_LETTER_DRAFT_HERE>
|
||||
</COVER_LETTER_DRAFT>
|
||||
|
||||
@@ -157,7 +159,7 @@ Return your feedback in **two parts**:
|
||||
A JSON array of concrete edits the drafter can apply directly without re-reading the files. Each edit is an object:
|
||||
```json
|
||||
{
|
||||
"file": "cv/main_<COMPANY>_<ROLE>.tex" | "cover_letters/cover_<COMPANY>_<ROLE>.tex",
|
||||
"file": "cv/main_<COMPANY>_<ROLE><CV_EXT>" | "cover_letters/cover_<COMPANY>_<ROLE><COVER_EXT>",
|
||||
"old_string": "<exact text currently in the draft>",
|
||||
"new_string": "<replacement text>",
|
||||
"reason": "<one-line rationale: keyword match / company angle / reframing / style / grounding>"
|
||||
@@ -200,17 +202,20 @@ After all edits are applied, the two files on disk are the final drafts.
|
||||
|
||||
## Step 5: DRAFTER - Compile & Inspect PDFs (MANDATORY)
|
||||
|
||||
**Never skip this step.** The `.tex` files looking fine is not sufficient — LaTeX page-break decisions are unpredictable and commonly produce broken layouts (orphaned job titles separated from their bullets, cover letters spilling to 2 pages, bullet fonts not matching body text). Compile both documents and visually verify the PDFs before presenting.
|
||||
**Never skip this step.** The source files looking fine is not sufficient — page-break decisions are unpredictable and commonly produce broken layouts (orphaned job titles separated from their bullets, cover letters spilling to 2 pages, bullet fonts not matching body text). Compile both documents and visually verify the PDFs before presenting.
|
||||
|
||||
### 5a. Compile
|
||||
|
||||
Use `<CV_COMPILE>` and `<COVER_COMPILE>` resolved in Step 2 (the active template's declared compile command, or the stock defaults below if no custom template is active):
|
||||
|
||||
```bash
|
||||
cd cv && lualatex -interaction=nonstopmode main_<company>_<role>.tex
|
||||
cd ../cover_letters && xelatex -interaction=nonstopmode cover_<company>_<role>.tex
|
||||
```
|
||||
|
||||
- CV uses **lualatex** — pdflatex fails on modern MiKTeX with fontawesome5 font-expansion errors. lualatex handles the same sources cleanly.
|
||||
- Cover letter uses **xelatex** — cover.cls requires fontspec.
|
||||
- **Stock CV** uses **lualatex** — pdflatex fails on modern MiKTeX with fontawesome5 font-expansion errors. lualatex handles the same sources cleanly.
|
||||
- **Stock cover letter** uses **xelatex** — cover.cls requires fontspec.
|
||||
- **Custom template active:** run its declared `<CV_COMPILE>`/`<COVER_COMPILE>` command instead, substituting the actual filename for `<file>`. Never fall back to lualatex/xelatex when a custom template's compile command is a different toolchain (e.g. `typst compile`) — that command is what the manifest actually verified in `/add-template` Step 4.
|
||||
|
||||
If either compile fails, fix the error and re-compile until clean.
|
||||
|
||||
@@ -231,7 +236,7 @@ Read both PDFs via the Read tool and verify:
|
||||
|
||||
### 5c. Iterate until clean
|
||||
|
||||
If the layout has problems, edit the `.tex` files and recompile. Common fixes (see `05-cv-templates.md` and `06-cover-letter-templates.md` for full details):
|
||||
If the layout has problems, edit the source files (`<CV_EXT>`/`<COVER_EXT>`) and recompile. Common fixes below are **LaTeX-specific** (stock templates, or a custom LaTeX template) — see `05-cv-templates.md` and `06-cover-letter-templates.md` for full details, and consult the active template's own manifest ("Known pitfalls") for a non-LaTeX toolchain:
|
||||
|
||||
- **Orphaned CV entry title:** `\usepackage{needspace}` in preamble, then `\needspace{5\baselineskip}` immediately before the problematic `\cventry`
|
||||
- **CV spills to page 3 with only a trailing section:** `\enlargethispage{2-3\baselineskip}` before a late section
|
||||
@@ -262,7 +267,7 @@ Read the `.txt` file.
|
||||
- [ ] **Reading order matches the visual order** — section headings appear in the same sequence as on the page, and lines from different sections are not interleaved. The stock banking template is single-column and safe; custom templates registered via `/add-template` with sidebars or multi-column layouts are where this breaks.
|
||||
- [ ] **Dates recognizable** — each role and degree has its years present in the extraction.
|
||||
|
||||
Failures here are template-level problems: fix them in the `.tex` (e.g. print the email as text rather than icon-only), then re-run 5a–5c and re-extract. If a custom template's layout fundamentally scrambles extraction order, tell the user prominently — they may be trading ATS compatibility for looks.
|
||||
Failures here are template-level problems: fix them in the `<CV_EXT>` source (e.g. print the email as text rather than icon-only), then re-run 5a–5c and re-extract. If a custom template's layout fundamentally scrambles extraction order, tell the user prominently — they may be trading ATS compatibility for looks.
|
||||
|
||||
**3. Keyword coverage.** Reuse the required/preferred keyword list you extracted in Step 1 — do not re-derive it. Match each keyword against the extracted text, **in the posting's language** (when the posting's language differs from the CV language — e.g. a Danish posting against an English CV — a concept the CV legitimately covers in its own language counts as synonym-only; note the language difference). Report a table:
|
||||
|
||||
@@ -279,7 +284,7 @@ Failures here are template-level problems: fix them in the `.tex` (e.g. print th
|
||||
|
||||
### 5e. Clean up build artifacts
|
||||
|
||||
After the final clean compile, delete the `.aux`, `.log`, `.out` files (keep the `.tex` and `.pdf`).
|
||||
After the final clean compile, delete intermediate build files the compile command left behind — LaTeX toolchains leave `.aux`/`.log`/`.out`; a custom template's toolchain may leave nothing beyond the PDF. Keep the source file and the `.pdf`.
|
||||
|
||||
---
|
||||
|
||||
@@ -299,8 +304,8 @@ Summarize 3-5 key decisions made to tailor the application:
|
||||
|
||||
### Files Created
|
||||
List the files written:
|
||||
- `cv/main_<company>_<role>.tex`
|
||||
- `cover_letters/cover_<company>_<role>.tex`
|
||||
- `cv/main_<company>_<role><CV_EXT>`
|
||||
- `cover_letters/cover_<company>_<role><COVER_EXT>`
|
||||
|
||||
Tell the user: "Both files are ready for your review. Open them to check the final output before compiling."
|
||||
|
||||
|
||||
Reference in New Issue
Block a user