Main Architectural Components of the AI Job Search System: Thin-Pointer Architecture Explained
The ai-job-search repository implements a thin-pointer architecture that separates declarative specifications in CLAUDE.md from executable portal-specific CLI tools, enabling a fully local, autonomous job application pipeline.
The ai-job-search system is an open-source framework by MadsLorentzen that automates the entire job search workflow using Claude Code. Its architecture follows a thin-pointer design pattern, where workflow logic lives in markdown specifications while external tools handle data extraction and document generation. This separation allows users to customize behavior by editing text files rather than source code.
Core Configuration: The CLAUDE.md Profile
At the heart of the system sits CLAUDE.md, the single source of truth for all agents.
This file stores the candidate's personal data, career goals, and high-level workflow rules that drive every subsequent operation. When you invoke commands like /setup or /apply, Claude Code reads this file to understand the user's context, writing style, and evaluation criteria.
Located at the repository root, CLAUDE.md acts as the declarative specification that all other components reference. According to the source code, this is the only place where candidate-specific workflow logic resides, making the system portable and version-controllable.
Command Interface Layer
The .claude/commands/ directory defines the CLI-style interface that users interact with.
Each command is implemented as a standalone markdown file (e.g., setup.md, apply.md, scrape.md) containing the prompts and instructions Claude Code executes when you type /setup, /scrape, or /apply. This design makes the command layer entirely transparent and editable without touching TypeScript or Python code.
Key commands include:
/setup– PopulatesCLAUDE.mdand initializes thedocuments/folder/scrape– Invokes portal CLI tools to collect job postings/apply– Evaluates fit, drafts LaTeX documents, and compiles PDFs/interview– Prepares interview materials based on job context
Domain Knowledge Engine
The .claude/skills/job-application-assistant/ directory encodes the system's domain expertise.
This skill is broken into numbered markdown sections (including SKILL.md) that cover:
- Candidate profile interpretation
- Writing style guidelines
- Job evaluation frameworks
- CV and cover letter templates
- Interview preparation protocols
When processing applications, Claude Code loads these files to ensure consistent output quality across all generated documents. The skill definition is separate from both the user profile (CLAUDE.md) and the command triggers (.claude/commands/), creating a clean separation of concerns.
Portal Integration Layer
The .agents/skills/ directory contains the search infrastructure for specific job portals.
Each subfolder (e.g., jobindex-search/, linkedin-search/, freehire-search/) houses a tiny TypeScript/Bun CLI tool that knows how to query a particular portal and return normalized JSON results. These tools provide the search layer for the /scrape command and follow a reusable pattern for adding new markets.
For example, the jobindex-search skill queries the Danish JobIndex portal, while linkedin-search handles LinkedIn exports. Each CLI tool operates independently, allowing the system to aggregate postings from multiple sources into a unified workflow.
Utility and Data Infrastructure
Supporting the core workflow are several auxiliary components:
tools/ – Helper scripts for salary benchmarking, skill linting, security guards, and Excel-to-JSON conversion. The lint_skills.py script ensures custom skills adhere to structural requirements.
documents/ – Storage for raw CVs, LinkedIn exports, diplomas, reference letters, and archived applications.
State directories – job_scraper/, gmail_sync/, and upskill/ persist intermediate results (scraped jobs, processed emails, up-skill reports) so commands can be re-run idempotently without data loss.
job_search_tracker.csv – The central spreadsheet recording every application, its status, and associated metadata.
Workflow Execution Model
The architectural components combine to implement a self-contained, language-agnostic pipeline that runs entirely on the user's machine:
/setupinitializes the profile and document structure/scrapeinvokes portal CLI tools (.agents/skills/) to collect and deduplicate postings/applyevaluates fit againstCLAUDE.mdcriteria, drafts LaTeX CVs and cover letters using templates from.claude/skills/, and compiles PDFs/interview,/rank,/outcome, and/upskillextend the loop with interview prep, ranking algorithms, outcome tracking, and learning plan generation
This pattern ensures that .claude/ remains the only location for workflow logic, while external tools merely reference that specification.
Example Command Usage
Commands are executed inside Claude Code's interactive environment:
# Initialize the system and populate CLAUDE.md
claude
> /setup
# Search configured portals for matching positions
claude
> /scrape
# Apply to a specific posting with automated document generation
claude
> /apply https://jobindex.dk/job/1234567
# Generate an offline HTML dashboard of your search progress
claude
> /html-report
Adding new capabilities requires only editing markdown. For example, scaffolding a new portal search tool:
claude
> /add-portal
# (Interactive prompts create a new CLI skill under .agents/skills/)
Summary
CLAUDE.mdserves as the single source of truth for candidate profiles and workflow rules.claude/commands/provides transparent, markdown-based command definitions for the Claude Code interface.claude/skills/job-application-assistant/contains the domain knowledge and templates for document generation.agents/skills/houses portal-specific TypeScript/Bun CLI tools for job scrapingtools/,documents/, andjob_search_tracker.csvprovide auxiliary services and data persistence- The thin-pointer principle ensures workflow logic lives only in
.claude/, making the system maintainable and portable
Frequently Asked Questions
What is the thin-pointer design pattern used in ai-job-search?
The thin-pointer pattern separates declarative specifications (stored in CLAUDE.md and .claude/ markdown files) from executable tooling (TypeScript CLIs in .agents/skills/). This means the workflow logic lives entirely in text files that Claude Code reads, while heavy operations like web scraping execute in separate CLI tools. According to the repository structure, .claude/ is the only place where workflow logic resides, making customization as simple as editing markdown.
How does the system handle different job portals?
Each job portal has its own dedicated CLI tool under .agents/skills/ (such as jobindex-search/ or linkedin-search/). These small TypeScript/Bun applications know how to query their specific portal and return normalized JSON results. When you run /scrape, Claude Code invokes these tools in parallel, aggregates the results, and deduplicates them against job_search_tracker.csv.
Where is my personal data stored in the ai-job-search system?
All candidate-specific data lives in CLAUDE.md at the repository root and in the documents/ folder. CLAUDE.md contains your career goals, writing style preferences, and evaluation criteria, while documents/ stores your CVs, LinkedIn exports, and reference letters. This local-first approach ensures your data never leaves your machine, as implemented in the MadsLorentzen/ai-job-search source code.
Can I add custom LaTeX templates for CV generation?
Yes. The .claude/skills/job-application-assistant/ directory contains the template definitions, and you can add new ones using the /add-template command. This interactive command prompts you for the template path, compile engine, and other metadata, then registers it within the skill structure. All templates are referenced by the /apply command when generating application materials.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →