Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
326 commits
Select commit Hold shift + click to select a range
89e72ac
Recover OAuth callbacks without auth flow query
LEANDERANTONY Mar 18, 2026
e56d05e
Require login for all AI features
LEANDERANTONY Mar 18, 2026
704905e
Refresh public docs and demo assets
LEANDERANTONY Mar 18, 2026
beff468
Remove local setup and testing instructions from README
LEANDERANTONY Mar 18, 2026
74bf69f
Document safe rollout for job backend
LEANDERANTONY Mar 18, 2026
9439471
Add job backend foundation and imported JD review
LEANDERANTONY Mar 19, 2026
fd3383e
feat(jd-summary): add readable JD summary view, service, and state
LEANDERANTONY Mar 20, 2026
5c43e40
Build recent-first Greenhouse search results UI
LEANDERANTONY Apr 2, 2026
4c23d7d
Add Lever provider and refine multi-source job search
LEANDERANTONY Apr 2, 2026
fc2f244
Harden pytest runs with default timeout
LEANDERANTONY Apr 2, 2026
1cc5a9f
Improve job search matching and workspace restore
LEANDERANTONY Apr 2, 2026
f0a51d0
Add saved jobs shortlist flow
LEANDERANTONY Apr 2, 2026
d671077
Polish job search UX and refresh docs
LEANDERANTONY Apr 2, 2026
7825d9d
Refine shortlist ordering and search matching
LEANDERANTONY Apr 3, 2026
2997a86
Prepare backend rollout configuration
LEANDERANTONY Apr 3, 2026
fce3ad1
Speed up assistant chat with session reuse
LEANDERANTONY Apr 20, 2026
e87092c
Fix assistant follow-up drift and search responsiveness
LEANDERANTONY Apr 20, 2026
6703fbd
Add Next.js workspace and FastAPI deployment flow
LEANDERANTONY Apr 22, 2026
4fbb953
Align frontend rewrite target with custom API domain
LEANDERANTONY Apr 22, 2026
a843099
Handle string fit summaries in workspace assistant
LEANDERANTONY Apr 22, 2026
39ffa3d
Clarify assistant requires workspace run
LEANDERANTONY Apr 22, 2026
0fc31ed
Preserve imported job titles in workspace analysis
LEANDERANTONY Apr 22, 2026
fddb8f1
Restore staged workflow progress in workspace UI
LEANDERANTONY Apr 22, 2026
e7fbf42
checkpoint: refine workspace UI flow and theme
LEANDERANTONY Apr 22, 2026
9ab3516
checkpoint: refine workspace visual system
LEANDERANTONY Apr 22, 2026
fbf6379
refine workspace theme and action styling
LEANDERANTONY Apr 22, 2026
132260d
Enable Supabase saved jobs configuration
LEANDERANTONY Apr 23, 2026
9174bfd
Refine workspace run flow and hero layout
LEANDERANTONY Apr 23, 2026
b090e61
Restore saved job action in search results
LEANDERANTONY Apr 23, 2026
8a49305
Rebaseline app around Next.js workspace
LEANDERANTONY Apr 23, 2026
8d68a7f
Improve workspace assistant and analysis flow
LEANDERANTONY Apr 24, 2026
9298782
chore: remove Streamlit-era dead code (orchestrator layer)
LEANDERANTONY Apr 24, 2026
d75a0e7
chore: drop dead strategy-prompt test
LEANDERANTONY Apr 25, 2026
769e4d8
chore: prune dead prompt builders, routing keys, and helpers
LEANDERANTONY Apr 25, 2026
a6443bf
fix: bump assistant reasoning default to medium
LEANDERANTONY Apr 25, 2026
784b619
feat(backend): add per-user/IP rate limiting with slowapi
LEANDERANTONY Apr 25, 2026
c07da74
docs: archive pre-migration ROADMAP.md
LEANDERANTONY Apr 25, 2026
ab3cefa
docs: remove stale pre-migration planning docs
LEANDERANTONY Apr 25, 2026
80c02af
docs: remove archived ROADMAP.md
LEANDERANTONY Apr 25, 2026
f4edad5
docs: clean up ADR index and disambiguate DEVLOG day headers
LEANDERANTONY Apr 25, 2026
22b2cd9
docs: add NEXT-STEPS-FRONTEND.md handoff for items 2 and 3
LEANDERANTONY Apr 25, 2026
9138ead
wip: assistant panel polish + minor DEVLOG fix
LEANDERANTONY Apr 25, 2026
0ae8c14
frontend(workspace): extract icon SVGs to workspace/icons.tsx
LEANDERANTONY Apr 25, 2026
63a66c5
frontend(workspace): add Zustand store with initial ui slice (sidebar…
LEANDERANTONY Apr 25, 2026
ac4b608
frontend(workspace): extract Sidebar and AssistantPanel components
LEANDERANTONY Apr 25, 2026
a87605c
frontend(workspace): extract ArtifactViewer component
LEANDERANTONY Apr 25, 2026
470915c
frontend(workspace): extract JDReview component (move buildSectionPar…
LEANDERANTONY Apr 25, 2026
4316686
frontend(workspace): extract AnalysisRunner component
LEANDERANTONY Apr 25, 2026
4a1ec36
frontend(workspace): extract ResumeIntake component (upload + builder…
LEANDERANTONY Apr 25, 2026
d115fdd
frontend(workspace): extract JobSearch component (move resultPreview/…
LEANDERANTONY Apr 25, 2026
89b6762
frontend(workspace): move to top-level WorkspaceShell + fold old layo…
LEANDERANTONY Apr 25, 2026
9b5e8dc
frontend(workspace): extract useArtifactExport hook (preview useEffec…
LEANDERANTONY Apr 25, 2026
7e23172
frontend(workspace): extract useAssistantHistory hook (localStorage p…
LEANDERANTONY Apr 25, 2026
0def464
frontend(workspace): extract useSavedJobs hook (load/save/remove + de…
LEANDERANTONY Apr 25, 2026
ccd1f06
frontend(workspace): extract useAnalysisJob hook (run + polling state…
LEANDERANTONY Apr 25, 2026
1540acd
frontend(workspace): extract useWorkspaceSession hook (auth bootstrap…
LEANDERANTONY Apr 25, 2026
f94be3c
frontend(workspace): remove thin job-application-workspace.tsx re-exp…
LEANDERANTONY Apr 25, 2026
5a7daba
frontend(workspace): wire ESLint (eslint 8 + eslint-config-next 14) a…
LEANDERANTONY Apr 25, 2026
6ad64fb
frontend(workspace): silence intentional react-hooks/exhaustive-deps …
LEANDERANTONY Apr 25, 2026
f5b9b45
chore(gitignore): exclude .codex-local, tsbuildinfo, and local design…
LEANDERANTONY Apr 25, 2026
3059b66
Route app subdomain to workspace with clean URL
LEANDERANTONY Apr 26, 2026
bb13242
Install Vercel Web Analytics
vercel[bot] Apr 26, 2026
03cf04a
Merge pull request #1 from LEANDERANTONY/vercel/install-vercel-web-an…
LEANDERANTONY Apr 26, 2026
0fefbaa
Add cookie auth and VPS auto deploy
LEANDERANTONY Apr 27, 2026
7fd1700
Fix analysis job start response
LEANDERANTONY Apr 27, 2026
d636500
Harden workflow snapshot rehydration
LEANDERANTONY Apr 27, 2026
91c5110
Add live app badge to README
LEANDERANTONY Apr 27, 2026
43d02aa
Update README with live app links
LEANDERANTONY Apr 27, 2026
de42f8b
Add explicit workspace auth handoff
LEANDERANTONY Apr 27, 2026
98dd272
Replace placeholder brand marks with logo
LEANDERANTONY Apr 27, 2026
0ee930f
Add app favicon assets
LEANDERANTONY Apr 27, 2026
96aeeb2
Refresh brand and favicon assets
LEANDERANTONY Apr 27, 2026
90a8371
Refresh final brand assets
LEANDERANTONY Apr 27, 2026
3bfef70
docs: highlight grounded agent architecture
LEANDERANTONY Apr 29, 2026
87a31ec
docs: add job search architecture diagram
LEANDERANTONY Apr 29, 2026
6f997af
Remove stack and local development sections from README
LEANDERANTONY Apr 29, 2026
3ccf3ac
Add workspace app link to README
LEANDERANTONY Apr 29, 2026
664a423
Redesign workspace UI to Direction B "Workbench"
LEANDERANTONY May 5, 2026
f3af16f
Polish assistant FAB: deeper black-blue surface + full-width replies
LEANDERANTONY May 5, 2026
5e14540
Fix: clear analysisLoading + Running notice on workflow completion
LEANDERANTONY May 5, 2026
461fd57
Fix: landing 'Sign out' button no longer reads 'Signing out…' on Ente…
LEANDERANTONY May 5, 2026
d03e40f
Restore landing fonts; bump workspace base size + button/chip metrics
LEANDERANTONY May 5, 2026
aeb06f8
Lift workspace chrome sizes for readability on standard 1080p
LEANDERANTONY May 5, 2026
cee3821
Layout: cap canvas width, restructure pipeline grid, collapse intake …
LEANDERANTONY May 5, 2026
e7302b0
Polish: honest hero, vertical skills/experience, friendly pipeline la…
LEANDERANTONY May 5, 2026
9db23d8
Workspace fonts → landing pair; sections collapsible for mobile
LEANDERANTONY May 5, 2026
cae357e
Resume builder: rename, mode reset on commit, name-pending fallbacks
LEANDERANTONY May 5, 2026
0517983
Resume builder draft: auto-grow textareas + collapsible sections per …
LEANDERANTONY May 5, 2026
4318593
Resume builder: fix basics extraction, role over-capture, review prog…
LEANDERANTONY May 5, 2026
350bbb5
De-boxify: editorial document treatment for Draft profile + JD body
LEANDERANTONY May 5, 2026
c64436e
Atmospheric polish — page grain, layered surfaces, richer hover + focus
LEANDERANTONY May 5, 2026
f7d900b
Motion + delight pass — entrance animations, micro-interactions, coun…
LEANDERANTONY May 5, 2026
923bd56
Step rail: unified pill nav with progress connector + tooltips
LEANDERANTONY May 5, 2026
4358820
Mobile responsive pass — single 540px breakpoint covers every surface
LEANDERANTONY May 5, 2026
9fcb612
Mobile bug-fix pass — hero chip wrap, account stats list, brand name
LEANDERANTONY May 5, 2026
abe08f3
Inset account popover sections horizontally
LEANDERANTONY May 5, 2026
0b5e6ff
Stretch intake mode toggle on mobile
LEANDERANTONY May 5, 2026
d854a12
Collapse pipeline cards on mobile to the relevant stage
LEANDERANTONY May 5, 2026
7f818c0
Drop empty resume sections + editorial type pairing
LEANDERANTONY May 5, 2026
c7d73cd
Restore workflow sections; drop only Certifications when empty
LEANDERANTONY May 5, 2026
a392fe6
Allow Experience to drop when empty (student / early-career case)
LEANDERANTONY May 5, 2026
9fed3a6
Add Projects + Publications resume sections; un-clip page-2 overflow
LEANDERANTONY May 5, 2026
08b0532
Match resume PDF + parsed-view to the cover-letter family
LEANDERANTONY May 6, 2026
5e05146
Add switchable professional_neutral theme for resume + cover letter
LEANDERANTONY May 6, 2026
2b8f051
Switch neutral resume body to Georgia to match cover letter family
LEANDERANTONY May 6, 2026
68cc61e
Harden the deterministic resume parser; route TXT through the LLM hybrid
LEANDERANTONY May 6, 2026
91a5f7c
Expand parser-quality test set 6 → 15 fixtures (unseen formats)
LEANDERANTONY May 6, 2026
82dfc82
Simplify resume parser hybrid: pure LLM source-of-truth + full fallback
LEANDERANTONY May 6, 2026
5453913
Deterministic parser polish: 0.81 → 0.92 across 15 fixtures
LEANDERANTONY May 6, 2026
18d5c58
Add Tier-2 renderer fidelity test + fix double-escape on experience meta
LEANDERANTONY May 6, 2026
0279dd0
Tier-1 baseline for JD parser: 15 fixtures, deterministic average 0.78
LEANDERANTONY May 6, 2026
c50c8e9
LLM JD parser: 0.78 → 0.99 across the 15-fixture test set
LEANDERANTONY May 6, 2026
37acb5e
Skill canonicalization: collapse 'Postgres' / 'PostgreSQL' synonyms i…
LEANDERANTONY May 6, 2026
dfedd0f
Remove FitAgent + application package report + bundle endpoint
LEANDERANTONY May 6, 2026
84c1698
TailoringAgent battle-test: 0.99 average across 6 (resume, JD) pairs
LEANDERANTONY May 6, 2026
c9ac9e0
ReviewAgent battle-test: 1.00 LLM, 0.69 deterministic across 6 scenarios
LEANDERANTONY May 6, 2026
f4ce384
Per-profile resume section ordering: students lead with Education, ac…
LEANDERANTONY May 6, 2026
bd78156
ResumeGenerationAgent battle-test: LLM 1.00, det 0.94 across 6 pairs
LEANDERANTONY May 6, 2026
efba3ff
CoverLetterAgent battle-test: LLM 0.97, det 0.95 across 6 pairs
LEANDERANTONY May 6, 2026
e2e3d4e
Add docs/PUNCHLIST.md as durable handoff for chat continuation
LEANDERANTONY May 6, 2026
84f67db
Punch list 1-14 + conversational LLM resume builder + frontend chat UI
LEANDERANTONY May 6, 2026
291e422
Fix workspace chat bubbles so they actually look like bubbles
LEANDERANTONY May 7, 2026
3604585
Revert "Fix workspace chat bubbles so they actually look like bubbles"
LEANDERANTONY May 7, 2026
6dc4cf8
Surface resume-builder persistence outcome to the user
LEANDERANTONY May 7, 2026
dc7c8b0
Resume-builder drafts get a 7-day TTL with active-user refresh
LEANDERANTONY May 7, 2026
428faab
Redirect signed-out users away from /workspace to the landing page
LEANDERANTONY May 7, 2026
333dff2
Cross-origin redirect when signed-out user hits the workspace
LEANDERANTONY May 7, 2026
a617e20
PUNCHLIST: capture DOCX export plan + clean up done items
LEANDERANTONY May 7, 2026
6db8d6f
Phase 1: DOCX exporter foundation (classic_ats theme)
LEANDERANTONY May 7, 2026
7da724f
Phase 2: wire DOCX through artifact export, drop markdown export path
LEANDERANTONY May 7, 2026
0513721
Phase 3: frontend cleanup sweep — markdown export removed
LEANDERANTONY May 7, 2026
0f92179
Phase 4: professional_neutral DOCX theme + palette resolver
LEANDERANTONY May 7, 2026
f13912f
Phase 5: resume builder export endpoint
LEANDERANTONY May 7, 2026
6cb4f65
Phase 6: resume builder download row UI (Theme + PDF/DOCX buttons)
LEANDERANTONY May 7, 2026
acbf71e
Resume-builder content quality: LLM-first structuring + regex fallbac…
LEANDERANTONY May 7, 2026
9d0d226
Cache resume-builder structuring across exports + persistence
LEANDERANTONY May 7, 2026
00cd164
Resume-builder: recover full name when LLM intake drops a surname
LEANDERANTONY May 7, 2026
a611407
Add Tier-3 quality runner for resume-builder structuring pass
LEANDERANTONY May 7, 2026
133f743
Resume-builder: collect + render Projects and Publications sections
LEANDERANTONY May 7, 2026
284e256
Resume-builder: bucket skills into named categories
LEANDERANTONY May 7, 2026
37a4c27
Resume-builder: expand thin one-liner summaries via structuring pass
LEANDERANTONY May 7, 2026
0612bd3
Resume-builder structuring: bump model + token budget for expanded co…
LEANDERANTONY May 7, 2026
e108c3e
Frontend: surface Projects + Publications as draft-form sections
LEANDERANTONY May 7, 2026
0fa1e67
Phase 2: cached_jobs refresh worker + /admin/refresh-cache endpoint
LEANDERANTONY May 7, 2026
611aa02
Phase 3: cut /jobs/search to query cached_jobs (live= escape hatch kept)
LEANDERANTONY May 7, 2026
51a5f40
Phase 4: bump source pool to ~117 Greenhouse boards + 30 Lever sites
LEANDERANTONY May 7, 2026
8f22be9
Phase 5: pg_net enabled + cron schedule docs + frontend Expired badge
LEANDERANTONY May 7, 2026
2604891
Phase 5b: relevance-ranked cache search via Postgres RPC + post-fligh…
LEANDERANTONY May 7, 2026
b8f380c
Phase 6: bigger Greenhouse list (79) + Ashby adapter (36 boards)
LEANDERANTONY May 7, 2026
a0e0a20
Phase 7: Workday adapter (11 Fortune 500 tenants) + status reporting fix
LEANDERANTONY May 7, 2026
9055867
Phase 8 backend: work_mode + employment_type filters + sort_by
LEANDERANTONY May 7, 2026
807c556
Phase 8 frontend: dropdown filters + sort for job search
LEANDERANTONY May 7, 2026
6e36c8f
Filter popover: dismiss on click-outside + Escape
LEANDERANTONY May 7, 2026
5ab2359
Docs: DEVLOG Days 37-40, four new ADRs, architecture refresh
LEANDERANTONY May 7, 2026
6c71bbb
Error-handling pass: humanizer + static lint + synthetic scenarios
LEANDERANTONY May 8, 2026
a60e6e1
Docs: LATENCY-TEST-PLAN.md handoff for parallel chat
LEANDERANTONY May 8, 2026
7a75529
Landing redesign: scroll-driven Workbench narrative
LEANDERANTONY May 8, 2026
83a38c4
Landing iteration: centered hero, near-black cards, bento carousel
LEANDERANTONY May 8, 2026
617e149
Tests: latency baseline runner + first-run scorecard
LEANDERANTONY May 8, 2026
9892d4f
Bento: single-tile carousel with arrow + dot navigation
LEANDERANTONY May 8, 2026
00dc812
Hero title: explicit 3-line stack instead of balanced pyramid
LEANDERANTONY May 8, 2026
29cf2e6
Landing tightening pass: drop public block, balance gaps, simplify CTA
LEANDERANTONY May 8, 2026
a8efafe
Hero artifact: near-pure-black + add Experience section
LEANDERANTONY May 8, 2026
76abff6
Hero artifact: wider (1120px) so it doesn't feel too tall
LEANDERANTONY May 8, 2026
ec2f659
Footer: drop the Project column
LEANDERANTONY May 8, 2026
ce99706
Landing copy: rewrite from "tech docs" to product-marketing voice
LEANDERANTONY May 8, 2026
d7e19ac
Bento: drop the FAST SEARCH tile (4 tiles total now)
LEANDERANTONY May 8, 2026
940d872
Hero: replace hand-built artifact mock with real workspace screenshot
LEANDERANTONY May 8, 2026
50309ba
Workbench title: shorten to 'From resume to job-ready application'
LEANDERANTONY May 8, 2026
90f2418
Workbench title: 'From a fresh resume to job ready application'
LEANDERANTONY May 8, 2026
2014223
Titles: strip trailing full stops
LEANDERANTONY May 8, 2026
1344469
Copy: trim three lines tighter
LEANDERANTONY May 8, 2026
dc4f990
Workbench: top-align the sticky visual to match step text
LEANDERANTONY May 8, 2026
a506850
Workbench: shrink the last step block to natural height
LEANDERANTONY May 8, 2026
210ef75
Workbench: stretch the stage to fill its sticky container
LEANDERANTONY May 8, 2026
16b22f1
Workbench mock: match JD review's deep-dark card treatment
LEANDERANTONY May 8, 2026
3f7d773
Bento tiles: match JD review's deep-dark card treatment
LEANDERANTONY May 8, 2026
e97248e
Workbench: shrink stage to square + center-pin mocks
LEANDERANTONY May 8, 2026
f4df175
Workbench mocks: rebuild content to mirror the real workspace
LEANDERANTONY May 8, 2026
2a691f9
Workbench: align step text vertically with the centered visual
LEANDERANTONY May 8, 2026
a049ed8
Topbar: drop the standalone GitHub link
LEANDERANTONY May 8, 2026
c7231c1
Workspace: ungate Job Search + Job Detail steps
LEANDERANTONY May 8, 2026
ef5be60
Workspace: ungate the assistant chat
LEANDERANTONY May 8, 2026
e741549
Assistant: thread live workspace state into every query
LEANDERANTONY May 8, 2026
66879ee
Assistant: fix two prompt-context bugs found in battle test
LEANDERANTONY May 8, 2026
902e350
Assistant: refresh product knowledge to ground truth + auth note
LEANDERANTONY May 8, 2026
e9d2fb9
OpenAI: add 1 application-level retry on top of SDK retries
LEANDERANTONY May 8, 2026
d805726
OpenAI: route the budget-retry call through the app-retry helper too
LEANDERANTONY May 8, 2026
0b72c50
Orchestrator: per-agent retry — one more shot before pipeline fallback
LEANDERANTONY May 8, 2026
46cae4b
Orchestrator: per-agent fallback isolates failures
LEANDERANTONY May 8, 2026
f1e0d1d
Docs: DEVLOG Day 41 + three new ADRs + architecture refresh
LEANDERANTONY May 8, 2026
3421b90
Landing: mobile responsive fixes for the iPhone-class viewport
LEANDERANTONY May 8, 2026
cf03f59
Landing: tighten the mobile dropdown + recenter the hero
LEANDERANTONY May 8, 2026
19edc41
Landing: fix dropdown bleed-through + match final-CTA size
LEANDERANTONY May 8, 2026
f834e47
Landing: equalize the desktop topbar nav gaps
LEANDERANTONY May 8, 2026
263d83d
Landing: tone down the artifact glow around the hero screenshot
LEANDERANTONY May 8, 2026
5bb070a
Workspace: tighten the mobile rail + command palette
LEANDERANTONY May 8, 2026
7740980
Workspace: center the chevron inside command-palette item chips
LEANDERANTONY May 8, 2026
c84a285
Drop session-handoff docs before merging to main
LEANDERANTONY May 8, 2026
2e26e51
Merge frontend redesign
LEANDERANTONY May 8, 2026
83a4ced
Remove deployment notes section from README
LEANDERANTONY May 8, 2026
521e6e9
Reorganize docs assets + check in design-system reference material
LEANDERANTONY May 8, 2026
de4d5dd
README: refresh to reflect the current product
LEANDERANTONY May 8, 2026
7df7750
design_system: prune to the shipped handoff (drop scratch work)
LEANDERANTONY May 8, 2026
94ef8fa
design_system: add 02-jobs.png + 03-jd.png to handoff screens
LEANDERANTONY May 8, 2026
ab30aca
Move deploy/vps/ → backend/vps/ and update path refs
LEANDERANTONY May 8, 2026
beb123a
Drop dead frontend code + consolidate eval scripts under tests/quality
LEANDERANTONY May 8, 2026
a867f9c
Fix: untrack accidentally-committed worktree submodule + gitignore .c…
LEANDERANTONY May 8, 2026
facf822
Reorganize docs: SQL into docs/sql/, static + pdf_rendered into docs/
LEANDERANTONY May 8, 2026
3fd79c5
Refresh architecture diagram to match shipped pipeline
LEANDERANTONY May 8, 2026
d638fec
Revise README with visual tour and content updates
LEANDERANTONY May 8, 2026
630b6e8
Untrack design_system + finish the SVG move + README fixes
LEANDERANTONY May 8, 2026
18fde26
Refresh worker: fix Workday 0-jobs + Ashby chunk timeouts
LEANDERANTONY May 8, 2026
7cd5b94
CI: green up the test + frontend jobs
LEANDERANTONY May 8, 2026
23212f1
CI round 2: fix the 5 tests broken by earlier commits' side effects
LEANDERANTONY May 8, 2026
0eb338f
Refresh worker: chunk_size 30 globally (was per-source)
LEANDERANTONY May 9, 2026
9fdad2e
Docs + landing: refresh cadence is 4 hours, not 30 min
LEANDERANTONY May 9, 2026
082c8cb
Workday: don't trust total=0 on pages 2+ (CXS quirk on large boards)
LEANDERANTONY May 9, 2026
1fa237f
Lever: drop limit=100 — was silently capping Mistral and Palantir
LEANDERANTONY May 9, 2026
7f47f04
Landing: ship Pricing section (Free / Pro $9 / Business $39 per seat)
LEANDERANTONY May 14, 2026
d25e362
Landing pricing: tone down Pro card + work around Chrome dark-mode
LEANDERANTONY May 14, 2026
4c1615f
Landing pricing: refresh tier caps to match COGS analysis
LEANDERANTONY May 14, 2026
ff2fe2d
Tier shim: resolve_user_tier + TIER_CAPS table (no enforcement yet)
LEANDERANTONY May 14, 2026
b2a4947
Quota: aijobagent_quota_counters table + atomic check_and_increment h…
LEANDERANTONY May 14, 2026
6e893e6
Workspace: enforce tailored_applications + premium_applications quota…
LEANDERANTONY May 14, 2026
2dc76cd
Workspace: enforce assistant_turns + resume_parses + resume_builder_s…
LEANDERANTONY May 14, 2026
d249b28
Workspace: enforce job_searches + saved_jobs + saved_workspaces quotas
LEANDERANTONY May 14, 2026
68be1d5
Workspace: tier-aware model selection for premium workflows (review +…
LEANDERANTONY May 14, 2026
24a1840
Workspace: add /workspace/quota endpoint + frontend Premium toggle wi…
LEANDERANTONY May 14, 2026
c57d658
Maintenance: tier-aware saved_workspaces retention sweeper (Free 7d /…
LEANDERANTONY May 14, 2026
e6f13c3
Workspace quota: use string literal for 401 detail (lint fix)
LEANDERANTONY May 14, 2026
0ede6ea
Supabase: drop legacy saved_workspaces sweeper + harden RPC grants
LEANDERANTONY May 14, 2026
1b8cf95
Subscriptions: table migration + backend/subscriptions.py + tier reso…
LEANDERANTONY May 14, 2026
c3c3348
LS webhooks: POST /api/webhooks/lemonsqueezy with HMAC verification +…
LEANDERANTONY May 14, 2026
c3a80ea
LS checkout: frontend Upgrade CTA wiring + customer portal link
LEANDERANTONY May 14, 2026
a236c81
LS docs: .env.example entries + setup walkthrough in docs/
LEANDERANTONY May 14, 2026
d7d6311
Docs: DEVLOG entries for tier enforcement + Lemon Squeezy scaffold
LEANDERANTONY May 14, 2026
27c7c1d
Docs: ADR-020..023 for tier enforcement + Lemon Squeezy decisions
LEANDERANTONY May 14, 2026
8dacf9c
Docs: README refresh for tier enforcement + bumped ADR count
LEANDERANTONY May 14, 2026
48a6f6b
Fix: allow Free saved_workspace upsert (Codex P1 finding)
LEANDERANTONY May 14, 2026
5494630
Fix: align access cookie lifetime to refresh cookie (Codex P1 finding)
LEANDERANTONY May 14, 2026
b8fb594
Fix: remove cross-user PKCE flow fallback (Codex P2 finding)
LEANDERANTONY May 14, 2026
f23b273
Fix: LS hosted checkout URL path is /checkout/buy/<variant>
LEANDERANTONY May 14, 2026
1f2aeb6
Nightly eval: backend/nightly_eval.py CLI + ops doc cron entry
LEANDERANTONY May 14, 2026
ce92097
Schema-strict: Pydantic output models for all 9 LLM-producing agents
LEANDERANTONY May 14, 2026
4cad3d7
Schema-strict: run_structured_prompt + 6 agent migrations
LEANDERANTONY May 14, 2026
043304b
Cost tracking: aijobagent_run_traces table + record_trace helper
LEANDERANTONY May 14, 2026
3977af6
Cost tracking: openai_service cost computation + trace integration
LEANDERANTONY May 14, 2026
9e83cf8
Fixup: nightly_eval runner signatures (openai_service kwarg)
LEANDERANTONY May 14, 2026
1032838
Add .coderabbit.yaml: enable manual reviews on non-default base branches
LEANDERANTONY May 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
26 changes: 26 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# CodeRabbit configuration
# Docs: https://docs.coderabbit.ai/getting-started/configure-coderabbit

reviews:
# Default is "chill" — we want it to surface issues without
# blocking on style nits.
profile: chill

# Auto-review configuration. By default CodeRabbit only reviews PRs
# where the BASE branch is the repo's default branch (main).
# We open one-off full-repo audit PRs against the `coderabbit-root`
# branch (a non-default branch pointing at the initial commit) so
# we can ask `@coderabbitai full review` over the entire codebase.
# Add coderabbit-root to the allowed base list so those audit PRs
# actually get reviewed instead of "Review skipped".
auto_review:
enabled: true
drafts: false
base_branches:
- "main"
- "coderabbit-root"

# Allow @coderabbitai review / full review on any PR opened against
# any base branch in this repo — overrides the default "only on
# default-branch base" policy so manual triggers always work.
request_changes_workflow: false
13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.env
.git
.github
.pytest_cache
.venv
__pycache__
*.pyc
*.pyo
*.pyd
*.log
DEVLOG.md
docs/pdf_rendered
tests
135 changes: 135 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
## Optional for AI-assisted workflow and assistant features.
OPENAI_API_KEY=
OPENAI_MODEL_DEFAULT=gpt-5.4-mini
OPENAI_MODEL_HIGH_TRUST=gpt-5.4
OPENAI_MODEL_MID_TIER=gpt-5.4-mini
OPENAI_MODEL_PRODUCT_HELP=gpt-5.4-mini
OPENAI_MODEL_APPLICATION_QA=gpt-5.4
OPENAI_REASONING_DEFAULT=medium
OPENAI_REASONING_HIGH_TRUST=high
OPENAI_REASONING_PROFILE=medium
OPENAI_REASONING_JOB=medium
OPENAI_REASONING_FIT=medium
OPENAI_REASONING_TAILORING=medium
OPENAI_REASONING_STRATEGY=medium
OPENAI_REASONING_REVIEW=high
OPENAI_REASONING_RESUME_GENERATION=high
OPENAI_REASONING_PRODUCT_HELP=medium
OPENAI_REASONING_APPLICATION_QA=high

## Optional app base URL. Used as the default auth redirect URL when no
## explicit SUPABASE_AUTH_REDIRECT_URL is provided.
APP_BASE_URL=http://localhost:3000

## Required for the current login-first resume workflow, Google sign-in,
## persisted saved-workspace reload, and account-level quotas.
SUPABASE_URL=
SUPABASE_ANON_KEY=
## Service-role key used ONLY by the cached_jobs writer
## (/admin/refresh-cache) and reader (/jobs/search). Bypasses RLS —
## never send to the frontend, never use for user-scoped tables.
SUPABASE_SERVICE_ROLE_KEY=
SUPABASE_AUTH_REDIRECT_URL=http://localhost:3000/workspace
SUPABASE_APP_USERS_TABLE=app_users
SUPABASE_USAGE_EVENTS_TABLE=usage_events
SUPABASE_SAVED_WORKSPACES_TABLE=saved_workspaces
SUPABASE_SAVED_JOBS_TABLE=saved_jobs
SUPABASE_RESUME_BUILDER_SESSIONS_TABLE=resume_builder_sessions
SUPABASE_CACHED_JOBS_TABLE=cached_jobs
SAVED_WORKSPACE_TTL_HOURS=24
## Shared secret guarding /admin/refresh-cache. Set the same value in
## the Supabase pg_cron job's HTTP headers so the cron can include
## it. Rotate if leaked.
REFRESH_CACHE_SECRET=

## Optional job-search backend settings. Keep ENABLE_JOB_SEARCH_BACKEND=false
## until the separate backend service is available in the target environment.
ENABLE_JOB_SEARCH_BACKEND=false
JOB_BACKEND_BASE_URL=http://localhost:8000
JOB_BACKEND_HOSTPORT=
# Comma-separated lists of board / site identifiers. Each is the
# {token} in https://boards-api.greenhouse.io/v1/boards/{token}/jobs
# or the {site} in https://api.lever.co/v0/postings/{site}. The
# /admin/refresh-cache endpoint pulls every active job from each.
# Bad tokens surface as "error" in the refresh report's
# providers.greenhouse.errors[] (or .lever) — trim them from your
# env after the first refresh shows which ones failed.
#
# Validated seed list ~58 Greenhouse + 6 Lever = ~8.7K active jobs.
# Companies that previously used Greenhouse/Lever and migrated to
# Ashby (Linear, Vercel, Netlify, Supabase, OpenAI, ...) were
# trimmed after the first refresh — they 404'd. Add your own and
# they'll either show up as "ok" or "error" in the next refresh
# report.
GREENHOUSE_BOARD_TOKENS=databricks,stripe,mongodb,anthropic,cloudflare,datadog,waymo,okta,samsara,zscaler,roblox,airbnb,brex,sofi,gitlab,scaleai,intercom,affirm,gleanwork,figma,fivetran,pinterest,elastic,reddit,twilio,robinhood,boxinc,lyft,smartsheet,asana,instacart,cresta,motional,dropbox,nuro,zoominfo,discord,moloco,gusto,wayve,faire,classpass,chime,fastly,amplitude,monzo,twitch,peloton,opendoor,mercury,mozilla,qualtrics,sumologic,pagerduty,launchdarkly,mixpanel,marqeta,wikimedia,algolia,triplelift,airtable,descript,calendly,typeface,narvar,glossier,placerlabs,modernhealth,lastpass,honeycomb,udacity,bitwarden,assemblyai,coursera,planetscale,inflectionai,kayak,allbirds,hubspot
LEVER_SITE_NAMES=dnb,plaid,mistral,palantir,netflix,attentive
## Ashby boards. Modern AI/dev-tools tier (Linear, Cursor, Replit,
## Vercel, Cohere, Mistral, Sierra, Decagon, ...) — companies that
## migrated off Greenhouse/Lever in 2023-2025. Endpoint:
## https://api.ashbyhq.com/posting-api/job-board/{token}
ASHBY_BOARD_TOKENS=mistral,notion,elevenlabs,cohere,sierra,ramp,decagon,plaid,cursor,replit,lovable,perplexity,deepgram,gamma,writer,supabase,n8n,workos,exa,linear,render,substack,character,posthog,poolside,column,railway,warp,statsig,pinecone,weaviate,stytch,pika,runway,nylas,clerk
## Workday tokens are tenant:host:site triples — each Fortune 500
## company runs its own Workday tenant on a numbered host
## (wd1.myworkdayjobs.com, wd5, etc) at a public site. Validated
## tenants below unlock ~14.5K jobs. The bulk-validation script in
## scripts/probe_workday.py (or a similar one-off) finds more —
## many big companies (AMD, Intel, Tesla, Cisco, IBM) require
## tenant-specific request shapes that the default body doesn't
## satisfy; those return 422 and are excluded.
WORKDAY_BOARD_TOKENS=micron:wd1:External,nvidia:wd5:NVIDIAExternalCareerSite,citi:wd5:2,walmart:wd5:WalmartExternal,hpe:wd5:Jobsathpe,adobe:wd5:external_experienced,boeing:wd1:EXTERNAL_CAREERS,disney:wd5:disneycareer,hp:wd5:ExternalCareerSite,blackrock:wd1:BlackRock_Professional,workday:wd5:Workday

## Frontend origin settings for the Next.js transition.
FRONTEND_APP_URL=http://localhost:3000
CORS_ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000
## Leave AUTH_COOKIE_DOMAIN empty on localhost. In production, set it to
## your parent domain (for example, .job-application-copilot.xyz) so the
## landing and workspace subdomains share the same HttpOnly session.
AUTH_COOKIE_DOMAIN=
AUTH_COOKIE_SECURE=false
AUTH_COOKIE_SAMESITE=lax

## AI-assisted workflow and the in-app assistant are login-required in the
## active UI. This flag controls whether the workflow button also enforces that.
AUTH_REQUIRED_FOR_ASSISTED_WORKFLOW=true
AUTH_DEFAULT_PLAN_TIER=free
AUTH_DEFAULT_ACCOUNT_STATUS=active
## Only internal unrestricted testing accounts belong here.
## Leave normal quota-test accounts out of this list so they stay on the free-tier path.
AUTH_INTERNAL_USER_EMAILS=
FREE_TIER_MAX_CALLS_PER_DAY=12
FREE_TIER_MAX_TOKENS_PER_DAY=60000
PAID_TIER_MAX_CALLS_PER_DAY=80
PAID_TIER_MAX_TOKENS_PER_DAY=400000

## Lemon Squeezy subscription integration.
##
## The backend uses these to validate webhook deliveries (HMAC over the
## raw body) and to mint customer portal URLs. The frontend uses the
## NEXT_PUBLIC_ values below to build the hosted checkout URL.
##
## Until these are populated the backend webhook returns 503 (with a
## Retry-After) on every delivery and the pricing CTA falls back to
## "Coming soon" for Pro / "Contact us" (mailto) for Business. This
## lets the integration ship to main without LS being live.
##
## Build against LS *sandbox* mode by default. Sandbox has its own
## webhook secret + API key; the dashboard URL is the same surface.
## See docs/lemon-squeezy.md for the full setup walkthrough.
AIJOBAGENT_LEMONSQUEEZY_API_KEY=
AIJOBAGENT_LEMONSQUEEZY_WEBHOOK_SECRET=
AIJOBAGENT_LEMONSQUEEZY_STORE_ID=
## LS variant_id values (numeric strings on the variant API resource).
## One per paid tier; mapping flows
## variant_id -> tier -> TIER_CAPS
## inside backend.webhooks.lemonsqueezy._tier_for_variant.
AIJOBAGENT_LEMONSQUEEZY_PRODUCT_VARIANT_PRO=
AIJOBAGENT_LEMONSQUEEZY_PRODUCT_VARIANT_BUSINESS=

## Public (frontend) LS env. NEXT_PUBLIC_ prefix gets these inlined
## into the JS bundle at build time. The store_id here is the
## subdomain piece (e.g. "yourstore" -> https://yourstore.lemonsqueezy.com).
## variant ids must match the AIJOBAGENT_* values above (same upstream
## resource, two views).
NEXT_PUBLIC_LEMONSQUEEZY_STORE_ID=
NEXT_PUBLIC_LEMONSQUEEZY_PRODUCT_VARIANT_PRO=
NEXT_PUBLIC_LEMONSQUEEZY_PRODUCT_VARIANT_BUSINESS=
60 changes: 60 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v5

- name: Set up uv
uses: astral-sh/setup-uv@v6
with:
version: "latest"

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"

- name: Sync dependencies
run: uv sync --group dev --frozen

- name: Compile check
run: uv run python -m compileall backend src tests

- name: Run tests
run: uv run pytest -v

frontend:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v5

- name: Set up Node
uses: actions/setup-node@v5
with:
node-version: "24"
cache: npm
cache-dependency-path: frontend/package-lock.json

- name: Install dependencies
working-directory: frontend
run: npm ci

- name: Lint
working-directory: frontend
run: npm run lint

- name: Build
working-directory: frontend
run: npm run build
117 changes: 117 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
name: Build & Deploy

on:
push:
branches: [main]

env:
IMAGE: ghcr.io/leanderantony/ai_job_application_agent/api
VPS_APP_DIR: /home/ubuntu/AI_Job_Application_Agent

jobs:
build-and-push:
name: Build Docker image to GHCR
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout
uses: actions/checkout@v5

- name: Log in to GHCR
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Build and push
uses: docker/build-push-action@v7
with:
context: .
push: true
tags: ${{ env.IMAGE }}:latest,${{ env.IMAGE }}:${{ github.sha }}
cache-from: type=registry,ref=${{ env.IMAGE }}:cache
cache-to: type=registry,ref=${{ env.IMAGE }}:cache,mode=max

deploy:
name: Deploy to VPS
runs-on: ubuntu-latest
needs: build-and-push
permissions:
contents: read
packages: read
env:
GITHUB_ACTOR: ${{ github.actor }}
GITHUB_TOKEN: ${{ github.token }}

steps:
- name: Checkout
uses: actions/checkout@v5

- name: Prepare VPS directory
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
port: ${{ secrets.VPS_PORT }}
script: |
mkdir -p "${{ env.VPS_APP_DIR }}/backend/vps"

- name: Copy deployment files
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
port: ${{ secrets.VPS_PORT }}
source: backend/vps/docker-compose.yml,backend/vps/docker-compose.override.yml
target: ${{ env.VPS_APP_DIR }}/backend/vps
strip_components: 2

- name: Deploy via SSH
uses: appleboy/ssh-action@v1
env:
IMAGE: ${{ env.IMAGE }}
GITHUB_ACTOR: ${{ env.GITHUB_ACTOR }}
GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }}
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
port: ${{ secrets.VPS_PORT }}
envs: IMAGE,GITHUB_TOKEN,GITHUB_ACTOR
script: |
echo "$GITHUB_TOKEN" | docker login ghcr.io -u "$GITHUB_ACTOR" --password-stdin
docker pull "$IMAGE:latest"
cd "${{ env.VPS_APP_DIR }}/backend/vps"
docker compose -p ai_job_application_agent up -d --no-deps --no-build --force-recreate api
docker logout ghcr.io

- name: Health check
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
port: ${{ secrets.VPS_PORT }}
script: |
echo "Waiting for AI Job Application Agent API to be healthy..."
for i in $(seq 1 12); do
STATUS=$(docker inspect --format='{{.State.Health.Status}}' ai-job-application-agent-api 2>/dev/null)
echo "Attempt $i: $STATUS"
if [ "$STATUS" = "healthy" ]; then
echo "Container is healthy"
exit 0
fi
sleep 5
done
echo "Container did not become healthy in time"
docker logs ai-job-application-agent-api --tail 30
exit 1
Loading
Loading