jobwatch helps technical job seekers find relevant roles from direct sources before they are buried on large job boards.
It monitors company career pages and other unaggregated sources you choose, reads the full job description, and matches jobs against your CV and preferences. Instead of noisy keyword alerts, you get a short digest of opportunities that are actually worth your attention.
Example:
git clone git@github.com:jvdheyden/jobwatch.git && cd "$(basename "$_" .git)"bash scripts/bootstrap_machine.sh --agent {claude,codex,gemini}- Optional: run
bash scripts/start_setup_agent.sh --agent {claude,codex,gemini}only if bootstrap did not start guided setup automatically or was invoked with--no-start-setup-agent.
For a more detailed set-up guide, see New User Setup.
- Find roles earlier: track company pages and other direct sources, not just aggregators.
- Better matching: evaluate the full job description against your CV and preferences, not just keywords.
- Stay focused: get a concise digest by email, Telegram, or as Markdown.
jobwatch is a good fit if you:
- are comfortable using the command line
- want more control than standard job alerts provide
It is probably not a good fit if you:
- do not have access to a supported coding-agent CLI account or API key
- do not want to use a CLI tool
- are on Windows (we support MacOS and most Linux distributions)
This repository runs an agent-assisted job-search workflow with per-track discovery, ranking, digest generation, and optional delivery to Logseq, email, or Telegram. Scheduled automation supports Codex CLI, Claude Code CLI, and Gemini CLI.
Each track run produces local JSON and Markdown artifacts first. Delivery is a separate opt-in step.
-
Requirements:
- Python 3
- the Codex CLI, Claude Code CLI, or Gemini CLI
- for Claude, run Claude Code login locally before scheduled runs
- for Gemini, authenticate Gemini CLI locally before scheduled runs
- on Linux with Codex,
bwrapif you want Codex sandboxing backed by Bubblewrap
-
From the repo root, choose the automation agent and bootstrap the checkout for local use:
bash scripts/bootstrap_machine.sh --agent claude # or bash scripts/bootstrap_machine.sh --agent codex # or bash scripts/bootstrap_machine.sh --agent gemini
This writes machine-local config, creates local profile placeholders, bootstraps the repo-local virtualenv, and generates scheduler artifacts under
.scheduler/. In an interactive terminal, bootstrap offers to start the guided setup agent; in non-interactive runs, pass--start-setup-agentto launch it automatically.What the bootstrap script writes
Machine-local config lives in `.env.local`, which is gitignored. `setup_machine.sh` writes:JOB_AGENT_ROOTJOB_AGENT_PROVIDERJOB_AGENT_BIN- optional
LOGSEQ_GRAPH_DIR - optional
JOB_AGENT_SECRETS_FILEplus non-secretJOB_AGENT_SMTP_*placeholders for email delivery
Local profile data lives in
profile/, which is also gitignored. Setup creates default placeholders:profile/cv.md: the primary agent-readable CV contextprofile/prefs_global.md: durable preferences that apply across tracks
Before or during your first track setup, replace those placeholders with your own information. You can also copy a PDF CV into
profile/; ifprofile/cv.mdis still the default, the setup agent can help turn the PDF into Markdown. The Markdown CV remains the canonical file the agent reads.If you only need to regenerate machine-local config later, run:
bash scripts/setup_machine.sh --agent claude # or bash scripts/setup_machine.sh --agent codex # or bash scripts/setup_machine.sh --agent gemini
-
If you are on Ubuntu and using Codex with
bwrap, install the generated AppArmor profile:sudo bash scripts/install_bwrap_apparmor.sh
Skip this on macOS. On Linux, this is only needed on hosts where AppArmor restricts unprivileged user namespaces.
-
Run the guided setup agent to create your first search track:
bash scripts/start_setup_agent.sh --agent claude # or bash scripts/start_setup_agent.sh --agent codex # or bash scripts/start_setup_agent.sh --agent gemini
The setup flow fills local profile files, creates the track files, discovers and validates sources, runs the first local digest before email testing, asks which delivery methods you want, configures scheduling if requested, and validates the track.
Track-specific preferences live in
tracks/<track-slug>/prefs.md. They are still required even whenprofile/cv.mdandprofile/prefs_global.mdare filled, because each track can have narrower goals, keywords, constraints, and red flags. -
Let the setup agent configure delivery and scheduling.
The setup agent asks whether you want scheduled runs, how often they should run, and at what local time. It then writes
.schedule.localwithscripts/configure_schedule.pyand installs the shared scheduler withbash scripts/install_scheduler.sh.Supported schedule choices:
- daily at
HH:MM - weekly on
mon,tue,wed,thu,fri,sat, orsunatHH:MM - monthly on day
1through31atHH:MM
On Linux, scheduler install updates your user crontab with a checkout-specific per-minute dispatcher. On macOS, it installs a checkout-specific LaunchAgent. If you skip scheduling during setup, you can still run tracks manually.
- daily at
To run a track immediately:
bash scripts/run_track.sh --track <track-slug>By default, this leaves the local JSON and Markdown artifacts in the repository and does not deliver them anywhere else.
Optional delivery targets can be requested per run:
bash scripts/run_track.sh --track <track-slug> --delivery logseq
bash scripts/run_track.sh --track <track-slug> --delivery email
bash scripts/run_track.sh --track <track-slug> --delivery telegram
bash scripts/run_track.sh --track <track-slug> --delivery logseq --delivery email
bash scripts/run_track.sh --track <track-slug> --delivery logseq --delivery telegramTo run the repo test suite:
bash scripts/test.shFor an architecture overview see docs/architecture.md. For the fork-and-PR workflow see CONTRIBUTING.md.
