Commit graph

192 commits

Author SHA1 Message Date
0ba27c3939 docs: mkdocs wiki — installation, user guide, developer guide, reference
Adds a full MkDocs documentation site under docs/ with Material theme.

Getting Started: installation walkthrough, 7-step first-run wizard guide,
Docker Compose profile reference with GPU memory guidance and preflight.py
description.

User Guide: job discovery (search profiles, custom boards, enrichment),
job review (sorting, match scores, batch actions), apply workspace (cover
letter gen, PDF export, mark applied), interviews (kanban stages, company
research auto-trigger, survey assistant), email sync (IMAP, Gmail App
Password, classification labels, stage auto-updates), integrations (all 13
drivers with tier requirements), settings (every tab documented).

Developer Guide: contributing (dev env setup, code style, branch naming, PR
checklist), architecture (ASCII layer diagram, design decisions), adding
scrapers (full scrape() interface, registration, search profile config,
test patterns), adding integrations (IntegrationBase full interface, auto-
discovery, tier gating, test patterns), testing (patterns, fixtures, what
not to test).

Reference: tier system (full FEATURES table, can_use/tier_label API, dev
override, adding gates), LLM router (backend types, complete() signature,
fallback chains, vision routing, __auto__ resolution, adding backends),
config files (every file with field-level docs and gitignore status).

Also adds CONTRIBUTING.md at repo root pointing to the docs site.
2026-02-25 12:05:49 -08:00
ad7a56dca5 docs: backlog — Ultra tier managed applications concept 2026-02-25 11:40:55 -08:00
2163f428dc feat: Integrations tab in Settings — connect/test/disconnect all 12 integration drivers 2026-02-25 11:30:44 -08:00
bbb3eda747 refactor: move HF token to Developer tab — hidden from standard user UI 2026-02-25 11:04:13 -08:00
a0164814e9 feat: expanded first-run wizard — complete implementation
13-task implementation covering:
- UserProfile wizard fields (wizard_complete, wizard_step, tier, dev_tier_override,
  dismissed_banners, effective_tier) + params column in background_tasks
