Repository navigation
Architecture
gysosin edited this page Oct 8, 2026
·
1 revision
flowchart LR
UI[React dashboard<br/>app/web] -->|JSON API, session cookie| API[FastAPI<br/>app/server.py]
API --> RUN[Runner + scheduler<br/>app/scheduler.py]
RUN --> PIPE[Tasks<br/>app/pipeline.py, app/gmail.py]
PIPE --> SRC[Job sources<br/>boards, Instahyre, CLIs]
PIPE --> AG[Claude Agent SDK<br/>app/agent.py]
AG --> G[Tool guard<br/>app/guards.py]
PIPE --> TEX[Sandboxed TeX<br/>app/texc.py]
PIPE --> TR[(job_search_tracker.csv)]
API --> TR
PIPE --> GM[Gmail IMAP<br/>read-only]
- Deterministic steps are plain Python: scraping, dedup, state, page counts, layout checks, the tracker. Judgement steps go to Claude: triage, scoring, drafting, "Why this role?", reply classification, interview prep.
-
The tracker CSV is the source of truth. The dashboard reads it on every request, so hand edits show up at once. Writes go through
app/store.pywith a lock, and status moves forward only. - One process. FastAPI serves the API and the built dashboard; a background runner executes one task at a time from a queue; the scheduler submits tasks on time.
| Module | Role |
|---|---|
app/server.py |
HTTP API, login, static dashboard, task list |
app/scheduler.py |
Runner (queue, run history, per-run logs, cancel) and Schedules
|
app/pipeline.py |
daily_run, draft_url, interview, deadline_alert, why_roles; scrape, dedup, triage, score, draft, verify, record |
app/boards.py |
Greenhouse / Ashby / Lever career boards |
app/instahyre.py |
Instahyre search and posting pages |
app/companies.py |
company size lookup and cache |
app/gmail.py |
the Gmail check |
app/agent.py |
Claude calls with structured output; lean mode for pure text tasks (short system prompt, no project files, thinking off) |
app/guards.py |
the PreToolUse hook every agent tool call passes |
app/texc.py |
LaTeX compile inside bubblewrap |
app/store.py |
tracker, config, settings, form answers |
app/notify.py |
ntfy pushes |
app/prompts/ |
one prompt per step |
| Call | Tools | Output |
|---|---|---|
| Triage | none | {keep: [keys]} |
| Company size | WebSearch | {sizes: [...]} |
| Score | Read (the batch file and evaluation guide) | per job: score, location verdict, gaps, deadline |
| Draft | Read, Write, Edit, Glob, Grep, guarded Bash, WebFetch, WebSearch | status, apply link, notes, deadline |
| Gmail replies | none (lean) | per email: signal, application, reason |
| Why this role? (backfill) | Read (the saved posting) | the answer text; Python checks it for banned names, then saves it |
| Interview prep | the drafting tool set, guarded | path of interview_prep.md
|
Every call has a JSON schema, so results are validated structures, not free text.
React, Vite, Tailwind and TanStack Query, built to app/web/dist and served by FastAPI. Light and dark themes, phone layout, a command palette (Ctrl K) and live run logs.
Apply Desk · MIT · Built on AI Job Search · Screenshots use fictional demo data
Get started
Using it
- Dashboard Tour
- Daily Search Pipeline
- Job Sources
- Gmail Tracking
- Drafts and Interview Prep
- Schedules and Notifications
Reference
Help