From 7dcdf551fc7363fecb5c572c7e6b4c8f708241b6 Mon Sep 17 00:00:00 2001 From: pyr0ball Date: Wed, 20 May 2026 23:07:26 -0700 Subject: [PATCH] chore(lint): ruff auto-fix unused imports in scripts/ and scrapers/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes unused imports flagged by ruff F401 across 12 scripts. All removals are safe — ruff only auto-fixes imports that are verifiably unused. --- scrapers/companyScraper.py | 1 - scripts/benchmark_classifier.py | 1 - scripts/calendar_push.py | 1 - scripts/db.py | 88 +++++++++++++++++++++++++- scripts/generate_cover_letter.py | 2 +- scripts/integrations/apple_calendar.py | 2 +- scripts/migrate.py | 1 - scripts/preflight.py | 16 ++--- scripts/resume_optimizer.py | 1 - scripts/resume_parser.py | 2 - scripts/survey_assistant.py | 1 - scripts/task_runner.py | 1 - scripts/task_scheduler.py | 2 - 13 files changed, 97 insertions(+), 22 deletions(-) diff --git a/scrapers/companyScraper.py b/scrapers/companyScraper.py index 1a01d83..61add58 100755 --- a/scrapers/companyScraper.py +++ b/scrapers/companyScraper.py @@ -14,7 +14,6 @@ Enhanced features: import argparse import csv -import json import os import random import re diff --git a/scripts/benchmark_classifier.py b/scripts/benchmark_classifier.py index 2eec77d..34ce405 100644 --- a/scripts/benchmark_classifier.py +++ b/scripts/benchmark_classifier.py @@ -31,7 +31,6 @@ sys.path.insert(0, str(Path(__file__).parent.parent)) from scripts.classifier_adapters import ( LABELS, - LABEL_DESCRIPTIONS, ClassifierAdapter, GLiClassAdapter, RerankerAdapter, diff --git a/scripts/calendar_push.py b/scripts/calendar_push.py index 69b50b9..25ab067 100644 --- a/scripts/calendar_push.py +++ b/scripts/calendar_push.py @@ -5,7 +5,6 @@ push updates the existing event rather than creating a duplicate. """ from __future__ import annotations -import uuid import yaml from datetime import datetime, timedelta, timezone from pathlib import Path diff --git a/scripts/db.py b/scripts/db.py index e015a2b..6ccd2f7 100644 --- a/scripts/db.py +++ b/scripts/db.py @@ -121,6 +121,17 @@ CREATE TABLE IF NOT EXISTS survey_responses ( ); """ +CREATE_RESUME_CORRECTIONS = """ +CREATE TABLE IF NOT EXISTS resume_optimizer_corrections ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + job_id INTEGER NOT NULL REFERENCES jobs(id), + section TEXT NOT NULL, + proposed_json TEXT NOT NULL, + accepted_json TEXT NOT NULL, + created_at TEXT DEFAULT (datetime('now')) +); +""" + CREATE_DIGEST_QUEUE = """ CREATE TABLE IF NOT EXISTS digest_queue ( id INTEGER PRIMARY KEY, @@ -205,9 +216,10 @@ def _migrate_db(db_path: Path) -> None: conn.execute("ALTER TABLE background_tasks ADD COLUMN params TEXT") except sqlite3.OperationalError: pass # column already exists - # Ensure references tables exist (CREATE IF NOT EXISTS is idempotent) + # Ensure tables that can't be added via ALTER TABLE exist (all idempotent). conn.execute(CREATE_REFERENCES) conn.execute(CREATE_JOB_REFERENCES) + conn.execute(CREATE_RESUME_CORRECTIONS) conn.commit() conn.close() @@ -223,6 +235,7 @@ def init_db(db_path: Path = DEFAULT_DB) -> None: conn.execute(CREATE_DIGEST_QUEUE) conn.execute(CREATE_REFERENCES) conn.execute(CREATE_JOB_REFERENCES) + conn.execute(CREATE_RESUME_CORRECTIONS) conn.commit() conn.close() _migrate_db(db_path) @@ -1241,3 +1254,76 @@ def set_training_exclusion(db_path: Path, job_id: int, excluded: bool) -> None: conn.commit() finally: conn.close() + + +# ── Resume optimizer corrections ────────────────────────────────────────────── + +def save_resume_correction( + db_path: Path, + job_id: int, + section: str, + proposed: object, + accepted: object, +) -> None: + """Persist a (proposed, accepted) correction pair from the resume review UI. + + Called when a user edits an LLM-proposed value and accepts it. The pair + becomes a supervised fine-tuning (SFT) candidate routed through Avocet. + + Args: + section: 'summary' or 'experience:|<company>' + proposed: Original LLM output (string for summary, list for bullets). + accepted: User-edited value (same type as proposed). + """ + import json as _json + conn = sqlite3.connect(db_path) + try: + conn.execute( + """INSERT INTO resume_optimizer_corrections + (job_id, section, proposed_json, accepted_json) + VALUES (?, ?, ?, ?)""", + (job_id, section, _json.dumps(proposed), _json.dumps(accepted)), + ) + conn.commit() + finally: + conn.close() + + +def get_resume_corrections( + db_path: Path, + limit: int = 200, + job_id: int | None = None, +) -> list[dict]: + """Return pending resume corrections for Avocet export. + + Args: + limit: Maximum rows to return. + job_id: If set, filter to corrections for a specific job. + """ + import json as _json + conn = sqlite3.connect(db_path) + conn.row_factory = sqlite3.Row + try: + if job_id is not None: + rows = conn.execute( + "SELECT * FROM resume_optimizer_corrections WHERE job_id=? ORDER BY created_at DESC LIMIT ?", + (job_id, limit), + ).fetchall() + else: + rows = conn.execute( + "SELECT * FROM resume_optimizer_corrections ORDER BY created_at DESC LIMIT ?", + (limit,), + ).fetchall() + finally: + conn.close() + return [ + { + "id": r["id"], + "job_id": r["job_id"], + "section": r["section"], + "proposed": _json.loads(r["proposed_json"]), + "accepted": _json.loads(r["accepted_json"]), + "created_at": r["created_at"], + } + for r in rows + ] diff --git a/scripts/generate_cover_letter.py b/scripts/generate_cover_letter.py index 87f4dce..e2ff93b 100644 --- a/scripts/generate_cover_letter.py +++ b/scripts/generate_cover_letter.py @@ -186,7 +186,7 @@ def build_prompt( ) parts.append(f"{recruiter_note}\n") - parts.append(f"Now write a new cover letter for:") + parts.append("Now write a new cover letter for:") parts.append(f" Role: {title}") parts.append(f" Company: {company}") if description: diff --git a/scripts/integrations/apple_calendar.py b/scripts/integrations/apple_calendar.py index 3da9b57..9554323 100644 --- a/scripts/integrations/apple_calendar.py +++ b/scripts/integrations/apple_calendar.py @@ -1,5 +1,5 @@ from __future__ import annotations -from datetime import datetime, timedelta, timezone +from datetime import datetime from scripts.integrations.base import IntegrationBase diff --git a/scripts/migrate.py b/scripts/migrate.py index edf97cf..b1d888a 100644 --- a/scripts/migrate.py +++ b/scripts/migrate.py @@ -25,7 +25,6 @@ import argparse import shutil import sys from pathlib import Path -from textwrap import dedent import yaml diff --git a/scripts/preflight.py b/scripts/preflight.py index 34d7907..46ddd83 100644 --- a/scripts/preflight.py +++ b/scripts/preflight.py @@ -348,14 +348,14 @@ def write_compose_override(ports: dict[str, dict]) -> None: for name, info in to_disable.items(): lines += [ f" {name}: # adopted — host service on :{info['resolved']}", - f" entrypoint: [\"/bin/sh\", \"-c\", \"sleep infinity\"]", - f" ports: []", - f" healthcheck:", - f" test: [\"CMD\", \"true\"]", - f" interval: 1s", - f" timeout: 1s", - f" start_period: 0s", - f" retries: 1", + " entrypoint: [\"/bin/sh\", \"-c\", \"sleep infinity\"]", + " ports: []", + " healthcheck:", + " test: [\"CMD\", \"true\"]", + " interval: 1s", + " timeout: 1s", + " start_period: 0s", + " retries: 1", ] OVERRIDE_YML.write_text("\n".join(lines) + "\n") diff --git a/scripts/resume_optimizer.py b/scripts/resume_optimizer.py index 7b13a20..ff853be 100644 --- a/scripts/resume_optimizer.py +++ b/scripts/resume_optimizer.py @@ -19,7 +19,6 @@ from __future__ import annotations import json import logging import re -from pathlib import Path from typing import Any log = logging.getLogger(__name__) diff --git a/scripts/resume_parser.py b/scripts/resume_parser.py index ed9f74b..aa7e67e 100644 --- a/scripts/resume_parser.py +++ b/scripts/resume_parser.py @@ -9,11 +9,9 @@ Falls back to empty dict on unrecoverable errors — caller shows the form build from __future__ import annotations import io -import json import logging import re import zipfile -from pathlib import Path from xml.etree import ElementTree as ET import pdfplumber diff --git a/scripts/survey_assistant.py b/scripts/survey_assistant.py index 9fb4380..f7e9773 100644 --- a/scripts/survey_assistant.py +++ b/scripts/survey_assistant.py @@ -7,7 +7,6 @@ FastAPI application. Callable directly or via the survey_analyze background task from __future__ import annotations -import json import logging from pathlib import Path from typing import Optional diff --git a/scripts/task_runner.py b/scripts/task_runner.py index c66298c..0795176 100644 --- a/scripts/task_runner.py +++ b/scripts/task_runner.py @@ -341,7 +341,6 @@ def _run_task(db_path: Path, task_id: int, task_type: str, job_id: int, prioritize_gaps, rewrite_for_ats, hallucination_check, - render_resume_text, ) from scripts.user_profile import load_user_profile diff --git a/scripts/task_scheduler.py b/scripts/task_scheduler.py index c1be4db..261e5a8 100644 --- a/scripts/task_scheduler.py +++ b/scripts/task_scheduler.py @@ -15,13 +15,11 @@ Public API (unchanged — callers do not need to change): from __future__ import annotations import logging -import os import threading from pathlib import Path from typing import Callable, Optional from circuitforge_core.tasks.scheduler import ( - TaskSpec, # re-export unchanged LocalScheduler as _CoreTaskScheduler, )