The Problem

Job‑searchers spend hours maintaining spreadsheets, copying CVs, and manually scoring offers. The lack of a single source of truth makes it easy to miss deadlines, duplicate applications, or overlook high‑value opportunities.

What This Does

career‑ops stitches Claude Code agents, Playwright‑driven scraping, and a terminal UI into a unified pipeline. The Go entry point dashboard/main.go launches a TUI that lists applications, filters, and sorts them. Core data handling lives in dashboard/internal/data/career.go (parsing JSON job data, loading batch inputs, normalising company names). UI rendering and interaction are in dashboard/internal/ui/screens/*.go, with the most complex screen in pipeline.go (713 lines, 30 functions). PDF generation and theme handling are in the templates/ and dashboard/internal/theme/ packages.

How It Is Wired

Execution starts at func main() in dashboard/main.go (line 118). main calls Init, Update, and View, which together reach 15‑30 functions each.

  • Update → LoadReportSummary → cleanTableCell (filesystem read via os.ReadFile).
  • View → renderHeader → Width (called from nine places, the widest internal hub).

The data path begins with ParseApplications in career.go, which reads the applications file, then feeds structures to the UI screens. UI screens call helper functions such as NormalizeStatus (used by eight callers) and applyFilterAndSort (used by three callers). The most‑impactful functions—Width, NormalizeStatus, CurrentApp—are invoked from multiple locations, so changes there propagate broadly. No circular imports were detected; the import graph consists of ten isolated internal modules.

File responsibilities (ranked by call‑graph reach):

FileCore dutiesReach
pipeline.goDefines NewPipelineModel, UI layout, resize, width/height calculations30 functions, 8 types
career.goParses applications, loads batch URLs, normalises company data, reads files13 functions, 3 types
viewer.goViewer model, init, resize, update, body height (reads files)10 functions, 2 types
theme.go / catppuccin.goTheme construction (NewTheme)2 functions
main.goTUI bootstrap (Init, Update, View)4 functions

All external effects are file reads (os.ReadFile) performed in ParseApplications and LoadReportSummary. No network calls are visible in the static analysis; the Playwright agents are invoked from the Claude Code side, not from the Go code.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/career-ops
cd career-ops

# Install Node dependencies (Playwright for PDF generation)
npm install
npx playwright install chromium

# Validate the environment
npm run doctor          # defined in package.json, checks Go, Playwright, etc.

# Configure your profile (required fields in config/profile.yml)
cp config/profile.example.yml config/profile.yml
# Edit config/profile.yml with your CV, preferences, API keys, etc.

# Run the terminal UI
go run ./dashboard/main.go

The UI lets you press a to add a URL, e to evaluate, p to generate a PDF, and arrow keys to navigate. Batch mode can be driven via the .opencode/commands/ scripts (e.g., career-ops-batch) which ultimately invoke the same Go functions.

Real‑World Use

A hiring engineer can point the UI at a list of Greenhouse URLs, let Claude evaluate each against a stored CV, and export a tailored PDF for any offer scoring above 4.0/5. The generated PDF and the normalized status are then committed to the local reports/ folder, providing an audit trail that can be version‑controlled alongside source code.

Code Health & Issues

  • High – No test suite – 17 source files, 0 test files. Add unit tests for each public entry point and gate them with CI.
  • High – Missing lockfile – package.json present without package-lock.json/yarn.lock. Run npm install and commit the generated lockfile.
  • High – No CI workflow – No GitHub Actions or other CI config. Add a workflow that runs go build and npm test.
  • Medium – Dependabot disabled – No .github/dependabot.yml. Add one covering Go, Node, and GitHub Actions.
  • Medium – Large binary in repo – docs/demo.gif (8.3 MiB). Move to Git LFS or external storage.
  • Medium – Deep nesting – career.go and viewer.go have indentation depth 6, making control flow hard to follow. Refactor with early returns or helper functions.
  • Medium – Duplicated code – Repeated 6‑line blocks across several UI screens and JS helpers. Extract shared helpers.
  • Medium – Oversized file – pipeline.go contains 713 lines; split by responsibility (e.g., layout vs. data handling).
  • Medium – High branching density – 171 branch points across 487 lines in several files; consider strategy tables or polymorphic dispatch.

The Bottom Line

career‑ops delivers a functional, AI‑augmented job‑search workflow with a usable TUI and PDF output, but the codebase suffers from maintainability issues (large files, duplicated logic) and a weak production pipeline (no tests, CI, or lockfile). It is suitable for teams comfortable extending Go/Node code and willing to invest in test and CI scaffolding.