Job Apps Automation v2
PyQt6 desktop app for tracking job applications with built-in AI transformations
Tech Stack
Overview
Smart Spreadsheet turns a CSV into an intelligent job search command center. Paste a job URL and it auto-scrapes the description with a stealth Playwright browser. Add a LinkedIn profile and it enriches the hiring manager's email via Wiza. One click generates tailored follow-up emails, LinkedIn intro messages, and custom resumes — all with auto-save and transformation history.
The application features a pluggable transformation architecture: each transformation is a self-contained module that defines its inputs, outputs, and processing logic. A ThreadPool executor runs up to 3 transformations concurrently with row-level mutex locking to prevent conflicts. Templates use a custom {{placeholder}} syntax that pulls from row data, user info, and resume files.
Screenshots

Main spreadsheet — Jobs with AI-powered transformations
Key Features
9 Built-in Transformations
Web scraper, Wiza enrichment, LinkedIn intro generator, follow-up email writer, resume builder, JD analysis, custom LLM prompts, and more.
Multi-Provider AI
Supports OpenAI, Anthropic, Ollama, and DeepSeek. Switch models per transformation with retry logic for constrained outputs.
Programmatic Resume Generation
Uses FAISS vector store and LangChain to semantically match your experience to job descriptions, then generates tailored resume sections as PDF.
Stealth Web Scraping
Playwright with anti-detection plugins extracts job descriptions from company websites, bypassing bot protection.
Auto-Save + Metadata
Every edit persists immediately. Transformation history stored as JSON sidecar files alongside your data.
Architecture
The application follows a clean separation of concerns: UI components (PyQt6 widgets and delegates), services (file I/O, email, settings, crypto), and transformations (pluggable AI/scraping modules).
The transformation system uses dynamic discovery — new transformations are automatically found by scanning the transformations package. Each inherits from BaseTransformation and defines required inputs, outputs, and a transform() method. The TransformationManager orchestrates execution using QThreadPool with configurable concurrency and row-level QMutex locking.