Skip to content

Architecture

gysosin edited this page Oct 8, 2026 · 1 revision

Architecture

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]
Loading

Principles

  • 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.py with 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.

Modules

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

Claude calls

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.

Front end

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.

Clone this wiki locally