The Problem

Job‑seeking professionals must repeatedly locate postings, evaluate fit, and fill web forms while protecting personal data. Manual copy‑paste is error‑prone, and most automation tools store résumés or credentials in the cloud, violating privacy expectations.

What This Does

The repository ships a privacy‑first “Agent Skill” that can be invoked from a coding agent or the command line.

  • bin/job-application-agent.mjs is the published CLI entry point (npx job-application-agent@latest install). It boots the installer located in installer/src/cli.mjs.
  • The installer (installer/src/installer.mjs, runner.mjs, scheduler.mjs) copies the skill into the user’s ~/.agents/skills/ tree, registers automatic update checks, and writes a local ledger that never leaves the host.
  • Core job‑application logic lives in job-application-agent/scripts/job-application.mjs (≈830 LOC). It orchestrates discovery, qualification, and form‑filling using the résumé stored by the secret store (job-application-agent/scripts/secret-store.mjs).
  • Telemetry is isolated in the telemetry-worker sub‑project. telemetry-worker/src/worker.mjs receives anonymised usage events from job-application-agent/scripts/telemetry-client.mjs and persists them in a Cloudflare Workers KV (defined in telemetry-worker/wrangler.jsonc). The schema for those events is defined in job-application-agent/scripts/telemetry-schema.mjs.

How It Is Wired

  1. Entry pointbin/job-application-agent.mjs parses the invoked sub‑command and immediately imports installer/src/cli.mjs.
  2. CLI flowcli.mjs validates arguments, then calls installer/src/installer.mjs to perform the filesystem copy and schedule periodic npm checks (via the scheduler.mjs helper).
  3. Skill activation – Once installed, an agent loads the skill from ~/.agents/skills/job-application-agent. The agent calls the exported function in job-application-agent/scripts/job-application.mjs. This file is the widest‑impact hub (5 incoming imports, 3 outgoing, instability 0.75).
  4. Discovery & qualification – Inside job-application.mjs the code branches heavily (≈70 branch points) to handle different ATS platforms, duplicate detection, and eligibility checks. It reads the résumé from secret-store.mjs and writes confirmed applications to a local ledger (installer/src/runner.mjs assists with file I/O).
  5. Telemetry – After each successful step, telemetry-client.mjs formats an event per telemetry-schema.mjs and posts it to the worker endpoint (telemetry-worker/public/index.html loads dashboard.js). The worker (worker.mjs) stores the event in KV and updates the public dashboard (public/dashboard.js).
  6. Update loopinstaller/src/scheduler.mjs runs on login and hourly (macOS/Linux/Windows) to invoke installer/src/cli.mjs with the update sub‑command, which pulls the latest npm version and swaps the skill directory atomically.

No circular dependencies were found; the most connected modules are telemetry-schema.mjs, telemetry-client.mjs, and the installer components. The large monolith job-application.mjs has the highest blast radius because many other modules import it and it imports three others.

How To Use It

# Install the skill (the only required command)
npx job-application-agent@latest install

# Verify installation and update mode
npx job-application-agent@latest status

# Manually trigger an update
npx job-application-agent@latest update

The installer writes to ~/.agents/skills/job-application-agent and creates a hidden ledger at ~/.agents/skills/job-application-agent/.ledger. No additional environment variables are required out‑of‑the‑box. To run the telemetry dashboard locally, serve telemetry-worker/public with any static server (e.g., npx serve telemetry-worker/public).

Real‑World Use

A developer integrates the skill into a personal AI assistant:

import runJobApp from '~/.agents/skills/job-application-agent/scripts/job-application.mjs';
await runJobApp({ resumePath: '~/resume.pdf', target: 'software engineer' });

The assistant calls runJobApp, which discovers matching postings, scores them, fills the forms using the local résumé, and records each submission in the private ledger while sending anonymised metrics to the public dashboard.

Code Health & Issues

  • MEDIUM – Enable Dependabot or Renovate – only one manifest (package.json) and no bot config. Add .github/dependabot.yml.
  • MEDIUM – Dependency‑vulnerability scan missing – CI workflows lack a scan step. Insert dependency-review-action or osv-scanner.
  • MEDIUM – Checkout persists tokenpublish-npm.yml checks out with default credentials; set persist-credentials: false and supply a token only to the push step.

Additional observations:

  • Tests exist for installer, skill, and telemetry (installer/tests/*.mjs, job-application-agent/tests/*.mjs, telemetry-worker/tests/*.mjs).
  • No Dockerfile, so containerised deployment must be added manually if required.
  • Documentation is limited to README.md, SKILL.md, and a few reference markdown files; API‑level docs are absent.

The Bottom Line

The repo delivers a functional, privacy‑oriented job‑application automation skill with a clear install path and solid test coverage. High cognitive load in job-application.mjs and lack of automated dependency management are the primary technical liabilities. It is suitable for engineers comfortable refactoring large scripts and who need a self‑hosted solution for private job‑search automation.