How /add-portal Scaffolds New Job Portal Search Skills for Different Markets
The /add-portal command is a guided, country-agnostic CLI generator that creates production-ready portal search skills by interviewing the user, investigating the target site, and scaffolding a TypeScript CLI that validates against live data before registration.
The ai-job-search repository provides a modular framework for automating job discovery across global markets. The /add-portal command, specified in .claude/commands/add-portal.md, implements a rigorous seven-step workflow to scaffold new job portal search skills that integrate directly into the existing scraping pipeline. This approach ensures every skill adheres to a strict architectural contract and validates against real-world data before deployment.
The Seven-Step Scaffold Workflow
The generator follows a strict, sequential process implemented in the command specification, with each step enforced by the repository's architecture.
Step 0: Argument Parsing and Discovery
When you invoke /add-portal, the generator first checks for the --list flag or a supplied portal URL. If --list is provided, it globs .agents/skills/*/SKILL.md to enumerate existing skills (e.g., jobindex-search, linkedin-search). Otherwise, it initiates the interactive interview process.
Step 1: Interview and Naming Conventions
The generator queries for the portal URL, desired skill name, target market/language, and a realistic test query. It enforces kebab-case naming with the mandatory -search suffix and validates against name collisions in .agents/skills/ to prevent overwriting existing implementations.
Step 2: Portal Investigation
The tool performs live HTTP fetches (or curl via Bash) to capture the portal's search endpoint, result fields, and detail-page patterns. It records these findings in url-reference.md and checks robots.txt and terms of service compliance before proceeding.
Step 3: Skill Scaffolding from Reference
Using .agents/skills/linkedin-search/ as the canonical reference implementation, the generator creates a new directory at .agents/skills/<name>/ containing:
SKILL.md— Description, trigger phrases, usage examples, and personal-use warningsurl-reference.md— Documented endpoints and field selectors for future maintainerscli/— Complete TypeScript project withpackage.json,tsconfig.json,src/cli.ts, helper modules, and command implementationstests/— Smoke-test suite for validation
Step 4: Mandatory Live Validation
Before the skill is considered complete, the generator installs dev dependencies, type-checks the code, and executes a real search using the user's test query via bun run src/cli.ts search. It validates the JSON output shape { meta, results } and tests the detail command with bun run src/cli.ts detail. This ensures the skill only ships after proven functionality against live data.
Step 5: Pipeline Registration
Optionally, the generator inserts the new portal into .claude/skills/job-scraper/search-queries.md, enabling the /scrape command to automatically include results from the new source without additional wiring.
Step 6: Confirmation and Summary
The command prints a concise confirmation block showing the skill location, test results, and a one-line command to run the new skill manually.
The Portal Skill Contract
Every generated skill adheres to a strict contract defined in the specification to ensure interoperability across the codebase:
- Commands:
searchanddetail <id|url> - Flags:
--query/-q,--jobage,--page,--limit,--format(acceptingjson,table, orplain), and optional--location - Output Structure: JSON containing
metaandresultsarrays, with each result includingid,title,company,location,date, andurl - Error Handling: Errors emitted on stderr as JSON with exit code 1
- Dependencies: Zero runtime dependencies by default, using only
bun+fetch+ regex parsing
Practical Usage Examples
List existing portal skills
/add-portal --list
This displays a table of installed skills by scanning .agents/skills/*/SKILL.md.
Scaffold a skill for a foreign market
/add-portal https://www.seek.com.au
The generator will interactively request:
- Skill name:
seek-search(enforced kebab-case with-searchsuffix) - Market/language: Australia / English
- Test query: Software Engineer
Run the generated skill manually
bun run .agents/skills/seek-search/cli/src/cli.ts search -q "Software Engineer" --limit 5 --format table
Fetch specific job details:
bun run .agents/skills/seek-search/cli/src/cli.ts detail <job-id> --format plain
Register for automatic scraping
Add the portal to .claude/skills/job-scraper/search-queries.md:
- https://www.seek.com.au/jobs?q=Software+Engineer
Once registered, /scrape automatically includes results from your new portal alongside existing sources.
Summary
/add-portalcreates production-ready skills in.agents/skills/<name>/using thelinkedin-searchreference implementation as a template- The workflow requires mandatory live validation (Step 4) before considering the skill complete, ensuring robust parsing logic
- Generated skills follow a strict contract with standardized
searchanddetailcommands and a consistent JSON output shape - Registration in
.claude/skills/job-scraper/search-queries.mdenables seamless integration with the/scrapecommand - All markup assumptions are documented in
url-reference.mdfor future maintenance and debugging
Frequently Asked Questions
What file structure does /add-portal create?
The generator scaffolds a directory under .agents/skills/<name>/ containing SKILL.md, url-reference.md, a cli/ directory with TypeScript source files (src/cli.ts, helpers, and command modules), and a tests/ directory with smoke tests. This structure mirrors the reference implementation at .agents/skills/linkedin-search/.
Why does the generator require a live test query before completion?
Step 4 mandates live validation to ensure the skill correctly parses the portal's HTML structure and returns data in the expected JSON shape { meta, results }. This prevents shipping broken scrapers by verifying the regex selectors and endpoint logic against real responses before the skill is considered production-ready.
How does the skill integrate with the existing job scraper?
After scaffolding, you can optionally register the portal in .claude/skills/job-scraper/search-queries.md. Once listed there, the /scrape command automatically includes results from your new portal skill alongside existing sources like linkedin-search or jobindex-search without requiring additional code changes.
What are the naming requirements for new portal skills?
The generator enforces kebab-case naming with the -search suffix (e.g., seek-search or indeed-search). It checks .agents/skills/ for name collisions to prevent overwriting existing implementations, ensuring each skill has a unique identity in the repository.
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 →