npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

harrier-ai

v1.0.1

Published

Autonomous job-application agent: discovers, scores, tailors resumes for, and submits applications to Greenhouse/Jobot/Ashby/Workday boards, with a live dashboard and Gmail-based confirmation tracking.

Downloads

208

Readme

Harrier

npm install -g harrier-ai

An autonomous job-application pipeline. It discovers roles from configured job boards, scores them against your profile, tailors a résumé per role, fills and submits the application form with a real (stealthed) Chrome browser, and tracks the outcome by reading your Gmail for confirmation / rejection / interview emails. A live web dashboard shows everything in real time.

Status: v1.0.0, published. You run it on your own machine with your own Anthropic API key — nothing is hosted, and no application data leaves your computer. The free tier submits 3 applications; a licence removes the cap.


At a glance (auto-updated September 8, 2026) — 35 discovery sources · 4 auto-submit platforms (Greenhouse, Jobot, Ashby, Workday) · 602 company playbooks · 819 engine modules · 4204 automated tests. See EXECUTIVE_SUMMARY.html for the full overview.

🚀 Quickstart — install Harrier (this is the one you want)

Start here if you bought Harrier or installed it from npm. Three commands, then it runs. Everything self-creates — no repository to clone, no database migration, no build step.

Prereqs: Node 22+, Google Chrome, and an Anthropic API key from https://console.anthropic.com (add ~$5–10 of credit and set a monthly usage limit in the console — that's your hard cap; Harrier gates spend in-app too, and every AI feature starts off ($0) until you switch it on).

npm install -g harrier-ai
harrier init      # asks for your Anthropic API key, then builds your profile — it never asks for a license
harrier start     # self-creates the DB, builds the dashboard, opens http://localhost:3001

