# Build Tools Used for the ai-job-search Project: Python, Bun, and LaTeX Pipeline

> Discover the build tools for the ai-job-search project: Python for automation, Bun for TypeScript CLI, and LaTeX for documents. Learn how they integrate with GitHub Actions CI.

- Repository: [Mads Lorentzen/ai-job-search](https://github.com/MadsLorentzen/ai-job-search)
- Tags: how-to-guide
- Published: 2026-09-02

---

**The ai-job-search repository combines Python 3.10+ for automation scripting, Bun for TypeScript CLI tooling, and LaTeX (lualatex/xelatex) for document generation, orchestrated through GitHub Actions CI.**

The ai-job-search project by MadsLorentzen relies on a heterogeneous build environment that spans multiple runtimes and compilers. Understanding the build tools used for the ai-job-search project requires examining three distinct layers: the Python automation framework, the JavaScript/TypeScript CLI tooling, and the LaTeX document compilation pipeline. Each layer serves a specific purpose in the job application workflow, from scraping job portals to generating tailored CVs and cover letters.

## Python 3.10+ Runtime and Automation Scripts

The foundation of the project rests on **Python 3.10+**, which powers the core automation utilities located in the `tools/` directory. These scripts handle framework validation, skill linting, and PDF verification.

Key utilities include:

- **[`tools/lint_skills.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/lint_skills.py)** – Validates skill definitions and ensures consistency across job portal integrations
- **[`tools/verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/verify_pdf.py)** – Verifies compiled PDFs using the `pypdf` library or falls back to the `pdftotext` utility from **Poppler**
- **[`tools/check_framework_version.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/check_framework_version.py)** – Validates installed runtime versions during CI checks

The `/apply`, `/scrape`, and `/setup` commands invoked by users are Python-driven entry points that orchestrate the broader toolchain.

## Bun and TypeScript for Job Portal CLIs

The project uses **Bun** as a lightweight JavaScript/TypeScript runtime for job-portal CLI tools located under `.agents/skills/*`. Each skill (such as `jobindex-search`, `linkedin-search`, or `jobbank-search`) contains its own TypeScript CLI package.

### Installing CLI Dependencies

According to the [`README.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/README.md) "Install job search tools" section, users must run `bun install` for each skill directory:

```bash

# From the repository root

for tool in jobbank-search jobdanmark-search jobindex-search \
            jobnet-search linkedin-search freehire-search; do
  (cd .agents/skills/$tool/cli && bun install)
done

```

### Type Checking with tsc

Each skill's [`package.json`](https://github.com/MadsLorentzen/ai-job-search/blob/main/package.json) defines a `typecheck` script that invokes the TypeScript compiler:

```bash
cd .agents/skills/jobindex-search/cli
bun run typecheck        # invokes `tsc --noEmit`

```

This ensures type safety across the JavaScript-based portal integrations without emitting compiled files, maintaining a clean source tree.

## LaTeX Document Compilation Pipeline

The document generation layer relies on **LaTeX** with engine-specific compilation workflows for CVs and cover letters.

### CV Generation with lualatex

The CV template at `cv/main_example.tex` compiles using **lualatex** to produce a two-page PDF:

```bash
lualatex -interaction=nonstopmode cv/main_example.tex

```

### Cover Letter Generation with xelatex

Cover letters use the class file `cover_letters/cover.cls` and compile with **xelatex** for proper font rendering:

```bash
xelatex -interaction=nonstopmode cover_letters/cover_example.tex

```

Both engines are required dependencies listed in [`SETUP.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SETUP.md), as the `/apply` workflow automatically invokes the appropriate compiler based on document type.

## PDF Processing and Verification

After compilation, the system verifies PDF integrity using dual approaches. The **[`tools/verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/verify_pdf.py)** utility first attempts extraction via the **pypdf** library, then falls back to the **`pdftotext`** command-line utility from Poppler if needed. This verification ensures that generated documents contain searchable text layers and meet page-count requirements (two pages for CVs, one page for cover letters).

```python
from tools.verify_pdf import verify_pdf

# Checks page count and extracts searchable text

verify_pdf("output/cv.pdf")

```

## Continuous Integration with GitHub Actions

The **GitHub Actions** workflow defined in [`.github/workflows/ci.yml`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.github/workflows/ci.yml) orchestrates the entire build matrix. The CI pipeline runs:

- LaTeX smoke tests to verify template compilation
- TypeScript type-checking (`bun run typecheck`) across all skill CLIs
- Python linting via [`tools/lint_skills.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/lint_skills.py)

This ensures that changes to any layer of the build system—whether Python automation, TypeScript skills, or LaTeX templates—pass validation before merging.

## Summary

- **Python 3.10+** powers the core automation framework and utility scripts in `tools/`
- **Bun** provides the JavaScript runtime for TypeScript-based job portal CLIs under `.agents/skills/*/cli`
- **TypeScript** (`tsc --noEmit`) enforces type safety via npm-style scripts invoked through Bun
- **LaTeX** engines (**lualatex** for CVs, **xelatex** for cover letters) compile application documents from `.tex` sources
- **GitHub Actions** validates the entire toolchain through automated CI checks

## Frequently Asked Questions

### What version of Python is required for ai-job-search?

The project requires **Python 3.10 or higher** as specified in [`SETUP.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SETUP.md). This version requirement ensures compatibility with modern type hints and standard library features used in the automation scripts.

### Why does the project use Bun instead of Node.js?

The repository uses **Bun** as a lightweight, fast alternative to Node.js for running the job-portal CLI tools. The [`README.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/README.md) specifically instructs users to run `bun install` for each skill, and the [`package.json`](https://github.com/MadsLorentzen/ai-job-search/blob/main/package.json) files in skill directories define Bun-compatible scripts for starting services and running tests.

### How are the CV and cover letter templates compiled?

The build system uses **lualatex** to compile `cv/main_example.tex` into a two-page CV and **xelatex** to compile cover letters using `cover_letters/cover.cls`. These commands run with `-interaction=nonstopmode` for automated pipeline execution, and the engine selection is hardcoded in the `/apply` workflow logic.

### What CI checks run on pull requests?

The **GitHub Actions** workflow ([`.github/workflows/ci.yml`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.github/workflows/ci.yml)) executes three main validation layers: LaTeX compilation smoke tests for document templates, TypeScript type-checking via `bun run typecheck` across all skills, and Python linting using [`tools/lint_skills.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/lint_skills.py) to validate skill definitions.