App: Peregrine Company: Circuit Forge LLC Source: github.com/pyr0ball/job-seeker (personal fork, not linked)
108 lines
4.8 KiB
Markdown
108 lines
4.8 KiB
Markdown
# Session Handoff — Generalization Implementation
|
|
|
|
**Date:** 2026-02-24
|
|
**For:** Next Claude session implementing the public fork
|
|
|
|
---
|
|
|
|
## Current State
|
|
|
|
The personal version (`/devl/job-seeker/`) is **complete and working** on `main`.
|
|
|
|
### What was completed in the 2026-02-24 session
|
|
- Survey Assistant page (`app/pages/7_Survey.py`) — text paste + screenshot via moondream2
|
|
- Vision Service (`scripts/vision_service/`) — FastAPI on port 8002, `job-seeker-vision` conda env
|
|
- LLM Router `images=` parameter — vision-aware routing
|
|
- `survey_responses` table + `survey_at` column in SQLite
|
|
- Kanban consolidation — applied+survey as pre-kanban section; offer+hired merged column
|
|
- `survey_received` email classifier label
|
|
- Forgejo remote: https://git.opensourcesolarpunk.com/pyr0ball/job-seeker.git
|
|
|
|
### Remote repo
|
|
```
|
|
git remote: https://git.opensourcesolarpunk.com/pyr0ball/job-seeker.git
|
|
branch: main (up to date as of 2026-02-24)
|
|
```
|
|
|
|
---
|
|
|
|
## What to Implement Next
|
|
|
|
Follow the plan at `docs/plans/2026-02-24-job-seeker-app-generalize.md`.
|
|
The design doc is at `docs/plans/2026-02-24-generalize-design.md`.
|
|
|
|
**Target directory:** `/Library/Development/devl/job-seeker-app/` (new repo, no shared history)
|
|
|
|
**CRITICAL:** Do NOT start implementing the public fork until explicitly asked. The user confirmed this.
|
|
|
|
---
|
|
|
|
## Complete List of Hardcoded Personal References
|
|
|
|
Everything that must be extracted into `config/user.yaml` via a `UserProfile` class:
|
|
|
|
| File | Hardcoded value | Generalized as |
|
|
|------|----------------|----------------|
|
|
| `company_research.py` | `"Meghan McCann"` in prompts | `profile.name` |
|
|
| `company_research.py` | `_NDA_COMPANIES = {"upguard"}` | `profile.nda_companies` |
|
|
| `company_research.py` | `_SCRAPER_DIR = Path("/Library/...")` | bundled in Docker image |
|
|
| `generate_cover_letter.py` | `SYSTEM_CONTEXT` with Meghan's bio | `profile.career_summary` |
|
|
| `generate_cover_letter.py` | `LETTERS_DIR = Path("/Library/...")` | `profile.docs_dir` |
|
|
| `4_Apply.py` | contact block (name/email/phone) | `profile.*` |
|
|
| `4_Apply.py` | `DOCS_DIR = Path("/Library/...")` | `profile.docs_dir` |
|
|
| `5_Interviews.py` | email assistant persona "Meghan McCann is a Customer Success..." | `profile.name + profile.career_summary` |
|
|
| `6_Interview_Prep.py` | `"Meghan"` in interviewer prompts | `profile.name` |
|
|
| `7_Survey.py` | `_SURVEY_SYSTEM` — "The candidate values collaborative teamwork..." | `profile.career_summary` or survey persona field |
|
|
| `scripts/vision_service/main.py` | `model_id = "vikhyatk/moondream2"`, `revision = "2025-01-09"` | `config/llm.yaml` vision_service block |
|
|
| `match.py` | `RESUME_PATH = Path("/Library/...Meghan_McCann_Resume...")` | configurable in Settings |
|
|
| `Home.py` | `"Meghan's Job Search"` | `f"{profile.name}'s Job Search"` |
|
|
| `finetune_local.py` | all `/Library/` paths + `"meghan-cover-writer"` | `profile.*` |
|
|
| `2_Settings.py` | `PFP_DIR`, host service paths (manage-services.sh etc.) | removed / compose-driven |
|
|
| `config/llm.yaml` | hard-coded `base_url` values | auto-generated from `user.yaml` |
|
|
|
|
---
|
|
|
|
## New Components to Dockerize
|
|
|
|
### Vision Service
|
|
- Currently: `job-seeker-vision` conda env, port 8002, `manage-vision.sh`
|
|
- In public fork: separate container in `single-gpu` / `dual-gpu` profiles only
|
|
- In `remote` / `cpu` profiles: vision falls back to cloud backends
|
|
- Model configurable via env var in container (default: moondream2)
|
|
|
|
### CompanyScraper
|
|
- Currently: `/Library/Development/scrapers/companyScraper.py` (external path)
|
|
- In public fork: bundled directly in the app image at a fixed internal path
|
|
|
|
---
|
|
|
|
## Key Architectural Decisions (from design doc)
|
|
|
|
1. **`UserProfile` class** wraps `config/user.yaml` — imported everywhere personal data is used
|
|
2. **Four Docker Compose profiles:** `remote`, `cpu`, `single-gpu`, `dual-gpu`
|
|
3. **First-run wizard** gates the app until `config/user.yaml` exists (5-step flow)
|
|
4. **No shared git history** with personal repo — fresh `git init` in target dir
|
|
5. **`.env` file** generated by wizard (never hand-edited), gitignored, contains resolved paths
|
|
6. **`config/llm.yaml` base URLs** are derived values auto-generated from `user.yaml` services block
|
|
7. **Claude Code Wrapper + Copilot Wrapper** removed from Services tab entirely
|
|
|
|
---
|
|
|
|
## Files/Paths in Personal Repo to Reference
|
|
|
|
- Entry point: `app/app.py`
|
|
- All pages: `app/pages/`
|
|
- DB helpers: `scripts/db.py` (single source of truth for schema)
|
|
- LLM router: `scripts/llm_router.py`
|
|
- Config: `config/llm.yaml`, `config/search_profiles.yaml`
|
|
- Vision service: `scripts/vision_service/` (FastAPI + environment.yml)
|
|
- Test suite: `tests/`
|
|
|
|
---
|
|
|
|
## Skill to Use
|
|
|
|
When starting the generalization session:
|
|
1. Load `superpowers:executing-plans` skill
|
|
2. Reference `docs/plans/2026-02-24-job-seeker-app-generalize.md` as the plan
|
|
3. Work task-by-task with review checkpoints
|