Skip to content
Back to skills

Application Tracker

ASecurity

Tracks the state of a user's job applications and drafts the follow-up communication around them. Use when the user wants to track their applications, see where they are across all their applications, build or update an application tracker, ask "what should I follow up on?", draft a polite check-in for an application that has gone quiet, write a post-interview thank-you note, or mark an application's status (applied, interviewing, offer, rejected, withdrawn). Maintains a small tracker.json an...

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 14, 2026
ai-agentspythongobashgit

Works with

  • claude code
  • cli

Security analysis

A100/100

Pro scans all 14 files and shows the line behind each finding

Scanned October 14, 2026

npx -y skills add wexxwuther/job-hunter --skill application-tracker --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Application Tracker?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Application Tracker
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wexxwuther-application-tracker/badge)](https://www.skillsdirectory.com/skills/wexxwuther-application-tracker)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: application-tracker
description: >
  Tracks the state of a user's job applications and drafts the follow-up communication around
  them. Use when the user wants to track their applications, see where they are across all
  their applications, build or update an application tracker, ask "what should I follow up on?",
  draft a polite check-in for an application that has gone quiet, write a post-interview
  thank-you note, or mark an application's status (applied, interviewing, offer, rejected,
  withdrawn). Maintains a small tracker.json and renders a self-contained ApplicationTracker.html
  with sortable rows, status pills, and (when scores are present) a colored score badge. Do not
  use for tailoring a resume (use resume-tailor), writing a cover letter (use cover-letter),
  or finding or
  scoring job postings (use job-search). It never auto-sends email — it drafts; the user sends.
license: MIT
compatibility: Cross-vendor (agentskills.io open standard) + cross-OS (Windows, macOS, Linux). Installs across Claude Code, OpenAI Codex, OpenClaw, and Hermes Agent. Works standalone or as the tracker member of the job-hunter family; reads the shared .job-hunter/ workspace and postings.json if present and degrades gracefully if absent.
metadata:
  spec_version: "agentskills.io (living spec; tracked 2026-05-28)"
  family: "job-hunter"
  family_role: "tracker"
allowed-tools: Read Write Edit Bash(python:*) Glob Grep
---

# application-tracker (family tracker member)

Keep a clear, shareable record of where every application stands, and draft the
polite follow-ups and thank-you notes that move them forward — without ever
sending mail on the user's behalf. This is the **tracker** member of the
job-hunter family, and it maps to "Phase 4: Prepare for Submission" plus
"Phase 4.5: Stale-application follow-ups" of the end-to-end hunt.

## When to use this skill

Use this skill when the user wants to **track** applications or **draft
follow-up communication**:

- "Track my applications" / "build me an application tracker"
- "Where am I on all my applications?" / "show me my application statuses"
- "What should I follow up on?" / "which applications have gone quiet?"
- "Draft a follow-up for the Stripe application"
- "I had a phone screen yesterday — help me write a thank-you note"
- "Mark the Acme application as interviewing" / "update my tracker"

Do **not** use this skill for tailoring or optimizing a resume (use
**resume-tailor**), writing a cover letter (use **cover-letter**), or for finding or scoring job
postings (use **job-search**). For an end-to-end hunt that spans several of
these, the **job-hunter** orchestrator routes across the family.

## Inputs (workspace contract)

This member reads upstream artifacts **if present** and **degrades gracefully**
if absent, so it also works standalone:

- **`postings.json`** (scored postings, produced by job-search): supplies
  company, title, url, location, salary, posted date, and the optional
  `score_breakdown`. Carry these straight onto the matching `tracker.json`
  entries when seeding the tracker.
- **Tailored resume / cover-letter filenames** (produced by resume-tailor):
  e.g. `Resume_Stripe_SeniorPM.docx`, `CoverLetter_Stripe_SeniorPM.docx`.
  Record them on the tracker entry as `resume_file` / `cover_letter_file` so the
  rendered HTML links to the exact materials submitted.