Then open http://localhost:3001 and finish your Profile (the gear, top-right): About you / Résumé / Job search / Take-home — no YAML editing needed. Do Job search first (target titles, minimum salary, home city, remote preference); it overrides the starter defaults so you get roles relevant to you.

  • Every command is harrier <cmd> — harrier status, harrier stop, harrier doctor (a read-only preflight that tells you what's wrong), harrier sync, harrier support.
  • Optional inbox tracking: harrier connect-email (Gmail App Password / IMAP) so confirmations, interviews, and rejections show up on the dashboard.
  • The free tier. A packaged install is free for the first 3 submitted applications; after that the drain holds and the dashboard shows an upsell card. Unlock with harrier activate <key> — not harrier init — then harrier stop && harrier start.
  • Something wrong? Run harrier doctor first, then see Something broken? Report it from inside Harrier.

The git clone sections below are not for you. This repository is private, so a clone will fail with a permission error. Everything from the next heading down to Install paths is for collaborators and beta testers who have been granted access to the repo — it is a second, separate way to run Harrier.


🚀 Quickstart — collaborators with repo access (clone + your Claude subscription)

Requires access to the private repository. If you installed from npm, use the section above instead.

The fastest path if you are a collaborator with a Claude subscription (uses the claude CLI, so no license key and no API key). Everything self-creates — no DB migration, no build step.

Prereqs: Node 22+, Google Chrome, and the claude CLI signed into your Claude subscription (npm i -g @anthropic-ai/claude-code, then run claude once to log in).

git clone https://github.com/TylerRussell/job-applier-agent.git harrier && cd harrier
npm run setup     # installs deps + Chrome, seeds config, creates .env + config/profile.yaml
npm start         # self-creates the DB, builds the dashboard, opens http://localhost:3001

(You need to be a repo collaborator and authenticated to GitHub for that clone to succeed.)

Then open http://localhost:3001 and fill your Profile (the gear, top-right): About you / Résumé / Job search / Take-home — no YAML editing needed. That's it.

  • npm run setup detects the claude CLI and leaves .env on the subscription path (no API key).
  • The Schedule tab stays blank until you connect your own Google Calendar (optional).
  • Optional inbox tracking: npx tsx src/harrier.ts connect-email (Gmail App Password / IMAP).
  • Stop: npm stop · Status: npm run status · Foreground (for systemd/launchd): npm run serve.
  • No application cap on a source/clone install — the 3-application free tier only applies to the packaged (npm install -g harrier-ai) build.
  • Don't run harrier init on a clone. Two reasons: there's no harrier command in a clone (the bin entry is only linked by an npm install — from source it's npx tsx src/harrier.ts <cmd>), and init writes HARRIER_DISTRIBUTION=npm + HARRIER_LLM_MODE=anthropic-api into .env, which flips your clone onto the metered API-key path and turns on the 3-application free-tier cap.

🐳 Run with Docker — collaborators (optional)

Prefer a container? Harrier ships a Dockerfile + docker-compose.yml. This is purely optional — the npm path above is unchanged — but if you'd rather not install Node/Chrome on your host, it's one command. The container runs the same headed stealth browser (inside a virtual display), and your config/data live on the host via bind-mounts, so nothing personal is baked into the image.

git clone https://github.com/TylerRussell/job-applier-agent.git harrier && cd harrier
docker compose up            # builds the image, then serves http://localhost:3001

Power the AI either way (same flexibility as the non-Docker paths):

  • Claude subscription (free): in docker-compose.yml, uncomment the ~/.claude volume, then docker compose up. Uses your existing claude CLI login — no API key.
  • API key: create a .env with HARRIER_LLM_MODE=anthropic-api and ANTHROPIC_API_KEY=sk-… (see the beta-tester section below), then docker compose up.

Everything else works the same: open http://localhost:3001, fill your Profile, and go. Stop with docker compose down. (Requires Docker Desktop / Engine; first build pulls ~1–2 GB and takes a few minutes.)

The Docker path is aimed at dev/beta users running from a repo clone (the npm package ships no Docker or test files). From a clone, prove the container path end-to-end with npm run smoke:docker — it builds the image and boots a throwaway, credential-less container on empty mounts, asserting the dashboard serves.


🚀 Quick start — beta testers with repo access (clone + your own Anthropic API key)

New here? Start with GETTING-STARTED.md — a plain-language, 20-minute walkthrough (including exactly how to get your Claude API key and put a $5 spending cap on it). The condensed version is below.

Also a clone path — it needs repo access, same as the section above; the npm install at the top of this file is the one that doesn't. You run Harrier on your own machine with your own Anthropic API key. Your profile, résumés, and applications live only in your local DB. ~10 minutes.

One thing a beta clone does that the packaged build cannot: beta diagnostics. A clone can send detailed usage diagnostics (pipeline events, logs, state snapshots including config/profile.yaml) to the maintainer, so a bug is diagnosable without a week of email. It captures nothing until you accept the dashboard's consent gate, a permanent header chip shows while it is on, and HARRIER_TELEMETRY=off or touch state/TELEMETRY_OFF stops it for good. Full field list: docs/beta-setup.md → Data sharing during the beta. Released/packaged builds cannot send diagnostics at all.

Before you start: Node 22+, git, and an Anthropic API key from https://console.anthropic.com (add ~$5–10 of credit and set a monthly usage limit in the console — that's your hard cap; Harrier also gates spend in-app: every AI feature starts off ($0) until you turn it on, plus a daily-spend cap, a daily application cap, and a lifetime budget that all auto-pause when reached). Harrier never bills you; the Anthropic API does, per token.

Estimated AI cost per application (the presets in src/lib/ai-usecases.ts, costed by totalCostPerApplication()) — Free $0.00/app · Lean ≈$0.06/app (≈$6 per 100) · Standard ≈$0.10/app (≈$10 per 100) · Max quality ≈$0.52/app (≈$52 per 100). The AI models chip on the dashboard shows the live estimate for your own picks.

# 1) Clone + install (also installs the dashboard + seeds starter config)
git clone https://github.com/TylerRussell/job-applier-agent.git harrier
cd harrier
./setup.sh        # or: npm run setup — installs deps + Chrome and creates .env

2) Your résumé — you don't need one to start. Open the dashboard's Résumé tab and fill in your experience, skills, and education; Harrier builds an ATS-safe résumé from it and tailors a fresh one per job. Edit it anytime and future résumés pick up the changes. (Prefer your own? Drop a real résumé — .pdf / .docx / .md — into the reference/ folder instead; Harrier uses it as the source of truth.)

3) Your API key — setup.sh already created a .env in the repo root with the two lines you need; paste your key after the =. .env starts with a dot, so Finder hides it — open it from the terminal:

