Jobs Skill
by @agitalent
Connect job seekers and recruiters by registering profiles or roles, searching the hub for matches, and tracking new fits since last visit.
clawhub install irecruiter-skillπ About This Skill
Jobs Skill
Direct access:
Purpose
jobs is a hub router skill for bots and agents.
It connects:
What the Bot Must Do Locally
A user should not hand-run extra repository scripts. The published skill bundle is intentionally self-contained.
Do not look for:
scripts/launchd/supabase-schema.sqlThe bot should use its own runtime and only these install steps: 1. Install or update the skill. 2. Ask for or read the configured runtime credentials. 3. Use runtime env vars or the platform secret store. Do not write credentials to disk unless the user explicitly asks for that behavior. 4. Start or resume watch mode. 5. Do not install, upgrade, or mention a Supabase SDK unless the user explicitly asks for SDK work.
Minimal install command:
npx -y clawhub install jobs
If runtime credentials already exist, the bot should refresh the skill and continue watch mode without asking for extra files. If any env value is a placeholder, treat it as missing and ask for a real value.
Connection Gate
If supabase_connected is false, treat the skill as not configured.
Rules:
job_descriptions: 0data_directorySUPABASE_URL and a public keyWhat Must Be Installed
For the bot to receive push and to see posts / profiles, install all of these on the bot machine:
1. Node.js 18+.
2. Supabase access credentials with least privilege:
- SUPABASE_URL
- SUPABASE_ANON_KEY or SUPABASE_PUBLISHABLE_KEY only if the project is intentionally public/test-only
- otherwise use a restricted runtime credential path provided by the host platform
3. The jobs hub schema in the same Supabase project:
- profiles
- needs
- matches
- events
4. ClawHub / OpenClaw skill sync on the bot side so the bot loads the latest skill markdown again after publication.
5. No local JSON database, no hub.json, no HUB_STORAGE_PATH, and no filesystem fallback store.
6. Do not require broad public read on production data. Use authenticated, scoped, least-privilege access for profiles, needs, matches, and events.
Bot Flow
Use this exact flow:
register profile writes a candidate into Supabase profilesregister profile also writes NEW_PROFILE into Supabase eventspost job writes a JD into Supabase needspost job also writes NEW_NEED into Supabase eventspost job, search Supabase profiles and return ranked profile results to the job posterregister profile, search Supabase needs and return ranked jobs to the candidateMATCH_CREATED into Supabase eventswatch inbox reads new hub events rows and emits push eventsneed -> job seeker agents, new profile -> recruiter agentsζεͺδΊjob posts or search --mode=pull, query Supabase needs directly and list the rowsany job posts or show job posts, also query Supabase needs directly; do not start a repair stepneeds cannot be reached, say the database is unavailable, not that it is emptyjob_descriptions: 0 unless the needs query truly returned zero rowsCandidate Profile Fields
nameageemailbio_linkcurrent_locationhighest_education_backgroundschool_graduategraduation_datecurrent_companycurrent_positionprevious_companiesskillspreferred_locationJob Need Fields
role_recruiter_nameemailcompany_namepost_linklocationpositionteamresponsibility_keywordstarget_companieseducation_degreepreferred_schoolpreferred_majorqualification_keywordsThe needs table no longer uses level or urgency; use company_name and post_link as the replacement fields in the job brief.
Storage
Store all records in the same Supabase project.
Tables:
profilesneedsmatcheseventsRules:
profiles before searchingneeds before searchingmatches only when the score is meaningfulevents row for every new profile, new need, and new matchBot Output
When a candidate is registered:
NEW_PROFILE eventneeds immediately and return the best matching jobsWhen a job is posted:
NEW_NEED eventprofiles immediately and return the best matching profiles to the job postermatches row if the score passes the thresholdMATCH_CREATED when a match row is writtenLatest job-post fetch rule:
needs row before rendering or answeringWhen a user asks for current job posts:
needs sorted by created_at descbio_link for profiles and post_link for needs when presentcompany_name and post_link when presentcompany_name and post_link inline if either field existsrole_title first, then position, then job_titlecontact_name first, then role_recruiter_name, then company_nameNo job posts found in Supabase needsSupabase needs is unavailable and stopsupabase_connected is false, say the skill is not configured and stoprole_title, position, job_title, contact_name, role_recruiter_name, or company_name, never call the table placeholder dataneeds table still contains placeholder entries unless every returned row literally uses placeholder valuesUntitled when role_title, position, job_title, contact_name, role_recruiter_name, or company_name existsN/A; use missing or leave the field blankRequired job listing summary template:
TitleCompanyPostLocationCreatedRaw rowThe summary must render company_name and post_link inline whenever they exist. If either field is missing, print missing; do not omit the field entirely.
When watching:
events~/.openclaw/irecruiter-inbox.jsonlCommand Examples
The bot should support direct commands like these:
@agitalent jobs post a job
Expected behavior:
needsprofiles@agitalent jobs register profile
Expected behavior:
profilesneeds@agitalent jobs search profiles for this job
Expected behavior:
profiles directlyReinstall / Sync on the Bot Side
After publishing a new skill version, the bot machine must reload it.
Recommended sequence:
1. Reinstall or resync the skill from ClawHub.
2. Confirm the bot has SUPABASE_URL and the required least-privilege credential available in its runtime config.
3. Resume watch mode.
4. Confirm the watcher is reading the same Supabase project and inbox files.
Example local commands:
# refresh the skill on the bot machine
npx -y clawhub install jobsresume the bot's own watch mode
watch inbox
Runtime State
Credentials:
Runtime state:
~/.openclaw/irecruiter-watch-state.json~/.openclaw/irecruiter-inbox.jsonl