AI job-search command center for the SOLID.Jobs public API.
A Go CLI (sjctl) fetches, caches and tracks offers; a set of agent skills turn
natural language into searches, build your candidate profile, score offers against
it, and surface new matches — with clickable links straight to each posting.
Powered by the SOLID.Jobs API client.
Via skills.sh (recommended) — installs the skills into
Claude Code; the first skill run downloads a checksum-verified sjctl binary into
~/.solid-jobs-skills/bin:
npx skills add solid-company/solid-jobs-skillsBinary only — pull the latest release for your platform without skills.sh:
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/solid-company/solid-jobs-skills/main/scripts/install-sjctl.sh | bash
# Windows (PowerShell)
irm https://raw.githubusercontent.com/solid-company/solid-jobs-skills/main/scripts/install-sjctl.ps1 | iexPin a version with SJCTL_VERSION=v0.1.0, change the install dir with
SJCTL_BIN_DIR. The database always lives at ~/.solid-jobs-skills/solidjobs.db
(override with SJCTL_DB), so sjctl works from any directory.
Releases are built by GoReleaser on every v* tag for
linux/darwin/windows × amd64/arm64. The binary is statically linked (pure-Go
SQLite, CGO_ENABLED=0).
Five skills, each a natural-language playbook over sjctl. A typical loop:
search offers → set up your profile → evaluate the interesting ones →
track what you apply to → digest new matches as they appear.
Translates a plain-language request into a sjctl search query, runs it, and shows
the best matches as a clickable table.
- Triggers on: "find me senior Go remote jobs", "show backend roles in Warsaw 25k+", "any React jobs?"
- Under the hood: maps your words to flags —
-d <Division>,--term,--category,--experience,--city,--remote,--min-salary, sorting, paging — then runssjctl search … --json. Divisions and experience levels are case-sensitive (IT, Engineering, Marketing, Sales, HR, Logistics, Finances, Other). - Output: a markdown table where each title links to the live posting on
solid.jobs, plus company, salary, work mode, location, and the
jobOfferKeyused by the other skills. Searching caches offers locally, so those keys are immediately trackable/evaluable. - Chains to:
/jobs-evaluate(is it worth it?) or/jobs-track(save it).
Turns a self-description or pasted CV into a stored profile. The profile is the yardstick every evaluation uses, and it lives in the database, not a file.
- Triggers on: "set up my profile", "here's my CV", "update my preferences", "switch to my contracting profile", "what's in my profile?"
- What it captures: role & seniority, skills (strong/working/learning),
compensation (minimum, target, contract type), location & work mode,
deal-breakers, nice-to-haves — the same dimensions
/jobs-evaluatescores. - Under the hood: fills the
config/profile.mdlayout from what you said, writes it to a temp file, and saves it withsjctl profile add <name> --file …(orsjctl profile importto update). Manage profiles withsjctl profile list,profile show, andprofile set-defaultto switch the active one. - Chains to: everything —
/jobs-evaluateand/jobs-digestgrade against the active profile (or any named one via--profile).
Scores a cached offer against your profile, gives an A–F verdict, and saves it.
-
Triggers on: "is this offer worth it?", "evaluate this job", "rate this one".
-
Rubric — six weighted dimensions, each A–F:
Dimension Weight What it checks Skill match 30% required skills vs your strong/working skills Salary fit 25% offer band vs your minimum and target Seniority fit 15% offer level vs your seniority Work mode / location 15% remote/hybrid/onsite and city vs preference Contract type 10% B2B vs employment vs preference Red flags 5% vague scope, missing salary, deal-breakers hit A violated deal-breaker caps the overall grade at D. Scale: A = apply now, B = strong, C = worth a look, D = weak, F = skip.
-
Under the hood: reads the cached offer plus
sjctl profile show --json, then persists the verdict withsjctl evaluate save <offerKey> --grade … --dimensions … --rationale …. Saved grades show up in the tracker board. -
Chains to:
/jobs-trackwhen the grade is good.
Moves offers through saved → applied → interview → offer / rejected, with notes
and auto-expiry once an offer's validTo passes.
- Triggers on: "I applied to this", "move it to interview", "show my pipeline", "where am I with my applications?"
- Under the hood:
sjctl track add/list/set/note/rm;listauto-expires stale offers first so the board always reflects what's still open. - Output: a clickable board grouped by status — title (linked to the posting), company, status, grade (from the latest evaluation), and key.
- Chains from:
/jobs-search,/jobs-evaluate,/jobs-digest.
Runs your saved searches (watches), reports only offers you haven't seen, and triages them against your profile.
- Triggers on: "what's new?", "any new jobs?", "give me today's digest".
- Prerequisite: at least one watch (
sjctl watch add my-go-roles -d IT --term golang --min-salary 20000). - Under the hood:
sjctl sync --jsonruns every watch, caches results, and returns only thenewarray; the skill ranks those by fit (same dimensions as evaluate) and marks them seen so they won't resurface. - Output: a short clickable digest table — title (linked), company, salary, mode, why it fits, key.
- Chains to:
/jobs-trackor/jobs-evaluatefor the best ones.
The skills are plain markdown that shell out to sjctl with no Claude-specific
tooling, so they work with any coding agent. skills.sh installs them under
.claude/skills/; agents that read an AGENTS.md (e.g. Codex) get the same
playbooks via the repo-root AGENTS.md, which lists the skills and the
sjctl resolution order. One source of truth, every agent.
go build -o sjctl ./cmd/sjctl
# search — table now includes a clickable LINK column
./sjctl search -d IT --term golang --remote --min-salary 20000
# KEY TITLE COMPANY SALARY MODE LOCATION LINK
# abc123 Senior Go Engineer Acme 22000-28000 PLN remote Remote https://solid.jobs/…
# set up your profile, then evaluate offers against it
./sjctl profile import default config/profile.md
# track an offer through the pipeline
./sjctl track add <jobOfferKey>
./sjctl track set <jobOfferKey> applied
# save a watch and check for new offers
./sjctl watch add my-go-roles -d IT --term golang --remote
./sjctl syncIn Claude Code, use the skills: /jobs-search, /jobs-create-profile, /jobs-evaluate,
/jobs-track, /jobs-digest.
- Search offers by division, skill, city, experience, salary, remote — with clickable links to each posting.
- Profiles stored in the database; build them from natural language and switch between them.
- Track applications through saved → applied → interview → offer/rejected, with
auto-expiry past
validTo. - Evaluate offers A–F against your profile, persisted for later review.
- Watch & digest saved searches, reporting only offers you haven't seen.
- Stats: salary min/median/max, remote share, counts by experience level.
See CLAUDE.md for architecture and the full command reference, and AGENTS.md for using the skills with other agents.
MIT