- Tier system: FEATURES gate, can_use(), tier_label() (app/wizard/tiers.py)
- Six pure validate() step modules (hardware, tier, identity, resume, inference, search)
- Resume parser: PDF (pdfplumber) + DOCX (python-docx) extraction + LLM structuring
- Integration base class + auto-discovery registry (scripts/integrations/)
- 13 integration drivers (Notion, Google Sheets, Airtable, Google Drive, Dropbox,
  OneDrive, MEGA, Nextcloud, Google Calendar, Apple Calendar, Slack, Discord,
  Home Assistant) + config/integrations/*.yaml.example files
- wizard_generate task type with 8 LLM generation sections + iterative refinement
  (previous_result + feedback support)
- step_integrations module: validate(), get_available(), is_connected()
- Wizard orchestrator rewrite (0_Setup.py): 7 steps, crash recovery, LLM polling
- app.py gate: checks wizard_complete flag in addition to file existence
- Home page: 13 dismissible contextual setup banners (wizard_complete-gated)
- Settings: Developer tab — tier override selectbox + wizard reset button

219 tests passing.
2026-02-25 10:54:24 -08:00
ea4f6a9160 feat: Developer tab in Settings — tier override + wizard reset button 2026-02-25 10:50:14 -08:00
928825b9b9 feat: dismissible setup banners on Home page (13 contextual prompts) 2026-02-25 09:53:34 -08:00
2a09b40a1d feat: app.py checks wizard_complete flag to gate main app 2026-02-25 09:43:53 -08:00
daf8e4a382 feat: wizard orchestrator — 7 steps, LLM generation polling, crash recovery
Replaces the old 5-step wizard with a 7-step orchestrator that uses the
step modules built in Tasks 2-8. Steps 1-6 are mandatory (hardware, tier,
identity, resume, inference, search); step 7 (integrations) is optional.
Each Next click validates, writes wizard_step to user.yaml for crash recovery,
and resumes at the correct step on page reload. LLM generation buttons
submit wizard_generate tasks and poll via @st.fragment(run_every=3). Finish
sets wizard_complete=True, removes wizard_step, and calls apply_service_urls.

Adds tests/test_wizard_flow.py (7 tests) covering validate() chain, yaml
persistence helpers, and wizard state inference.
2026-02-25 09:10:51 -08:00
6b093522bf feat: step_integrations module with validate() + tier-filtered available list 2026-02-25 08:35:16 -08:00
eb0e7883b8 docs: backlog — cover letter iterative refinement feedback loop 2026-02-25 08:30:24 -08:00
9fdb95e17f feat: wizard_generate — feedback + previous_result support for iterative refinement 2026-02-25 08:29:56 -08:00
6156aebd3a feat: wizard_generate task type — 8 LLM generation sections 2026-02-25 08:25:17 -08:00
445917cbd6 docs: backlog — Podman support + FastAPI migration path 2026-02-25 08:22:24 -08:00
2dd331cd59 feat: 13 integration implementations + config examples
Add all 13 integration modules (Notion, Google Drive, Google Sheets,
Airtable, Dropbox, OneDrive, MEGA, Nextcloud, Google Calendar, Apple
Calendar/CalDAV, Slack, Discord, Home Assistant) with fields(), connect(),
and test() implementations. Add config/integrations/*.yaml.example files
and gitignore rules for live config files. Add 5 new registry/schema
tests bringing total to 193 passing.
2026-02-25 08:18:45 -08:00
f67eaab7de feat: integration base class + auto-discovery registry 2026-02-25 08:13:14 -08:00
c7e4749fc6 feat: resume parser — PDF/DOCX extraction + LLM structuring 2026-02-25 08:04:48 -08:00
2a7f88a771 feat: wizard step validate() functions — all six mandatory steps 2026-02-25 08:00:18 -08:00
df58213f4d feat: tier system with FEATURES gate + can_use() + tier_label() 2026-02-25 07:55:47 -08:00
e2b5b26689 feat: wizard fields in UserProfile + params column in background_tasks
- Add tier, dev_tier_override, wizard_complete, wizard_step, dismissed_banners
  fields to UserProfile with defaults and effective_tier property
- Add params TEXT column to background_tasks table (CREATE + migration)
- Update insert_task() to accept params with params-aware dedup logic
- Update submit_task() and _run_task() to thread params through
- Add test_wizard_defaults, test_effective_tier_override,
  test_effective_tier_no_override, and test_insert_task_with_params
2026-02-25 07:27:14 -08:00
873d035de6 docs: expanded wizard implementation plan — 13 tasks, TDD throughout 2026-02-25 06:29:23 -08:00
ec2f35380a docs: expanded first-run wizard design
Architecture: wizard module system, mandatory 6-step flow, optional
home banners, tier gating (free/paid/premium + dev_tier_override),
resume upload/parse/builder, LLM generation via background tasks,
integrations registry pattern with 14 v1 services.
2026-02-24 21:30:05 -08:00
3d3f81c252 chore: add backlog.md + gitignore config/.backup-* dirs 2026-02-24 20:54:12 -08:00
236db81ed3 feat: startup preflight — port collision avoidance + resource checks
scripts/preflight.py (stdlib-only, no psutil):
- Port probing: owned services auto-reassign to next free port; external
  services (Ollama) show ✓ reachable / ⚠ not responding
- System resources: CPU cores, RAM (total + available), GPU VRAM via
  nvidia-smi; works on Linux + macOS
- Profile recommendation: remote / cpu / single-gpu / dual-gpu
- vLLM KV cache offload: calculates CPU_OFFLOAD_GB when VRAM < 10 GB
  free and RAM headroom > 4 GB (uses up to 25% of available headroom)
- Writes resolved values to .env for docker compose; single-service mode
  (--service streamlit) for scripted port queries
- Exit 0 unless an owned port genuinely can't be resolved

scripts/manage-ui.sh:
- Calls preflight.py --service streamlit before bind; falls back to
  pure-bash port scan if Python/yaml unavailable

compose.yml:
- vllm command: adds --cpu-offload-gb ${CPU_OFFLOAD_GB:-0}

Makefile:
- start / restart depend on preflight target
- PYTHON variable for env portability
- test target uses PYTHON variable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 20:36:16 -08:00
3eeccd7a33 feat: migration tool + portable startup scripts
scripts/migrate.py:
- dry-run by default; --apply writes files; --copy-db migrates staging.db
- generates config/user.yaml from source repo's resume + cover letter scripts
- copies gitignored configs (notion, email, adzuna, craigslist, search profiles,
  resume keywords, blocklist, aihawk resume)
- merges fine-tuned model name from source llm.yaml into dest llm.yaml

scripts/manage-ui.sh:
- STREAMLIT_BIN no longer hardcoded; auto-resolves via conda env or PATH;
  override with STREAMLIT_BIN env var

scripts/manage-vllm.sh:
- VLLM_BIN and MODEL_DIR now read from env vars with portable defaults

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 20:25:54 -08:00
84eb647348 feat: LGBTQIA+ focus + Phase 2/3 audit fixes
LGBTQIA+ inclusion section in research briefs:
- user_profile.py: add candidate_lgbtq_focus bool accessor
- user.yaml.example: add candidate_lgbtq_focus flag (default false)
- company_research.py: gate new LGBTQIA+ section behind flag; section
  count now dynamic (7 base + 1 per opt-in section, max 9)
- 2_Settings.py: add "Research Brief Preferences" expander with
  checkboxes for both accessibility and LGBTQIA+ focus flags;
  mission_preferences now round-trips through save (no silent drop)

Phase 2 fixes:
- manage-vllm.sh: MODEL_DIR and VLLM_BIN now read from env vars
  (VLLM_MODELS_DIR, VLLM_BIN) with portable defaults
- search_profiles.yaml: replace personal CS/TAM/Bay Area profiles
  with a documented generic starter profile

Phase 3 fix:
- llm.yaml: rename alex-cover-writer:latest → llama3.2:3b with
  inline comment for users to substitute their fine-tuned model;
  fix model-exclusion comment

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 20:02:03 -08:00
40bd297b14 fix: remove hardcoded personal values — Phase 1 audit findings
- 3_Resume_Editor.py: replace "Alex's" in docstring and caption
- user_profile.py: expose mission_preferences and candidate_accessibility_focus
- user.yaml.example: add mission_preferences section + candidate_accessibility_focus flag
- generate_cover_letter.py: build _MISSION_NOTES from user profile instead of
  hardcoded personal passion notes; falls back to generic defaults when not set
- company_research.py: gate "Inclusion & Accessibility" section behind
  candidate_accessibility_focus flag; section count adjusts (7 or 8) accordingly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 19:57:03 -08:00
cbaa7e019e feat: add cross-platform dependency installer and Makefile for Linux/macOS
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 19:47:06 -08:00
48c957da64 feat: complete generalization — smoke tests, README, all personal refs extracted
- UserProfile class drives all personal data
- First-run wizard gates app until user.yaml exists
- Docker Compose stack: remote/cpu/single-gpu/dual-gpu profiles
- Vision service containerized (single-gpu/dual-gpu)
- All Alex/Library references removed from app and scripts
- Circuit Forge LLC / Peregrine branding throughout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 19:41:09 -08:00
9931f811ac feat: add vision service to compose stack and fine-tune wizard tab to Settings
- Add moondream2 vision service to compose.yml (single-gpu + dual-gpu profiles)
- Create scripts/vision_service/Dockerfile for the vision container
- Add VISION_PORT, VISION_MODEL, VISION_REVISION vars to .env.example
- Add Vision Service entry to SERVICES list in Settings (hidden unless gpu profile active)
- Add Fine-Tune Wizard tab (Task 10) to Settings with 3-step upload→preview→train flow
- Tab is always rendered; shows info message when non-GPU profile is active

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 19:37:55 -08:00
678460def2 feat: services tab uses docker compose commands and SSL-aware health checks
Replace hardcoded systemd/shell-script service commands with docker compose
profile-aware commands. Add inference_profile-based filtering (hidden flag
removes Ollama on remote profile, vLLM unless dual-gpu). Replace TCP socket
health check with HTTP-based _port_open() that accepts host/ssl/verify params
for remote/TLS-terminated service support.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 19:34:44 -08:00
0290c6fa17 feat: add Docker Compose stack with remote/cpu/single-gpu/dual-gpu profiles
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 19:31:57 -08:00
381aabe358 fix: persist API keys to .env and write notion.yaml with field_map defaults in wizard
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 19:24:51 -08:00
05fe5999ae feat: first-run setup wizard gates app until user.yaml is created
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 19:20:35 -08:00
5b13b3126e feat: add My Profile tab to Settings with full user.yaml editing and URL auto-generation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 19:16:31 -08:00
3855a2c7a1 test: add ollama_research URL assertion to llm config generation test 2026-02-24 19:14:33 -08:00
e575c66d53 feat: auto-generate llm.yaml base_url values from user profile services config
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 19:10:54 -08:00
6d763d4a1e feat: extract hard-coded personal references from all app pages via UserProfile
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 19:00:47 -08:00
2b5ee80ca8 fix: thread searxng URL through research functions via _SEARXNG_URL constant
- Add module-level _SEARXNG_URL derived from UserProfile.searxng_url (or default localhost:8888)
- Update all _searxng_running() call sites to pass _SEARXNG_URL explicitly
- Replace hardcoded "http://localhost:8888/" in _scrape_company() with _SEARXNG_URL + "/"
- Replace hardcoded "http://localhost:8888/search" in _run_search_query() with f"{_SEARXNG_URL}/search"
- Guard _profile.name.split() against empty string in finetune_local.py OLLAMA_NAME

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 18:52:10 -08:00
bc94a92681 feat: extract hard-coded personal references from all scripts via UserProfile
Replace hard-coded paths (/Library/Documents/JobSearch), names (Alex Rivera),
NDA sets (_NDA_COMPANIES), and the scraper path with UserProfile-driven lookups.
Update tests to be profile-agnostic (no user.yaml in peregrine config dir).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 18:45:39 -08:00
83ce120666 feat: add UserProfile class with service URL generation and NDA helpers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 18:29:45 -08:00
f11a38eb0b chore: seed Peregrine from personal job-seeker (pre-generalization)
App: Peregrine
Company: Circuit Forge LLC
Source: github.com/pyr0ball/job-seeker (personal fork, not linked)
2026-02-24 18:25:39 -08:00