with one click
jobhunt
// Track job applications, analyze positions, identify skill gaps, and plan your job search strategy
// Track job applications, analyze positions, identify skill gaps, and plan your job search strategy
| name | jobhunt |
| description | Track job applications, analyze positions, identify skill gaps, and plan your job search strategy |
| read_strategy | On first use: read Quick Start + Job Seeker Profile. When searching: read Discovery section (agent-driven search missions). When ingesting: read Ingestion + Sensemaking sections. When analyzing: read Analysis section. Full command reference: read Commands section on demand. |
| triggers | ["add job / ingest job / new position","search for jobs / run a search mission","analyze this job posting / make sense of","show my pipeline / skill gaps / learning plan","update status / job search","create seeker profile / set up job search"] |
| prerequisites | ["TypeDB running (make db-start)","make build-skills"] |
Use this skill to manage a job search as a knowledge graph. Claude acts as the career agent — browsing job boards, evaluating postings against the seeker's profile, and building structured understanding of positions, companies, and fit over time.
Key principle: The agent does the sensemaking. Scripts are tools that search APIs, store data, and run queries. The agent decides what's relevant, writes the rationale, and manages the pipeline.
Role model: The job seeker is a BFO/UFO role that inheres in a person. One person can have multiple roles (job seeker, author, evaluator). The role holds search-specific data; the person holds identity data.
make db-startuv sync --all-extras (from project root)make build-db after make build-skillsPath note: Replace
.claude/skills/jobhuntbelow with your installation directory:
- Claude plugin install:
${CLAUDE_PLUGIN_ROOT}/skills/jobhunt(self-contained bundle atplugins/jobhunt/)- skillful-alhazen project:
.claude/skills/jobhuntWhen installed as a plugin, TypeDB starts automatically on session start (no manual init required).
TYPEDB_HOST: TypeDB server (default: localhost)TYPEDB_PORT: TypeDB port (default: 1729)TYPEDB_DATABASE: Database name (default: alhazen_notebook)# Ingest a job posting from URL
uv run python .claude/skills/jobhunt/jobhunt.py ingest-job \
--url "https://boards.greenhouse.io/anthropic/jobs/123456" \
--priority high
# List your pipeline
uv run python .claude/skills/jobhunt/jobhunt.py list-pipeline
# Show position details
uv run python .claude/skills/jobhunt/jobhunt.py show-position --id "position-abc123"
# Add a note to any entity
uv run python .claude/skills/jobhunt/jobhunt.py add-note \
--about "position-abc123" --type research \
--content "Strong AI safety focus, good culture fit"
uv run emits a VIRTUAL_ENV warning to stderr. Always use 2>/dev/null when piping output to a JSON parser -- never 2>&1, which merges the warning into stdout and breaks JSON parsing.
The job seeker is modeled as a role (BFO/UFO pattern) that inheres in a person. The role holds search-specific data (target role, industries, salary expectations) while the person entity holds identity data (name, email, linkedin).
uv run python .claude/skills/jobhunt/jobhunt.py create-seeker-profile \
--person op-f25ab4b15b0f \
--target-role "Principal AI Architect" \
--industries "AI, Biotech, Scientific Computing" \
--salary "200k-250k" \
--location "Remote / SF Bay Area" \
--focus "TypeDB-powered knowledge systems, AI for science"
This creates a jhunt-job-seeker-role entity linked to the person via alh-role-bearing. All pipeline data (opportunities, skills, candidates) scopes to this role.
Skills are owned by the seeker role, derived from real evidence, and use a simplified Bloom's taxonomy for proficiency levels.
Proficiency levels:
| Level | Meaning | Evidence type | Interview readiness |
|---|---|---|---|
expert | Can design/teach | Publications, architected systems, led teams | Can whiteboard, critique alternatives |
practiced | Hands-on experience | Projects, production use, coursework | Can walk through how you used it |
aware | Conceptual knowledge | Read papers/docs, attended talks | Can answer "what is X" questions |
none | Not known | No evidence | Cannot discuss |
The agent ingests the seeker's professional artifacts as sources of evidence. Each artifact is stored and linked to the seeker via alh-aboutness so skills can trace back to their proof.
# Ingest LinkedIn profile (save page HTML or use Playwright MCP to capture)
uv run python .claude/skills/jobhunt/jobhunt.py ingest-job \
--url "https://linkedin.com/in/username"
# Ingest resume (PDF or text)
# Upload or paste resume content, agent stores as jhunt-resume artifact
# Ingest ORCID profile
# Agent fetches via WebFetch and stores key publications/experience
# Ingest Google Scholar page
# Agent fetches and extracts publication list, h-index, citation metrics
The agent should fetch each source, extract the content, and store it as an artifact linked to the seeker role via alh-aboutness. This creates the evidence chain: artifact → seeker → skill.
The agent reads the ingested artifacts and conducts a structured interview with the seeker:
For each skill identified, the agent assesses the proficiency level based on the evidence and discussion.
uv run python .claude/skills/jobhunt/jobhunt.py add-skill \
--name "Knowledge Graphs" --level "expert" \
--evidence "Built 5000+ entity TypeDB production KG, BFO/UFO ontology design" \
--recency "daily 2026" \
--description "TypeDB 3.x, TypeQL, schema evolution, GLAV mapping"
uv run python .claude/skills/jobhunt/jobhunt.py add-skill \
--name "RAG Pipelines" --level "expert" \
--evidence "Voyage AI + Qdrant in production, hybrid ontology-filtered retrieval" \
--recency "daily 2026"
uv run python .claude/skills/jobhunt/jobhunt.py add-skill \
--name "Pharma Experience" --level "none" \
--description "No direct pharma industry experience. Biomedical informatics at CZI."
Each skill is linked to the seeker via jhunt-seeker-has-skill. The --evidence field should reference the ingested artifacts where possible.
Once skills are populated, gap analysis joins seeker skills against position requirements:
uv run python .claude/skills/jobhunt/jobhunt.py show-gaps
uv run python .claude/skills/jobhunt/jobhunt.py list-skills
Discovery is agent-driven: Claude browses job boards, reads postings, evaluates fit against the seeker profile, and adds good matches as candidates with a written rationale. No automated scoring or LLM triage — the agent IS the sensemaker.
search-source) for bulk listing from Greenhouse/Lever boardssearch-source on website sources) for browsing JS-rendered job sites like hiring.cafeweb-search skill) for ad-hoc browsing of careers pages or niche boardsuv run python .claude/skills/jobhunt/job_forager.py add-candidate \
--title "Research Scientist, AI for Science" \
--url "https://boards.greenhouse.io/anthropic/jobs/123" \
--location "San Francisco" \
--relevance 0.85 \
--reason "Strong fit: combines AI evaluation with scientific methodology"
Three types of sources:
# Company recruiting pages (Greenhouse/Lever/Ashby) — API-based, returns all jobs
uv run python .claude/skills/jobhunt/job_forager.py add-source \
--name "Anthropic" --platform greenhouse --token anthropic
# Job board aggregators (LinkedIn/Remotive/Adzuna) — API-based, keyword search
uv run python .claude/skills/jobhunt/job_forager.py add-source \
--name "ML Jobs" --platform linkedin --query "machine learning" --location "San Francisco"
# Job websites (hiring.cafe, etc.) — browser-based via Playwright MCP
uv run python .claude/skills/jobhunt/job_forager.py add-source \
--name "hiring.cafe" --platform website \
--url "https://hiring.cafe" \
--query "AI scientist knowledge graph biotech drug discovery"
| Platform | Type | Auth | Args |
|---|---|---|---|
greenhouse | Company board | None | --token (slug) |
lever | Company board | None | --token (slug) |
ashby | Company board | None | --token (slug) |
linkedin | Aggregator | None | --query, --location |
remotive | Aggregator | None | --query, --location |
adzuna | Aggregator | API key | --query, --location |
website | Job website | Playwright MCP | --url, --query |
Returns all job listings from a source for the agent to evaluate:
uv run python .claude/skills/jobhunt/job_forager.py search-source --source "Anthropic"
# Returns: {jobs: [{title, url, location, external_id}, ...]}
The agent reads through these, fetches interesting postings via web-fetch, and adds good matches as candidates.
For website platform sources, search-source returns instructions instead of job listings.
The agent uses Playwright MCP tools to browse the site interactively:
search-source --source "hiring.cafe" returns the URL and querybrowser_navigate to the source URLbrowser_type the query into the search box, submitbrowser_snapshot or browser_take_screenshot to see rendered resultsbrowser_run_code_unsafe to extract job URLs from the DOM, or read the snapshotWebFetch each interesting job URL (individual pages usually render server-side)add-candidate with rationale for each good matchExample: hiring.cafe
hiring.cafe is a 41M+ job aggregator with AI-powered search. It uses client-side React rendering, so API/curl cannot access search results — Playwright MCP is required.
The site auto-generates filters from natural language queries (Department, Industry, Tech Keywords). Sometimes the auto-filters are too narrow and return zero results. If this happens, click "Reject All" on the suggested filters and try a broader query, or remove specific filter chips.
Individual job pages (/viewjob/{id}) render server-side and can be fetched with WebFetch for full details.
Candidates are embedded in Qdrant on creation. Search by meaning:
uv run python .claude/skills/jobhunt/job_forager.py search-candidates \
--query "knowledge graph engineering for science" --limit 10
# List all candidates
uv run python .claude/skills/jobhunt/job_forager.py list-candidates
# List by status
uv run python .claude/skills/jobhunt/job_forager.py list-candidates --status reviewed
# Promote a candidate to a full position (creates jhunt-position + application note)
uv run python .claude/skills/jobhunt/job_forager.py promote --id candidate-abc123
The agent does the sensemaking. Scripts are tools — they search APIs, store data, and run queries. The agent decides what's relevant, writes the rationale, and manages the pipeline.
Triggers: "add job", "ingest job", "new position", "found a job posting", "here's a job"
uv run python .claude/skills/jobhunt/jobhunt.py ingest-job \
--url "https://boards.greenhouse.io/anthropic/jobs/123456" \
--priority high \
--tags "ai" "ml" "safety"
Options:
--url (required): Job posting URL--priority: Set priority (high/medium/low)--tags: Space-separated tagsReturns:
{
"success": true,
"position_id": "position-abc123",
"artifact_id": "artifact-xyz789",
"status": "raw",
"message": "Artifact stored - ask Claude to 'analyze this job posting' for sensemaking."
}
What ingestion produces:
jobhunt-position entity with status researchingjobhunt-job-description artifact containing the raw scraped page contentjobhunt-application-note tracking the application statusuv run python .claude/skills/jobhunt/jobhunt.py add-position \
--title "Senior ML Engineer" \
--company "Anthropic" \
--priority high
uv run python .claude/skills/jobhunt/jobhunt.py add-company \
--name "Anthropic" \
--url "https://anthropic.com" \
--description "AI safety research company"
uv run python .claude/skills/jobhunt/jobhunt.py add-engagement \
--name "Acme Corp Data Consulting" \
--company-id "company-abc123" \
--type project \
--rate "$200/hr" \
--status active \
--priority high
Engagement types: hourly | project | retainer | advisory
uv run python .claude/skills/jobhunt/jobhunt.py add-venture \
--name "Augura Health Advisory" \
--stage proposal-sent \
--equity-type advisor \
--priority high
Venture stages: exploring | proposal-sent | negotiating | active | paused | closed
Equity types: none | advisor | cofounder | investor
uv run python .claude/skills/jobhunt/jobhunt.py add-lead \
--name "Jane Smith - BigCo" \
--status warm \
--priority medium \
--description "Met at ML Summit, interested in consulting"
Lead statuses: first-contact | active | inactive | closed
When user says "analyze this job posting" or "make sense of [position]":
Get the artifact content
uv run python .claude/skills/jobhunt/jobhunt.py show-artifact --id "artifact-xyz"
Read and comprehend the content
Research the company and leadership online (use the web-search skill)
Search for: company mission, funding, recent news, and LinkedIn activity of key leaders. Focus on:
Save findings as a research note attached to both the company and the position:
# Company-level research (background, funding, mission)
uv run python .claude/skills/jobhunt/jobhunt.py add-note \
--about "company-xyz" \
--type research \
--content "Series C, $4B raised. Mission: X. CEO recently spoke at Y conference..."
# Position-level research (leadership context, role fit signals, hiring manager)
uv run python .claude/skills/jobhunt/jobhunt.py add-note \
--about "position-abc123" \
--type research \
--content "Bo Wang (SVP Biomedical AI) is likely hiring manager. Very active on LinkedIn..."
Create/update the company
uv run python .claude/skills/jobhunt/jobhunt.py add-company \
--name "Anthropic" \
--url "https://anthropic.com" \
--description "AI safety research company"
Extract requirements using the skill vocabulary
Before extracting requirements, load the skill concept vocabulary:
uv run python .claude/skills/jobhunt/jobhunt.py list-concepts
This returns the full vocabulary with your proficiency levels, alt-labels, and hierarchy. Use canonical concept names when creating requirements so they match your skill profile.
For each skill in the posting:
# Create a new concept if needed
uv run python .claude/skills/jobhunt/jobhunt.py add-concept \
--name "Molecular Simulation" \
--alt-labels "MD,Molecular Dynamics,Force Fields"
# Add the user's self-assessed skill
uv run python .claude/skills/jobhunt/jobhunt.py add-skill \
--name "Molecular Simulation" --level "aware" \
--evidence "Read papers, understand concepts, no hands-on" \
--recency "reading 2026"
# Then add the requirement (using the canonical concept name)
uv run python .claude/skills/jobhunt/jobhunt.py add-requirement \
--position "position-abc123" \
--skill "Molecular Simulation" \
--level "required"
Key principle: Never assume the user's skill level. If a requirement mentions a skill not in their profile, ask them. Their self-assessment + evidence is the ground truth, not the agent's inference.
Create analysis notes
Fit Analysis Note:
uv run python .claude/skills/jobhunt/jobhunt.py add-note \
--about "position-abc123" \
--type fit-analysis \
--content "Strong fit for core requirements. Gap in distributed systems." \
--fit-score 0.82 \
--fit-summary "Strong technical fit, one gap to address"
Skill Gap Note:
uv run python .claude/skills/jobhunt/jobhunt.py add-note \
--about "position-abc123" \
--type skill-gap \
--content "Distributed systems is required. Recommend: DDIA book, MIT 6.824 course."
Flag uncertainties
uv run python .claude/skills/jobhunt/jobhunt.py tag \
--entity "requirement-xyz" \
--tag "uncertain"
Report findings to user: company overview, leadership signals, fit score breakdown, key gaps, suggested next steps (including who to follow on LinkedIn)
uv run python .claude/skills/jobhunt/jobhunt.py list-artifacts --status raw
uv run python .claude/skills/jobhunt/jobhunt.py list-artifacts --status all
uv run python .claude/skills/jobhunt/jobhunt.py show-artifact --id "artifact-xyz789"
Every opportunity MUST have after sensemaking:
--company flag on add-position, auto-matched to existing jobhunt-company entities (do not create duplicates)salary-range attributejobhunt-requirement entities via add-requirementfit-score (0.0-1.0) and fit-summaryjobhunt-opp-summary-note synthesizing all notes. Regenerated after any note is added or updated.embedding_map.py embed-and-map after saving the summary so the opportunity appears on Mission Control.Every opportunity has exactly one jobhunt-opp-summary-note — a living markdown dossier that is overwritten each time notes change. This is the primary embedding text for the Mission Control map and the quick-read view for understanding any opportunity.
Workflow — regenerate after any note update:
# 1. Fetch all notes + metadata
uv run python .claude/skills/jobhunt/jobhunt.py regenerate-summary --about <opp-id>
# 2. Read the JSON output, write a markdown summary following the template below
# 3. Save the summary (creates or overwrites)
uv run python .claude/skills/jobhunt/jobhunt.py upsert-summary --about <opp-id> --content "@/tmp/summary.md"
# 4. Re-embed to update the Mission Control map
uv run python local_skills/jobhunt/embedding_map.py embed-and-map
IMPORTANT: Step 4 (re-embed) MUST be run after saving the summary. Without it, new or updated opportunities will not appear on the Mission Control map. This step re-computes embeddings for ALL opportunities and regenerates the 2D layout.
Summary templates by type:
Position:
## Role
- Title, company, location/remote policy
- Key responsibilities (2-3 bullets)
- Salary range if known
## Fit
- Overall fit score and one-line assessment
- Top strengths (2-3 bullets with specifics)
- Key gaps (1-2 bullets)
## Company
- What they do, stage/size, why interesting
- Key people (hiring manager, contacts)
## Status
- Current application status
- Key dates, next steps, or outcome
Engagement:
## Engagement
- Client, scope, type (consulting/contract/advisory)
- Rate/compensation if known
## Fit
- Why this is a good match
- Key deliverables
## Status
- Current stage (proposal/active/paused/closed)
Venture:
## Overview
- What the venture is, stage
- Your role/involvement
## Opportunity
- Why it's interesting
- Key milestones or next steps
## Status
- Current stage (seed/series-a/series-b/growth/closed)
Lead:
## Contact
- Who, title, organization
- How you met, when
## Context
- What the connection is about
- Potential opportunity or value
## Status
- Relationship state (first-contact/active/inactive/closed)
uv run python .claude/skills/jobhunt/jobhunt.py update-status \
--position "position-abc123" \
--status "applied" \
--date "2025-02-05"
Status values: researching | applied | phone-screen | interviewing | offer | rejected | withdrawn
# Interaction note
uv run python .claude/skills/jobhunt/jobhunt.py add-note \
--about "position-abc123" \
--type interaction \
--content "Phone screen went well, moving to technical round." \
--interaction-type "call" \
--interaction-date "2025-02-05"
# Strategy note
uv run python .claude/skills/jobhunt/jobhunt.py add-note \
--about "position-abc123" \
--type strategy \
--content "Lead with distributed systems experience from caching project."
# Claude Code brief (CC agent writes a brief for the next session)
uv run python .claude/skills/jobhunt/jobhunt.py add-note \
--about "position-abc123" \
--type cc-brief \
--content "Next session: prep for technical interview on 2025-02-10. Focus on system design questions."
# Claude Code feedback (CC agent records feedback from completed interaction)
uv run python .claude/skills/jobhunt/jobhunt.py add-note \
--about "position-abc123" \
--type cc-feedback \
--content "User reported phone screen went well. Interviewer asked about distributed caching. Move to next round."
Note types: research | strategy | interview | interaction | skill-gap | fit-analysis | general | cc-brief | cc-feedback
uv run python .claude/skills/jobhunt/jobhunt.py show-gaps
uv run python .claude/skills/jobhunt/jobhunt.py learning-plan
uv run python .claude/skills/jobhunt/jobhunt.py add-resource \
--name "Designing Data-Intensive Applications" \
--type "book" \
--url "https://dataintensive.net" \
--hours 30 \
--skills "distributed-systems" "system-design"
uv run python .claude/skills/jobhunt/jobhunt.py link-resource \
--resource "<resource-id>" \
--requirement "<requirement-id>"
# Search for papers on a skill gap topic
uv run python .claude/skills/scientific-literature/scientific_literature.py search \
--query "machine learning systems design" \
--collection "ML Systems Reading List"
# Link collection to skill gap
uv run python .claude/skills/jobhunt/jobhunt.py link-collection \
--collection "<collection-id>" \
--skill "machine-learning"
# Link a specific paper to a learning resource
uv run python .claude/skills/jobhunt/jobhunt.py link-paper \
--resource "<resource-id>" \
--paper "<paper-id>"
# View updated plan
uv run python .claude/skills/jobhunt/jobhunt.py learning-plan
# All positions
uv run python .claude/skills/jobhunt/jobhunt.py list-pipeline
# Filter by status or priority
uv run python .claude/skills/jobhunt/jobhunt.py list-pipeline --status "interviewing"
uv run python .claude/skills/jobhunt/jobhunt.py list-pipeline --priority "high"
# All opportunity types
uv run python .claude/skills/jobhunt/jobhunt.py list-opportunities --type all
uv run python .claude/skills/jobhunt/jobhunt.py list-opportunities --type venture
uv run python .claude/skills/jobhunt/jobhunt.py list-opportunities --type engagement --status active
# Detail views
uv run python .claude/skills/jobhunt/jobhunt.py show-position --id "position-abc123"
uv run python .claude/skills/jobhunt/jobhunt.py show-opportunity --id "venture-abc123"
uv run python .claude/skills/jobhunt/jobhunt.py show-company --id "company-xyz"
uv run python .claude/skills/jobhunt/jobhunt.py show-gaps
uv run python .claude/skills/jobhunt/jobhunt.py learning-plan
uv run python .claude/skills/jobhunt/jobhunt.py report-pipeline # Pipeline overview
uv run python .claude/skills/jobhunt/jobhunt.py report-stats # Stats summary
uv run python .claude/skills/jobhunt/jobhunt.py report-gaps # Skill gaps
uv run python .claude/skills/jobhunt/jobhunt.py report-position --id "position-xyz" # Position detail
Use reports (Markdown) for displaying to users in chat. Use JSON commands (list-pipeline, show-position) for programmatic processing.
uv run python .claude/skills/jobhunt/jobhunt.py tag --entity "position-abc123" --tag "remote"
uv run python .claude/skills/jobhunt/jobhunt.py search-tag --tag "remote"
The jobhunt skill tracks multiple types of career opportunities via the jobhunt-opportunity hierarchy:
jobhunt-opportunity (base)
+-- jobhunt-position -- formal employment application (has application-status pipeline)
+-- jobhunt-engagement -- paid consulting/service work for a client
+-- jobhunt-venture -- startup/advisory/equity opportunity
+-- jobhunt-lead -- early-stage networking contact, role undefined
All opportunity types share: opportunity-status, priority-level, deadline, and can be linked to a jobhunt-company via opportunity-at-organization.
All opportunity types work with add-note --about <ID> -- notes attach to any identifiable-entity.
uv run python .claude/skills/jobhunt/jobhunt.py update-opportunity \
--id "venture-abc123" \
--status active \
--stage negotiating \
--priority high
| Situation | Entity type | Key attributes |
|---|---|---|
| Own consulting business | jobhunt-company | name, description |
| Startup advisory role | jobhunt-venture | venture-stage, equity-type |
| Consulting engagement | jobhunt-engagement | engagement-type, rate-info |
| Networking contact (no role yet) | jobhunt-lead | opportunity-status, description |
| Formal job application | jobhunt-position | job-url, application-status pipeline |
Phylo strategy pattern: Use an existing jobhunt-position as the anchor for all interactions. Add jobhunt-interaction-note entries for each meeting. Only create a separate jobhunt-lead if a genuinely new thread emerges from those conversations.
| Type | Description |
|---|---|
your-skill | Your skills for gap analysis |
jobhunt-company | An employer/client organization |
jobhunt-opportunity | Base type for all opportunities |
jobhunt-position | Formal job posting (sub opportunity) |
jobhunt-engagement | Consulting engagement (sub opportunity) |
jobhunt-venture | Startup/advisory venture (sub opportunity) |
jobhunt-lead | Networking lead (sub opportunity) |
jobhunt-learning-resource | Course, book, tutorial |
jobhunt-contact | Person at a company |
jobhunt-search-source | Company board for forager |
jobhunt-candidate | Discovered posting (forager) |
| Type | Description |
|---|---|
jobhunt-job-description | Raw HTML/text from job posting URL |
jobhunt-resume | Resume document |
jobhunt-cover-letter | Cover letter |
jobhunt-company-page | Company website snapshot |
jobhunt-proposal | Proposal or pitch deck for engagement/venture |
| Type | Purpose |
|---|---|
jobhunt-application-note | Status tracking (positions) |
jobhunt-research-note | Company/opportunity research |
jobhunt-interview-note | Interview prep/feedback |
jobhunt-strategy-note | Talking points, approach |
jobhunt-skill-gap-note | Learning needs |
jobhunt-fit-analysis-note | Fit assessment |
jobhunt-interaction-note | Contact logs |
jobhunt-cc-brief-note | Claude Code brief for next session |
jobhunt-cc-feedback-note | Claude Code feedback from completed interaction |
position-at-company -- links position to employeropportunity-at-organization -- links any opportunity type to a companyaboutness -- links notes to any entity (position, company, opportunity)requirement-of -- links requirements to positionslocal_skills/jobhunt/schema.tqllocal_resources/typedb/alhazen_notebook.tql| Command | Description | Key Args |
|---|---|---|
ingest-job | Fetch job URL, store raw | --url |
add-skill | Add/update skill with Bloom's proficiency | --name, --level (expert/practiced/aware/none), --evidence, --recency |
list-skills | Show your skills | |
list-artifacts | List artifacts by status | --status |
show-artifact | Get artifact content | --id |
add-company | Add company | --name |
add-position | Add position manually | --title |
add-engagement | Add consulting engagement | --name, --type, --rate |
add-venture | Add startup/advisory venture | --name, --stage, --equity-type |
add-lead | Add networking lead | --name, --status |
update-opportunity | Update any opportunity status/stage/priority | --id |
show-opportunity | Show any opportunity details | --id |
list-opportunities | List by type/status | --type, --status, --priority |
add-requirement | Add skill requirement | --position, --skill |
update-status | Change position application status | --position, --status |
add-note | Create any note type | --about, --type, --content |
add-resource | Add learning resource | --name, --type |
link-collection | Link paper collection to skill gap | --collection, --skill |
link-resource | Link resource to a skill requirement | --resource, --requirement |
link-paper | Link learning resource to a paper | --resource, --paper |
create-seeker-profile | Create job-seeker role for a person | --person, --target-role, --industries |
list-pipeline | Show position pipeline | --status, --priority, --person |
show-position | Position details | --id |
show-company | Company details | --id |
show-gaps | Skill gap analysis | |
learning-plan | Prioritized study list | |
tag | Tag an entity | --entity, --tag |
search-tag | Find by tag | --tag |
report-pipeline | Pipeline overview (Markdown) | |
report-stats | Stats summary (Markdown) | |
report-gaps | Skill gaps report (Markdown) | |
report-position | Position detail (Markdown) | --id |
| Command | Description | Key Args |
|---|---|---|
add-source | Add a search source (company board or aggregator) | --name, --platform, --token/--query |
list-sources | List configured search sources | |
remove-source | Remove a source | --id, --token, or --name |
search-source | Search one source (raw listings for agent review) | --source |
add-candidate | Add a candidate with agent evaluation | --title, --url, --relevance, --reason |
search-candidates | Semantic search across candidates (Qdrant) | --query, --limit |
list-candidates | List candidates | --status, --source |
promote | Promote candidate to full position | --id |
Declarative audit rules for data quality are defined in quality-checks.yaml.
# Check for violations
uv run python .claude/skills/jobhunt/jobhunt.py audit
# Auto-fix where possible
uv run python .claude/skills/jobhunt/jobhunt.py audit --fix
# Or use the generic audit runner
uv run python src/skillful_alhazen/utils/audit_runner.py run \
--checks local_skills/jobhunt/quality-checks.yaml
| Check | Severity | Description |
|---|---|---|
position-company-link | high | Positions should be linked to a company via position-at-company |
ugly-titles | medium | Position titles containing job-board boilerplate |
missing-short-name | medium | Positions without a short-name for compact display |
missing-salary | low | Positions without salary-range information |
positions-without-notes | low | Positions with no notes at all |
duplicate-companies | high | Multiple company entities with identical names |
orphaned-companies | medium | Companies with no positions or opportunities linked |
A Next.js dashboard is available for visualizing your job search pipeline. It runs in Docker (not npm run dev).
docker compose build --no-cache dashboard
docker compose up -d dashboard
# Dashboard available at http://localhost:3001
/jobhunt) -- Kanban columns by application status/jobhunt/position/{id}) -- Full position profile: requirements, notes, gap analysis, fit score/jobhunt/collection/{id}) -- Notes and resources grouped by collectiondashboard/src/app/(jobhunt)/jobhunt/dashboard/src/components/jobhunt/dashboard/src/app/api/jobhunt/dashboard/src/lib/jobhunt.tsDuring sensemaking, if you encounter a concept, relationship, or entity type that has no place in the current TypeDB schema, that is a schema gap -- a signal for schema evolution, not a failure.
When you notice a schema gap:
uv run python local_resources/skilllog/skill_logger.py file-schema-gap \
--skill jobhunt \
--concept "<the concept you tried to represent>" \
--missing "<which TypeDB entity/relation/attribute is absent>" \
--suggested "<proposed TypeQL addition, or 'unknown' if unsure>"
Examples of schema gaps:
jobhunt-contactUse --dry-run first to review the issue before filing it.
[HINT] Download the complete skill directory including SKILL.md and all related files