Produces a **`tracker.json`** the user owns, rendered into a self-contained
**`ApplicationTracker.html`** per the family workspace contract (see
`references/workspace-contract.md`, shipped with this skill; the `job-hunter`
orchestrator owns the canonical copy and is the single source of truth for the
family's typed hand-offs).

## Phase 4: Prepare for Submission

For each targeted position, provide a summary package:
- Link to the original posting (clickable, in HTML)
- The tailored resume file
- The cover letter (if generated)
- A short "application notes" blurb: 3-5 talking points the user should emphasize if they get
  an interview, based on how their background maps to this specific role

Save a final **Application Tracker** HTML file to the workspace folder. Maintain a small JSON
file `tracker.json` with the list of targeted positions (fields: `company`, `title`, `url`,
`location`, `salary`, `posted`, `applied_date`, `status`, `resume_file`, `cover_letter_file`,
`notes`, `match_strength`, and optionally `score_breakdown`, see below), then run
`scripts/generate_tracker_html.py tracker.json --out ApplicationTracker.html` to render it.
The script bundles inline CSS (from `assets/templates/tracker.css`), sortable table layout,
color-coded match and status badges, and totals-by-status pills, fully self-contained, no
external assets, so the user can email or share the tracker without anything breaking. Status
values: `to apply`, `applied`, `interviewing`, `offer`, `rejected`, `withdrawn`. Re-run the
script as the user updates `tracker.json` over time.

**Field discipline, `posted` vs `applied_date`:** these are two different dates and the
distinction is load-bearing.

- **`posted`** is the date the **company** put the job up. A posting that's been live for 30
  days is a soft signal for ghost-job risk (see `posting_legitimacy` rubric).
- **`applied_date`** is the date the **user** submitted their application. Phase 4.5's
  stale-detection (`scripts/draft_followup.py scan-stale`) reads ONLY this field, never
  `posted`. Conflating them produces false-positive stale flags on old postings that were
  just applied to.

When you set status to `applied`, set `applied_date` to today's date. The `posted` field
stays as whatever the original posting showed. Both fields are independent.

**Score breakdown (optional but recommended):** when job-search has scored a posting
(`postings.json` carries a `score_breakdown`), include that output as a `score_breakdown`
field on the tracker entry:

```json
"score_breakdown": {
  "cv_match": 4.5, "comp_vs_target": 4.5, "cultural_signals": 4.0,
  "posting_legitimacy": 5.0, "red_flags_penalty": 0.0,
  "weighted_global": 4.5, "recommendation": "apply"
}
```

When any row has a score breakdown, the tracker renders a colored score badge as the
primary at-a-glance signal, sorts rows by `weighted_global` descending, and adds filter
controls (recommendation buckets + minimum-score slider). Clicking a score badge expands
the row to show the 5 sub-score bars. Rows without a score_breakdown keep the legacy
match-strength tag rendering, backward compat is preserved.

The CSS is the source of truth at `assets/templates/tracker.css` — it is **never** inlined
back into the script (a load-bearing test enforces this; the rendered HTML must carry the
asset's declarations, so asset and script can't silently drift apart).

## Phase 4.5: Stale-application follow-ups

This phase runs (a) when the user asks about follow-ups, (b) when the user
explicitly invokes "what should I follow up on?", or (c) opportunistically when
you notice (via `tracker.json` inspection) entries that are stale at status=applied.

1. **Identify stale applications.** Run:
   ```
   python scripts/draft_followup.py scan-stale --tracker tracker.json [--stale-days 7]
   ```
   Default threshold is 7 days. Returns the list of applications at
   `status=applied` for >=7 days. Does NOT flag entries at `interviewing`,
   `offer`, `rejected`, or `withdrawn`, those need different communication
   patterns (or none at all). scan-stale reads ONLY `applied_date` — never
   `posted` — so a posting that was live for 30 days but applied to today is
   not flagged.

2. **Surface to user before drafting.** Present the list of stale applications
   first, ask which the user wants to follow up on. Some users prefer batched
   follow-ups; some are selective. Don't draft emails for entries the user
   hasn't asked about.

3. **Draft each requested follow-up.** Run:
   ```
   python scripts/draft_followup.py draft --template check_in \
       --company "<Company>" --role "<Role>" --applied-date <YYYY-MM-DD>
   ```
   The output is a structurally correct email body with `[Add one specific
   qualification...]` placeholder. The user MUST personalize before sending,
   generic follow-ups get ignored at the same rate as no follow-up. See
   [`references/followup-templates.md`](references/followup-templates.md) for the
   patterns and rationale.

4. **Post-interview thank-yous use a different template.** After the user
   reports an interview (phone screen, onsite), draft a thank-you within 24-48
   hours using `--template thank_you`. Ask the user for one specific thing
   discussed so the placeholder gets filled with real content.

5. **Never auto-send.** This script never sends mail, the script doesn't even
   import SMTP or email libraries (load-bearing safety test enforces this).
   The user copy-pastes into their own mail client. The skill is a drafter,
   not a sender.

6. **Cap follow-ups.** Per hiring-advisor consensus (Indeed, The Muse, Robert
   Half), the convention is: 1 check-in 7-10 days after applying, optional
   second touch 5-7 days later if you have something new to add, then move on.
   After 21 days of silence, update `tracker.json` status to
   `no_response_after_21d`, that closes the loop and feeds the learning loop
   (outcome-learning's Phase 5).

## Standalone vs. routed

Standalone, this skill keeps a tracker of whatever applications the user tells it
about and drafts the follow-ups they ask for. Under the `job-hunter` orchestrator
it's the Phase 4 / 4.5 member: it seeds `tracker.json` from `postings.json` and
the resume-tailor output filenames, and its `no_response_after_21d` closures feed
outcome-learning's per-user learning loop. It degrades gracefully either way —
with no orchestrator workspace present it simply maintains `tracker.json` and
renders the HTML in the user's folder.

Files in this skill

  • CHANGELOG.md496 B
  • SKILL.md9.7 KB
  • _meta.json1.5 KB
  • assets/templates/tracker.css4.9 KB
  • docs/continuity/README.md259 B
  • evals/outcome-evals.json4.1 KB
  • evals/trigger-evals.json2.5 KB
  • references/followup-templates.md4.8 KB
  • references/workspace-contract.md4.7 KB
  • scripts/draft_followup.py11.4 KB
  • scripts/generate_tracker_html.py15.1 KB
  • tests/test_draft_followup.py11.9 KB
  • tests/test_generate_tracker_html.py12.1 KB
  • tests/test_member_meta.py500 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.