TEMPLATE — a CareerForge example job-portal adapter (ADR-0004). Copy this directory to add structured search for a real job board. Not auto-loaded by Claude Code.
Scanned 8/30/2026
Install to Claude Code
npx -y skills add suraj-davariya/ai-job-search --skill example-portal --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Example Portal?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/suraj-davariya-example-portal)More formats (shields.io, HTML) on the badges page.
---
name: example-portal
description: "TEMPLATE — a CareerForge example job-portal adapter (ADR-0004). Copy this directory to add structured search for a real job board. Not auto-loaded by Claude Code."
---
# Example Portal Adapter — TEMPLATE (copy me)
> ⚠️ **This is a template, not a working portal.** Its `cli/` returns clearly-labelled
> **example** data so you can run it end-to-end and see the contract. To add a real
> portal, **copy this whole directory** to `.agents/skills/<portal-name>/` and implement
> real fetching in `cli/index.ts`.
## Why `.agents/skills/` and not `.claude/skills/`?
Per **ADR-0004**, structured portal adapters are a **Plane-2** extension: each portal is a
self-contained CLI tool that the country-agnostic [`job-scraper`](../../../.claude/skills/job-scraper/SKILL.md)
skill calls out to, with web search (`site:<portal>`) as the universal fallback. They live
under `.agents/skills/` deliberately — that path is **not** the Claude Code skill
auto-load directory (`.claude/skills/`), so an adapter is invoked as a CLI (via `bun run`),
never silently activated as a chat skill. This keeps the core framework clean and lets any
market contribute an adapter without changing core code.
## Directory contract (ADR-0004)
```
.agents/skills/<portal-name>/
├── SKILL.md # this file — trigger keywords + contract
├── cli/
│ ├── package.json # dependencies + start script (Bun/TypeScript)
│ └── index.ts # CLI entry point implementing the contract below
└── url-reference.md # optional — the portal's search-URL patterns
```
## CLI contract
| | |
|---|---|
| **Runtime** | Bun (TypeScript). `node`/`npx tsx` also work for this template. |
| **Input** | CLI flags: `--keywords "<terms>"`, `--location "<place>"`, `--date-range <days>` |
| **Output** | A JSON array on stdout, one object per posting: `{ title, company, location, url, date, snippet }` |
| **Exit code** | `0` on success (even with zero results — emit `[]`), `1` on error (message on stderr) |
The `job-scraper` skill runs the adapter like:
```bash
bun run .agents/skills/<portal-name>/cli/index.ts \
--keywords "data engineer" --location "Remote" --date-range 14
```
…then parses the JSON array, dedupes against `seen_jobs.json`, quick-rates fit, and
presents results exactly as it does for web-search hits.
## How to add a real portal
1. Copy this directory to `.agents/skills/<portal-name>/`.
2. In `cli/index.ts`, replace the example data with a real fetch (the portal's public
search/API, or HTML parsing) that honours the input/output/exit-code contract.
3. Record the portal's search-URL patterns in `url-reference.md`.
4. Add the portal to your `search-queries.md` so `job-scraper` knows to use it.
5. **No core change is required** — that is the whole point of ADR-0004.
## Constraints
- **No fabrication (ARCH-0007):** a real adapter must return only postings it actually
found, with real URLs. This template clearly labels its output as example data.
- Keep dependencies minimal; each adapter installs independently (`bun install`).
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!