# Where Are Skill Files Located and What Is Their Purpose in the ai-job-search Repository

> Discover where skill files are located in the ai-job-search repository and understand their purpose in defining job-search capabilities for Claude and portal scraping using YAML.

- Repository: [Mads Lorentzen/ai-job-search](https://github.com/MadsLorentzen/ai-job-search)
- Tags: internals
- Published: 2026-08-26

---

**Skill files reside in `.claude/skills/` for Claude-style workflow automation and `.agents/skills/` for portal-specific scraping, serving as modular specifications that define job-search capabilities through YAML metadata and step-by-step instructions.**

The MadsLorentzen/ai-job-search repository implements a thin-pointer architecture described in [`AGENTS.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/AGENTS.md) to organize its automation logic. Understanding where skill files are located and what purpose they serve is essential for extending the job-search workflow or troubleshooting agent behavior. These files act as the single source of truth for all AI-driven capabilities in the project.

## Skill Files Location: The Two Primary Directories

The repository organizes reusable skill definitions in two distinct locations, each serving a different layer of the automation stack.

### Claude-Style Workflow Directory (`.claude/skills/`)

Located at the repository root, the `.claude/skills/` directory houses skills that drive the core job-search workflow orchestration. Each subdirectory—such as `upskill/`, `job-scraper/`, or `job-application-assistant/`—contains a mandatory [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md) file at `/.claude/skills/<skill-name>/SKILL.md`. These files define high-level capabilities that Claude (or compatible agents) execute, including application assistance and skill improvement tasks.

Key files in this directory include:

- **[`.claude/skills/job-application-assistant/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/SKILL.md)** – Defines the core job-application workflow.
- **[`.claude/skills/job-scraper/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-scraper/SKILL.md)** – Orchestrates portal-specific scrapers.
- **[`.claude/skills/upskill/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/upskill/SKILL.md)** – Handles up-skilling and professional development tasks.

### Portal-Specific Agent Directory (`.agents/skills/`)

Parallel to the Claude directory, `.agents/skills/` contains portal-specific implementations for scraping job boards like LinkedIn and Indeed. Following the pattern `/.agents/skills/<portal>/SKILL.md`, these skills expose a minimal command-line interface that other agents invoke to perform targeted searches on specific platforms. For example, [`.agents/skills/linkedin/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.agents/skills/linkedin/SKILL.md) (when present) provides the CLI specification for LinkedIn job searches.

## What Skill Files Are Used For

The purpose of each [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md) extends beyond simple documentation; it functions as an executable contract between human intent and agent behavior. Every file begins with YAML front-matter declaring a `name`, `description`, and optionally an `allowed-tools` list that restricts which scripts or binaries the skill may invoke. This whitelist approach ensures that even if an agent misinterprets instructions, it cannot execute arbitrary code outside the predefined toolset.

The body of the file contains the actual step-by-step instructions that agents follow. According to the repository's thin-pointer architecture, these canonical definitions prevent configuration duplication across the codebase. When you need to modify how the system handles job applications, you edit [`.claude/skills/job-application-assistant/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/SKILL.md), and all dependent agents automatically pick up the changes.

## Automatic Discovery and Validation via [`tools/lint_skills.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/lint_skills.py)

The repository ensures skill integrity through [`tools/lint_skills.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/lint_skills.py), a helper script that automatically discovers all [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md) files under both `.claude/skills/` and `.agents/skills/`. The script globs these directories, parses the YAML front-matter to validate schema compliance, and verifies that every entry in `allowed-tools` references an actual executable file in the repository.

This validation guarantees that skills are well-formed and that the automation toolchain can safely invoke them without encountering missing dependencies. Running the linter from the repository root produces a concise status report:

```bash
python tools/lint_skills.py

# → lint_skills: OK (3 skills, 15 commands, settings.json)

```

## Reading and Executing Skill Files Programmatically

You can extract structured metadata from any skill file by parsing its YAML front-matter. The following Python snippet demonstrates how to load a skill's configuration:

```python
import yaml
from pathlib import Path

skill_path = Path(".claude/skills/job-application-assistant/SKILL.md")
text = skill_path.read_text()
frontmatter = text.split("---")[1]           # extract YAML block

metadata = yaml.safe_load(frontmatter)

print(metadata["name"])          # → "Job Application Assistant"

print(metadata["description"])  # → brief description of the skill

```

To invoke a portal-specific skill from the command line, navigate to the skill directory and execute its CLI wrapper:

```bash

# Invoking the LinkedIn skill

cd .agents/skills/linkedin
./cli/run-search.sh "software engineer"   # runs the CLI defined for LinkedIn

```

## Summary

- Skill files are located in `.claude/skills/` for workflow automation and `.agents/skills/` for portal scraping.
- Each [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md) file combines YAML metadata with executable instructions to define agent capabilities.
- The `allowed-tools` whitelist provides a security boundary that restricts agent execution to predefined binaries.
- The [`tools/lint_skills.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/lint_skills.py) script validates all skills automatically, ensuring schema compliance and tool existence.
- The architecture follows a thin-pointer design for single-source-of-truth configuration management.

## Frequently Asked Questions

### What is the difference between `.claude/skills/` and `.agents/skills/`?

The `.claude/skills/` directory contains high-level workflow skills like `job-application-assistant` that orchestrate the overall job search process, while `.agents/skills/` houses portal-specific implementations such as LinkedIn or Indeed scrapers that provide command-line interfaces for targeted data extraction.

### How does the `allowed-tools` parameter improve security?

The `allowed-tools` YAML key explicitly lists which binaries or scripts a skill may execute, functioning as a whitelist that prevents agents from accidentally or maliciously running unauthorized commands even if they misinterpret the skill's natural language instructions.

### Can I add a new job portal without modifying existing code?

Yes. Create a new subdirectory under `.agents/skills/` named after the portal, add a [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md) file with the required YAML front-matter, and include the portal's CLI tools. The [`tools/lint_skills.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/lint_skills.py) script will automatically discover and validate the new skill on its next run.

### How do I programmatically extract metadata from a skill file?

Parse the [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md) file by reading its contents, splitting on the `---` delimiter to isolate the YAML front-matter, and loading that block with `yaml.safe_load()`. This returns a dictionary containing the skill's `name`, `description`, and `allowed-tools` configuration.