open -e .env      # macOS TextEdit  (or: code .env · nano .env · $EDITOR .env)
# the two lines that must end up in .env
ANTHROPIC_API_KEY=sk-ant-...your key...
HARRIER_LLM_MODE=anthropic-api
# 4) Start — dashboard opens at http://localhost:3001
npm start

5) Set up your profile via the dashboard's Profile button (the gear, top-right) — no file editing. Its sub-nav is About you / Résumé / Job search / Take-home:

  • About you — name, current title, years of experience, contact, location, LinkedIn/GitHub.
  • Job search — target titles, work eligibility, minimum salary, home city, remote preference, interview style, résumé voice, AI spend budget, email connection. Do this first — it overrides the starter defaults so you get roles relevant to you.

(This is a clone, so there is no harrier command and you should not run harrier init — it would mark the install as a packaged build and apply the 3-application free-tier cap. Run source commands as npx tsx src/harrier.ts <cmd>, e.g. npx tsx src/harrier.ts doctor.)

On your first run, Harrier protects you (because it's your pay-per-token key):

  1. Spend-consent gate — shows the estimate ("~$X for N matches") and asks you to set a budget or confirm. Nothing spends on AI until you do.
  2. First-run confidence sample — while discovery, scoring and tailoring run (a few minutes) the dashboard shows a "Setting up your first run" strip with live counts, so you can see it working and know there's nothing to do yet. It then prepares your first 3 applications and holds (submits nothing); click Approve & continue on the dashboard to proceed. If you've connected an inbox it also emails you a preview of exactly what it would submit in your name.
  3. Profile banner — flags anything still missing so you're never half-configured.

Optional — track responses: node --import tsx src/harrier.ts connect-email connects your inbox (read-only) so confirmations / interviews / rejections show on the dashboard (and the preview email above can reach you). Full walkthrough: docs/beta-setup.md.


Install paths: which commands are yours

Two ways to run Harrier, and they use different commands. Pick one and stick to its column.

| | Source / git clone (this repo) | Packaged install (npm install -g harrier-ai) | |---|---|---| | Install | git clone … then ./setup.sh | npm install -g harrier-ai | | First-run setup | .env + the dashboard's Profile page | harrier init (API key + profile, interactive) | | Run a CLI command | npx tsx src/harrier.ts <cmd> | harrier <cmd> | | Start / stop | npm start / npm stop | harrier start / harrier stop | | AI provider | your Claude subscription or your own API key | your own Anthropic API key | | Application cap | none — uncapped | free for the first 3 submitted applications |

License & free tier — Harrier Pro is $49. One-time purchase — license valid for one year. A packaged install (npm install -g harrier-ai) runs free until 3 submitted applications, then the drain holds and the dashboard shows an upsell card. A source/clone install is never capped.

  • harrier … is not a command in a clone. The harrier bin comes from the npm bin field, which only a package install links; a clone has no node_modules/.bin/harrier. Everywhere a doc says harrier <cmd>, the clone equivalent is npx tsx src/harrier.ts <cmd> (doctor, connect-email, status, …).
  • harrier init belongs to the packaged path only. It writes HARRIER_DISTRIBUTION=npm and HARRIER_LLM_MODE=anthropic-api into .env, which is right for a package install and wrong for a clone (it switches the AI to a metered key and switches the free-tier cap on). It never asks for a license.
  • The free tier. The upsell card above links to checkout when a purchase link is configured, and the key arrives by email. Unlock with harrier activate <key> — not harrier init — then restart (npm stop && npm start).

What it does (end to end)

  1. Discover — probe Greenhouse (and Eightfold/Netflix) boards plus the LinkedIn and Indeed job-search aggregators listed in config/sources.yaml for matching titles. Each source emits the same canonical match shape (src/lib/<source>-normalize.ts) into docs/discovery/, deduped across sources. LinkedIn/Indeed are discovery-only — matches still apply through each role's real ATS. Toggle with LINKEDIN_DISCOVERY=0 / INDEED_DISCOVERY=0.
  2. Score — rank each role A+–F on a weighted rubric (level, stack overlap, comp, geo tier, interview style, etc.); deterministic first, Claude only for ambiguous cases. Geo/comp/title hard-filters applied.
  3. Stage — write a per-role folder under output/staged/<co>_<role>/ with a tailored résumé, application.json (pre-filled fields), and the JD.
  4. Submit — launch real Chrome with anti-detection shims, fill standard fields + résumé upload + react-select dropdowns + employment-history blocks (truthful dates from the profile; "current role" checkbox convention), handle emailed security codes, click submit, and poll Gmail to confirm.
  5. Repair — once the staged backlog is drained, deep-retry previously failed roles one company at a time (up to 1 hour/role, Claude + screenshots); companies whose forms can't be cracked go to an icebox for manual review.
  6. Track — scan Gmail for confirmations, rejections, and interview requests; surface cooldowns (e.g. "too many applications in 180 days") and counts on the dashboard. An interview request also pauses further applications to that company — a recruiter sees every application you have open with them, and a new one landing mid-loop is yours to explain. The hold lifts on a rejection or after application_policy.active_interview_window_days (profile.yaml).

The dashboard (where to look)

Once running, the dashboard at http://localhost:3001 has seven content tabs — Dashboard · Pipeline · Roles · Schedule · Prep · Stats · Guide — plus a Profile button (top-right, in the settings gear). On a phone, Roles, Prep and Schedule are hidden (a wide table, a code editor and a calendar grid aren't usable at that width), so the mobile nav shows four.

  • Dashboard — the live pipeline: roles moving through discover → staged → submitting → sent → confirmed, with per-company lanes and system-status. Its filter bar holds the AI models control with a live estimated cost-per-application — the main dial on a metered key. One-click presets (Free / Lean / Standard / Max) or tune each step (Opus/Sonnet/Haiku, or Off for any of them); on a BYO key everything starts Off and a first-run gate makes you open it before continuing. (Vision is unavailable on a BYO API key, shown as such.) Turned Résumé tailoring on after roles were already staged? npx tsx src/retailor-staged.ts re-writes the résumés of your best staged roles at the new tier — dry-run by default (shows targets + estimated cost), --apply --limit N to run; your spend caps still apply.
  • Pipeline — the full-lifecycle per-company view: one track per company, each expandable to its roles and the live step in flight, filtered by Active / Waiting / Stalled. This is where you watch what's moving right now.
  • Roles — every role Harrier has seen, as a sortable/searchable table (filter by search, grade, stage, timeframe) above a funnel strip, with a column picker. This is where you go to answer "what happened to that job".
  • Stats — charts over time (scored, submitted, confirmed, interviews, rejections), plus three all-time diagnostics that answer "where is this pipeline losing work": good roles we never sent and why (the largest loss bucket — mostly application sites Harrier has no autonomous path to, listed by site so you know which adapter is worth building), which job sources are worth running (postings found against applications actually sent, per discovery source — a source can be the biggest supplier of postings and produce almost nothing), and what an application costs (measured AI spend per sent application, split into finding-the-work and sending-it, with the repair lane's share called out because it is a switch you can turn off).
  • Prep — interview practice: a problem bank (Easy→Hard, filterable by difficulty), an AI coach (graduated hints / full explanation / mock interviewer), and a multi-language code runner (JavaScript in-browser; Python/Java/C++/Ruby compiled server-side). The editor has live syntax checking in every runner language (squiggles + error messages as you type — JavaScript via the TypeScript language service in a lazily-loaded chunk; Python/Java/C++/Ruby via their real toolchains server-side) and hover documentation (signatures + stdlib docs + param docs, IDE-style; JavaScript first). The language picker shows the detected runtime each language executes against (e.g. Python · 3.9.6, C++ · clang 17.0.0 · c++17). Prep has two nested tabs: Practice (the problem-bank workspace above) and Screen — a faithful reproduction of CoderPad's AI Assist interview environment (the "AI turned on in CoderPad" screen), with a right-docked assistant offering Ask / Plan / Edit modes over an honest Claude model picker, an interviewer-observer that probes how you use the AI, a 60-minute timer, and a post-session scorecard on the four competencies (Problem-Solving, Code Quality, Verification, Communication) that flags the documented anti-patterns.
  • Schedule — your interviews on a 4-week calendar synced from your Google Calendar (interviews only; blank until you connect Google). Click any meeting for its details + an on-demand AI gameplan. Comp/take-home planning lives under Profile → Take-home (federal + FICA + state tax → net pay, feeding your search floor).
  • Guide — a built-in "How Harrier works" explainer (the six stages: discover → score → tailor → stage → submit → track); the place to start on day one.
  • Profile (top-right button) — a gear (with a pending-actions count badge when the action-items source is enabled) opening a page with an About you / Résumé / Job search / Take-home sub-nav. About you is your identity and contact details; Résumé is the experience/skills/education intake Harrier writes your résumé from; Job search is what to chase (target titles, work eligibility, minimum salary, home city, remote preference, interview style, résumé voice, AI spend budget, and the Email & notifications connection); Take-home is the tax/net-pay math behind your salary floor. On a packaged install, harrier init does the same first-time setup from the terminal (your API key + profile — it never asks for a license); the first 3 applications are free, then harrier activate <key> unlocks unlimited. On a clone, use the Profile page and skip init entirely.

New here? Start with docs/beta-setup.md — the full from-scratch walkthrough.


Prerequisites

System requirements at a glance: macOS or Linux · Node.js 22+ · Google Chrome · ~2 GB free RAM while it's actively submitting (it drives a real Chrome) · ~5 GB free disk — a live install settles around 2 GB (~850 MB node_modules + ~1 GB state/, most of it the per-employer browser profiles), and the rest is headroom for the temporary submission recordings; see Disk space. Any modern laptop handles it; on a small drive the disk figure is the one to watch.

  • ~5 GB of free disk space. Harrier keeps everything on your own computer — see Disk space & what's stored below. On a small drive (e.g. a base MacBook Air), this is the requirement to watch.
  • Node.js 22–26 (validated through 26; uses built-in ESM auto-detection and node:test).
  • Google Chrome (Playwright drives a real Chrome for submissions).
  • (Optional) a Gmail account + Google App Password to track interview/rejection replies — connected in the dashboard (Profile → Job search → Email & notifications), no OAuth setup. Everything else runs without it.
  • An Anthropic API key (your own, from https://console.anthropic.com) for the AI scoring + résumé tailoring. Put ANTHROPIC_API_KEY and HARRIER_LLM_MODE=anthropic-api in .env, and set a monthly usage limit in the console. The deterministic paths work without it, at lower quality.

Platforms — macOS and Linux. macOS is where Harrier is developed and run daily. Linux is verified from a clean room: docs/beta-validate.Dockerfile builds on node:22-bookworm (Debian) and only exits 0 if npm install, the native better-sqlite3 compile, npx playwright install --with-deps chromium, the dashboard SPA build and the full npm test all pass there. Windows is not supported — it has never been tested (there's no Windows runner to test it on), and setup.sh is bash, so the install path doesn't exist on it. Claiming it without a test would be a guess, so the docs don't. Revisit when there's a Windows runner to build and run the container suite against.

npm start / npm stop / npm run status are one Node launcher (src/harrier.ts, no bash) that runs the whole worker tree as a single supervised process and stops it together. The credential vault is portable too — the master key auto-provisions to the macOS Keychain when available, otherwise to a 0600 key file under ~/.harrier (set CREDENTIALS_KEY, base64 32 bytes, for the strongest headless option). For auto-restart + start-on-boot, point your OS service manager (launchd / systemd --user / Docker / pm2) at npm run serve (the supervisor in the foreground); the bundled launchd plist is the macOS shortcut.

Install JS dependencies:

npm install
npx playwright install chrome

Disk space & what Harrier stores on your computer

Harrier runs entirely on your own machine — nothing is stored in the cloud — so it needs room to work. Plan to keep about 5 GB free. Here's what that space is for, in plain terms:

What gets installed (one-time, ~1–1.3 GB)

Everything lives inside the project folder plus one browser — no system-wide services, no background OS daemons, nothing in the cloud.

  • Harrier and its libraries — ~770 MB, installed into the project's node_modules by npm install. This is the bulk: the browser-automation engine (Playwright), the local dashboard, the SQLite database driver, and the Google/Gmail API client. (npm install also generates the database client and installs the dashboard's own ~24 MB of dependencies — both included in that figure.)
  • A browser for submissions — ~280 MB, via npx playwright install chrome. Harrier drives a real Google Chrome to fill and submit applications. If you already have Chrome, it reuses it and this is ~0. Where Google ships no Chrome (notably Linux on ARM) or the download is blocked, setup falls back to Playwright's own bundled Chromium (~110 MB) so résumé rendering and submissions still work.

To remove Harrier later, you just delete the folder (Chrome, if you want it gone, uninstalls separately).

What Harrier stores as you use it (grows slowly)

Three things accumulate permanently on disk:

  • The job database (state/pipeline.db) — every job it has found and scored. Grows ~10–15 KB per role; tens of MB after thousands of jobs.
  • A logged-in browser profile per employer portal (state/browser-profiles/) — Workday-style portals require an account, so Harrier keeps one Chrome profile per employer rather than logging in from scratch every time. This is the largest thing in state/: ~650 MB on a live install after two months of daily applying. It grows with the number of employers you've applied to, not the number of jobs.
  • A kept application packet per applied job — your tailored résumé (a ~125 KB PDF, plus a durable archived copy under output/resume-archive/), the answers it filled into that company's form, and a saved copy of the job posting. About 0.2–0.3 MB per applied job. (One résumé is written per role — not several — so this is the dominant per-job cost, and it's small.)

Rough durable footprint (résumés + postings + answers + database), excluding the browser profiles above and the temporary recordings below:

| Applied jobs | Kept on disk | |---|---| | 100 | ~25 MB | | 1,000 | ~250 MB | | 5,000 | ~1.2 GB |

The part that can spike — temporary submission recordings

Each time Harrier submits an application it makes a detailed recording of that attempt (mostly full-page screenshots before/after submit) so it can diagnose and retry anything that didn't go through. These are large — usually around 20 MB each, up to ~100 MB on the heaviest career portals (big sites like Twilio, MongoDB, or StackAdapt push the most data). Harrier auto-deletes each recording once that application settles (a confirmation/rejection arrives, or it gives up), so in normal use they don't pile up. While a batch is actively submitting, expect a few hundred MB to a couple of GB of these in use at once — this does not scale with your total job count, only with how many are submitting right now.

If you're on a small drive, watch this. If a batch stalls and applications never settle, the recordings can build up until the automatic cleanup catches them. A quick way to see Harrier's footprint:

du -sh output state    # the two folders that grow with use

Your logins are kept in a local encrypted vault. Some application sites (Workday-based career portals — Home Depot, Target, and many large employers) require an account before you can apply. Harrier creates one per employer with a unique random password and stores those passwords encrypted on your machine (AES-256-GCM). The key that unlocks them lives in your macOS Keychain when available, otherwise in a locked-down (0600) key file in your home folder (~/.harrier) — kept separate from the data, so the database, a backup, or a synced file never exposes a password on its own. Nothing is ever sent over the network; the vault is local-only.


Setup (clone → running)

Quick start: run ./setup.sh — it checks Node, installs dependencies + Chrome, scaffolds config/profile.yaml/.env from the examples (never clobbering existing files), validates your profile, and prints the remaining steps (your API key in .env, adding a résumé). Your whole profile — identity, work eligibility, and search preferences — is set via the dashboard's Profile button (the gear, top-right), not in a file. (harrier init is the packaged install's equivalent — don't run it here; see Install paths.) The steps below are the same flow done by hand.

1. Set your API key

setup.sh already put the two lines in .env; paste your key after ANTHROPIC_API_KEY=. It's a dotfile, so Finder won't show it — open it from the terminal:

open -e .env         # macOS TextEdit (or: code .env · nano .env · $EDITOR .env)
                     # ANTHROPIC_API_KEY=sk-ant-...   HARRIER_LLM_MODE=anthropic-api

That's the only file you must touch. After npm start, click the dashboard's Profile button (the gear, top-right) and fill in everything else — no YAML editing. The page has an About you / Résumé / Job search / Take-home sub-nav:

  • About you — name, current title, years of experience, contact, location, LinkedIn/GitHub.
  • Résumé — experience, skills, education (what Harrier writes your résumé from).
  • Job search — target roles, work eligibility, minimum salary, home city, remote preference, interview style, résumé tone, AI spend budget, Email & notifications.
  • Take-home — the tax/net-pay math behind your salary floor.

These persist to the local database and overlay config/profile.yaml live (a saved value wins; anything you leave blank falls back to the YAML). config/profile.yaml still exists for power-user fields the UI doesn't cover yet — detailed stack, education, full mailing address — and npm run check validates it, but it's optional to start.

2. (Optional) Connect your email

To track submission confirmations, rejections, and interview replies — and get run summaries — connect a Gmail inbox with a Google App Password (no OAuth, no Google Cloud project):

  1. Turn on 2-Step Verification on your Google account, then create an App Password at https://myaccount.google.com/apppasswords.
  2. Connect it either way:
    • Dashboard: Profile → Job search → Email & notifications → paste your address + App Password.
    • CLI: npx tsx src/harrier.ts connect-email

The credential is verified over IMAP and stored encrypted in a local vault; reading and sending both use it. Skip this entirely and everything else still runs — you just won't get reply tracking or summary emails.

3. Initialize the database

The SQLite database (state/pipeline.db) is created automatically on first run from src/db/schema.ts. Nothing to do — it self-initializes.

4. Run

npm start          # start the whole supervised tree in the background; dashboard → http://localhost:3001
npm run status     # is the supervisor running? is the dashboard up?
npm stop           # stop everything together (safe + resumable — state is in SQLite/JSONL)
npm run serve      # run the supervisor in the FOREGROUND (for systemd/launchd/Docker/a terminal)

npm start/stop/status/serve are one Node launcher (src/harrier.ts) — no bash — so they behave identically on macOS and Linux. app.ts is the single supervisor: one process that spawns + keep-alives every worker (dashboard, discovery, drain, …) and tears the whole tree down together on stop.

Individual stages can also be run directly, e.g. npx tsx src/discover-greenhouse.ts, npx tsx src/submit.ts --concurrency 6.


Configuration reference

Everything user-specific lives in config/profile.yaml (see config/profile.example.yaml for the full annotated template): identity/contact, application_answers (EEOC/work-eligibility), prompt_summary (one-line phrasings for Claude prompts), target_comp, geo_preferences, interview_preferences, stack, domains, experience, education.

Runtime tuning is via environment variables (see .env.example for the full annotated list), including: NOTIFY_EMAIL, PROFILE_PATH, LOG_LEVEL, MAX_DAILY_INPUT_TOKENS (Claude budget), ITERATION_ENGINE_HARD_CAP, ATTEMPT_WATCHDOG_MS, the REPAIR_* deep-repair settings, and PORT (dashboard).

Other config files: config/sources.yaml (boards to scan), config/filters.yaml (hard skips, captcha/skip companies), config/learned_answers.yaml (cross-role answer cache), config/strategies.yaml (submission strategy bank).


Useful commands

npm run check          # validate config/profile.yaml
npm test               # unit tests (config loader, geo filter, learned answers, verifier)
RUN_DASHBOARD_RENDER=1 node --test src/test/test-dashboard-render.ts  # Playwright dashboard render tests (the e2e CI gate; needs a built bundle + browsers)
npm run report -- dashboard           # pipeline metrics (today/week/all-time)
npm run report -- backlog             # staged-but-not-confirmed breakdown
npx tsx src/cooldown.ts list          # company application cooldowns
npm run report -- interviewing        # companies paused because an interview is in progress

Architecture (high level)

discover → score → stage → submit → (repair) → track
  • src/discover-*.ts — board probing.
  • src/score-fast.ts + src/classify-jd-fit.ts — scoring.
  • src/stage-*.ts — write staged role folders.
  • src/submit.ts + src/core/* — the submission engine (browser, field-filler, form-solver, iteration-engine, verifier).
  • src/harrier.ts — the start/stop/status/serve launcher.
  • src/app.ts — the single-process supervisor it launches: spawns + keep-alives every worker (dashboard, discovery, drain + repair lanes) and stops them together.
  • src/dashboard/server.ts + index.html — live dashboard (port 3001).
  • src/db/ — SQLite schema + access helpers.
  • src/lib/config.ts — single config loader; src/lib/logger.ts — logging.

Data persists in state/pipeline.db (SQLite, source of truth) plus JSONL mirrors under state/. Generated artifacts live in output/staged/.


Something broken? Report it from inside Harrier

Open the gear in the dashboard header and pick Report a problem. Describe what happened and press Send — Harrier attaches the technical detail itself (version, install type, Node/npm, operating system, the built-in preflight results, which settings are switched on, and the tail of its own logs).

Three things are worth knowing about it:

  • Your credentials and personal data never go. API keys, passwords, OAuth tokens, your résumé, your job list, your name, email, phone and home directory are stripped before the report is even written to disk. Settings are reported as set or unset, never by value.
  • You can read the exact payload first. "Show me the exact report" prints the precise bytes that would be sent. Nothing leaves your machine until you press Send.
  • It sends through the inbox you already connected. If you have not connected one, the report is still saved to output/support/ and Harrier hands you a prefilled draft instead — it will never tell you a report went out when it did not.

If the dashboard itself will not start, the same report can be produced from a terminal:

harrier support               # writes output/support/HR-<date>-<id>.txt and prints where to email it
harrier support --open        # …and opens a prefilled draft in your mail app

Limitations

  • Single-user. One profile, one Gmail account, runs on one machine.
  • Four autonomous ATSes. The drain auto-submits only to Greenhouse, Jobot, Ashby and Workday (DEFAULT_ALLOWLIST in src/lib/submit-ats.ts), and Workday only for tenants in PROVEN_WORKDAY_TENANTS. Eightfold/Netflix has its own dedicated submitter outside that drain. Lever and Workable have working adapters but were removed from the allowlist on 2026-07-26 — measured 0/106 and 0/9 real confirmations against their captcha wall — so they stage for the human-assist lane instead. Every other ATS is discovered but skipped at submit.
  • Selector fragility. Form-filling depends on current ATS DOM structure; ATS UI changes can break field detection until strategies/learned-answers adapt.
  • CAPTCHA / anti-bot. Some companies (tracked in config/filters.yaml) can't be auto-submitted and are skipped or iceboxed.
  • No CI/CD. Runs locally via npm start; no hosted deployment.
  • Credential vault is local + key-bound. The encrypted login vault has two honest caveats: (1) on a headless install (a server/CI box with no OS keychain) you must provide the master key yourself via the CREDENTIALS_KEY env var; (2) the key lives in your machine's secure store, so wiping or migrating the machine loses it — the encrypted passwords then can't be decrypted. That's recoverable, not catastrophic: Harrier simply re-creates the employer accounts (they're also password-resettable via your email). Back up the key (or export/import it) if you want a clean migration.

See docs/ for recon notes and per-company playbooks.