Skip to content

Work Wingman

Local-first desktop Career Concierge for job applications. It pulls your saved jobs from LinkedIn, tailors a resume + cover letter per job in your own voice, fills applications across 15 ATS platforms — auto-apply on 6 (Workday, Greenhouse, iCIMS, Lever, Paycor, Oracle) and assisted fill after you sign in on 9 more (UKG, ADP, Paycom, SuccessFactors, Microsoft Careers, Avature, Amazon, Google, Dayforce) — in a watchable embedded browser (pausing to ask you when it isn't sure), builds a per-job study plan, and tracks applications and interviews — with Google Drive/Sheets as backup sync, not hosting. Everything sensitive (KeePass vault, resume files, automation browser) stays on your machine.

Design source: design/AutoApply-Prototype.dc.html (imported from the claude.ai/design project "Automated Job Application Assistant").

Stack

Layer Tech
Shell Electron (spawns the API, hosts the UI + automation BrowserView)
Frontend Angular 22 (standalone components, signals)
Backend ASP.NET Core (net10.0), loopback-only
HTTP clients Flurl
Resilience Polly (retry + backoff on 429/5xx/network)
Automation Microsoft.Playwright (persistent Chromium profile)
Secrets KeePass vault (vault.kdbx) — secrets never cross the HTTP API
Sync Google Forms / Sheets / Calendar REST, Sign in with Apple, LinkedIn OIDC

Repository layout

WorkWingman/
├── WorkWingman.slnx           .NET solution
├── src/
│   ├── WorkWingman.Core/            domain models + service interfaces
│   ├── WorkWingman.Infrastructure/  Flurl clients, Polly pipelines, Playwright
│   │                                scraper/automation, KeePass vault, services
│   └── WorkWingman.Api/             ASP.NET Core controllers (loopback only)
├── tests/WorkWingman.Tests/   xUnit (unit + in-memory API smoke tests)
├── frontend/                  Angular app (10 screens: 9 flow + dependency doctor)
├── electron/                  Electron main + preload
├── design/                    imported claude.ai/design prototype files
└── docs/                      two-track docs — technical/ + plain/ (see docs/README.md)

Documentation

Full docs live in docs/, written in two trackstechnical/ (for engineers) and plain/ (everyday language) — covering architecture, setup, connections & SSO, security, testing, the API, contributing, and a prompt-by-prompt making-of. They double as a learning resource: every tool links to its docs and source. Start at docs/README.md.

Progress at a glance: the delivery board — active sprint, delivered epics, and the commit behind every ticket.

Running it

Prerequisites: .NET 10 SDK, Node 22.12+ (Electron 43's install tooling requires it).

# 1. Backend (terminal 1) — http://127.0.0.1:5211
dotnet run --project src/WorkWingman.Api

# 2. Frontend (terminal 2) — http://localhost:4200
cd frontend; npm start

# 3. Electron shell (terminal 3, optional — wraps 1+2)
cd electron; npm install; npm run dev

On launch the app runs the dependency doctor (Dependencies screen): it checks that Node 22.12+, Playwright's Chromium, KeePassXC, the Claude CLI, and the rest meet each dependency's minimum version, and — only after you tick each item and approve — installs/ repairs them via winget / npm / the in-process Playwright installer, then re-verifies. The install endpoint requires a per-launch token (readable only by processes running as you), so a hostile web page hitting the loopback API cannot trigger installs; in dev the localhost:4200 origin is also trusted so ng serve works.

Tests:

dotnet test          # backend (44 tests)
cd frontend; npm test  # Angular (vitest)

Trust model (non-negotiables baked into the code)

  • Final submit always waits for you. AutomationSettings.AlwaysRequireReviewBeforeSubmit is a computed true — there is no way to turn it off.
  • Judgement calls, not guesses. Below the confidence threshold (default 90%) the run pauses with ranked options; your pick persists as a rule and is never asked again.
  • Secrets stay in the vault. The HTTP API exposes vault metadata only; the automation engine resolves passwords in-process, just-in-time.
  • Local first. JSON store under ~/Wingman/data is the source of truth; Drive/Sheets mirrors it for backup.