How Job Portal Skill Auto-Discovery Works in `.agents/skills/`: A Technical Deep Dive
The AI-Job-Search framework automatically discovers job portal integrations by scanning .agents/skills/*/SKILL.md manifests at runtime, requiring zero registration code for new portals.
The MadsLorentzen/ai-job-search repository implements a plug-and-play skill architecture that treats each job portal as a self-contained module. This design allows the /scrape command to dynamically discover and invoke portal-specific logic without hardcoding integrations or modifying core framework code.
The Four-Step Discovery Mechanism
The auto-discovery system operates through a predictable pipeline that executes every time the scraper runs.
Step 1: Directory Tree Scanning
The framework walks the /.agents/skills/ directory tree, searching for SKILL.md files in each sub-directory. According to the job-scraper skill documentation, this path pattern .agents/skills/*/SKILL.md is the canonical discovery target【/.claude/skills/job-scraper/SKILL.md†L61-L66】.
Step 2: Manifest Parsing
Each SKILL.md serves as a declarative contract specifying:
- CLI commands:
searchanddetailsubcommands - Supported flags: query parameters, location filters, pagination options
- Output formats: JSON, CSV, or structured text
- Enabled flag: boolean
enabled:key controlling activation
The manifest uses YAML syntax for human-readable configuration.
Step 3: Runtime Registration
For every valid and enabled manifest, the scraper loads the corresponding CLI implementation—typically located in a cli/ sub-folder within the same directory—and adds it to the available portal registry. As the README states: "/scrape auto-discovers any installed skill that follows the contract – nothing to register, nothing to wire up"【/README.md†L309】.
Step 4: Dynamic Extension
New portals become immediately discoverable after creation. The /add-portal command scaffolds the required structure, and because discovery re-scans the directory on each run, no restart or rebuild is necessary.
Practical Implementation Examples
Running the Scraper
# Execute scrape across all discovered portal skills
$ ai-job-search /scrape --query "Data Scientist" --location "Berlin, Germany"
Adding a New Portal
# Scaffold a new portal integration
$ ai-job-search /add-portal --name mylocalboard
# Generated structure:
# .agents/skills/mylocalboard/
# ├─ SKILL.md ← manifest declares cli, flags, output format
# └─ cli/ ← implementation of search and detail commands
The skill becomes instantly available to /scrape without framework modifications.
Core Discovery Logic (Simplified)
import pathlib
import yaml
def discover_portal_skills(base_path: str = ".agents/skills") -> list[dict]:
"""
Auto-discover all enabled job portal skills.
Mirrors the actual implementation in MadsLorentzen/ai-job-search.
"""
skills = []
for skill_dir in pathlib.Path(base_path).glob("*/"):
manifest_path = skill_dir / "SKILL.md"
if not manifest_path.is_file():
continue
manifest = yaml.safe_load(manifest_path.read_text())
# Skip disabled skills silently
if not manifest.get("enabled", True):
continue
skills.append({
"name": skill_dir.name,
"cli_path": skill_dir / "cli",
"manifest": manifest,
})
return skills
Key Source Files and Their Roles
| File Path | Purpose |
|---|---|
/README.md |
Documents the auto-discovery contract and /scrape behavior【/README.md†L309】 |
/.claude/skills/job-scraper/SKILL.md |
Specifies the exact discovery algorithm and path pattern【/.claude/skills/job-scraper/SKILL.md†L61-L66】 |
/.agents/skills/<portal>/SKILL.md |
Per-portal manifest declaring CLI interface and enabled status |
/.agents/skills/<portal>/cli/ |
Executable implementation of portal-specific commands |
/CONTRIBUTING.md |
Notes that Codex and Antigravity skills are auto-discovered today【/CONTRIBUTING.md†L57】 |
Design Benefits of Skill Auto-Discovery
This architecture delivers three core advantages:
- Zero registration overhead: New portals require no imports, no registry updates, no central configuration files
- Isolation and safety: Each skill operates in its own directory with explicit interface contracts
- Runtime flexibility: Enable, disable, or modify portals by changing files on disk—no redeployment needed
The enabled: flag in each SKILL.md provides granular control without deleting skill code, supporting A/B testing and gradual rollouts.
Summary
- Discovery target:
.agents/skills/*/SKILL.mdpattern with YAML manifests - Activation criteria: File exists +
enabled: true(defaults to true when omitted) - CLI location: Co-located
cli/directory inside each skill folder - Extension method:
/add-portalscaffold + automatic re-scan on next/scrape - Zero core changes: Framework remains untouched when adding new job portals
Frequently Asked Questions
What happens if a SKILL.md is malformed or missing?
The discovery logic skips invalid entries gracefully. If SKILL.md is absent or contains unparseable YAML, that directory is silently excluded from the skill registry. No errors propagate to halt the scraping process.
Can multiple versions of the same portal skill coexist?
The directory-based naming convention enforces uniqueness at the folder level. Since skill_dir.name becomes the identifier, duplicate portal names would collide. Version management should occur within a single skill's implementation or through git-based deployment strategies.
How does the framework distinguish between job-scraper skills and other skill types?
The /.agents/skills/ path houses job-portal integrations specifically. The job-scraper skill itself resides under /.claude/skills/ and orchestrates discovery. This separation allows other agent capabilities to use distinct discovery mechanisms without interference.
Is there a performance cost to re-scanning on every /scrape invocation?
For typical skill counts (dozens of portals), directory traversal and YAML parsing incur negligible overhead. The CONTRIBUTING guide notes current production usage with Codex and Antigravity skills【/CONTRIBUTING.md†L57】, suggesting the design scales adequately for real-world workloads.
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 →