--- name: application-tracker description: Track the state of a job search across applications, recruiter conversations, and prior outcomes — independent of any single resume-tailoring run. Use whenever the user asks "what happened with {Company}", "any recruiters working {Company}", "did I apply to {Company} before", "what's on my someday list", "archive this application", "summarize my pipeline", or wants context about prior or active applications. Also acts as a context provider for the sibling resume-tailor skill — surfaces recruiter threads, prior outcomes, and someday-task matches when resume-tailor invokes a tailoring run for a known company. --- # Application Tracker Maintain context about the user's job search across multiple tailored applications. Reads context from the working folder; surfaces it on request or when a sibling skill (typically `resume-tailor`) asks for it. The skill is **user-agnostic**. Personal data — applications, recruiter threads, tasks, archived outcomes — lives in the user's working folder, not the skill folder. See `examples/working-folder/` for the conventions the skill expects. ## When this skill applies Trigger when the user asks about job-search state, application history, recruiter context, or the open-task list — anything that requires reading aggregate state across multiple applications rather than tailoring a single one. Common trigger phrases: - *"What happened with {Company}?"* — prior-outcome lookup - *"Did I apply to {Company} before?"* — re-application detection - *"Any recruiters working {Company}?"* — recruiter cross-reference - *"What's on my someday list that matches this JD?"* — task matching - *"Summarize my pipeline / active applications."* — state aggregation - *"Archive this application."* — move active → archived via `scripts/archive_application.py` Also acts as a callable context provider for `resume-tailor`: when a tailoring run starts, `resume-tailor`'s Step 0 can invoke application-tracker scripts to surface prior outcomes, recruiter threads, and someday matches for inclusion in `tailoring_notes.md`. ## Working-folder conventions The skill reads context from these conventional locations in the user's working folder. Override paths via CLI flags on the individual scripts when the user organizes things differently. | Convention | Default path | What lives there | | --- | --- | --- | | Active applications | `{working_folder}/Applications/__/` | Per-application folders generated by resume-tailor. Read-only for this skill (until archive workflow lands). | | Archived applications | `{working_folder}/Archive/Applications/__/` | Closed-out applications. Each carries an `_outcome.md` with the result + lessons. | | Recruiter threads | `{working_folder}/memory/people/recruiters.md` (or any single Markdown file the user designates) | Recruiter contacts with one section per active thread: name, firm, last contact, comp anchor, status. | | Tasks | `{working_folder}/TASKS.md` | Task list with sections like `## Active`, `## Waiting On`, `## Someday`, `## Done`. The skill reads the Someday section by default. | See `examples/working-folder/` for templates of each. ## Scripts The skill provides three read-only context-provider scripts. Each is callable independently and emits JSON to stdout for easy consumption by the LLM or by `resume-tailor`'s tailoring workflow. ### `scripts/find_prior_applications.py` Look up prior applications to a given company across `Applications/` and `Archive/Applications/`. ``` python find_prior_applications.py \ --company "Acme Corp" \ --working-folder "/path/to/working-folder" \ [--applications-dir Applications] \ [--archive-dir Archive/Applications] ``` Returns JSON: ```json { "company": "Acme Corp", "matches": [ { "folder": ".../Applications/AcmeCorp_DirectorEng_2026-04-15", "status": "active", "role": "DirectorEng", "date": "2026-04-15", "outcome_excerpt": null }, { "folder": ".../Archive/Applications/AcmeCorp_HeadOfPlatform_2025-11-02", "status": "archived", "role": "HeadOfPlatform", "date": "2025-11-02", "outcome_excerpt": "Rejected after final round — feedback was framework-depth gap." } ] } ``` Matching is case-insensitive and handles common spelling variants (whitespace, punctuation collapsed). ### `scripts/find_recruiter_threads.py` Search the user's recruiter file for threads mentioning a company. ``` python find_recruiter_threads.py \ --company "Acme Corp" \ --recruiters-file "/path/to/memory/people/recruiters.md" ``` Returns JSON: ```json { "company": "Acme Corp", "matches": [ { "heading": "Kegan Smith / TalentUnify", "excerpt": "...Pitched Acme Corp Senior Director role 2026-05-22...", "line_number": 47 } ] } ``` The script returns the surrounding markdown section for each match — the LLM parses the structured fields (name, firm, last contact, comp anchor) from the excerpt at runtime. ### `scripts/archive_application.py` Move an application from `Applications/` to `Archive/Applications/` and stub an `_outcome.md` if one isn't already there. This is the only **write** operation in the skill — every other script is read-only. ``` python archive_application.py \ --application-folder "/path/to/Applications/Globant_VP_Technology_2026-05-16" \ --working-folder "/path/to/working-folder" # Optional: pre-populate outcome fields so the stub isn't all placeholders. python archive_application.py \ --application-folder "..." \ --working-folder "..." \ --outcome-status "Rejected" \ --notified-by "Nicole Gruber, Executive Recruiting Partner — Globant" \ --your-read "Not quite the right fit." \ --outcome-notes "Multi-line note describing what happened, what feedback came through, etc." # --dry-run prints the planned move + the follow-up nudges without touching anything. ``` What it does: 1. Validates that `--application-folder` exists and is inside the working folder's `Applications/` directory. 2. Computes the destination path under `Archive/Applications/` (same folder name). 3. Refuses to clobber an existing destination — fail loudly with exit code 1 instead. 4. Moves the folder via `shutil.move` (preserves all child files: DOCX, JSON, MD). 5. Stubs `_outcome.md` from a template if not already present; populates whichever fields you passed and leaves placeholders for the rest. 6. Emits a JSON report listing the move + a list of follow-up nudges the user / LLM should apply to **other** working-folder files (TASKS.md, memory/projects/job-search.md, memory/people/recruiters.md). What it does NOT do: - It does **not** mutate `TASKS.md`, the job-search memory file, or the recruiters file. Those are user-curated and the right edits depend on the user's conventions; the script surfaces nudges instead. - It does **not** overwrite an existing `_outcome.md` in the source folder — if one exists, it's moved as-is and the stub step is skipped. Returns JSON: ```json { "dry_run": false, "moved_from": "/working-folder/Applications/Globant_VP_Technology_2026-05-16", "moved_to": "/working-folder/Archive/Applications/Globant_VP_Technology_2026-05-16", "folder_name": "Globant_VP_Technology_2026-05-16", "outcome_file": "/working-folder/Archive/Applications/Globant_VP_Technology_2026-05-16/_outcome.md", "outcome_status": "Rejected", "outcome_stubbed": true, "follow_ups": [ "Update TASKS.md: move any Active task referencing this application to Done.", "Update memory/projects/job-search.md: move Globant_VP_Technology_2026-05-16 from active to closed; populate the outcome row.", "Update memory/people/recruiters.md: mark the relevant thread closed/lapsed if applicable.", "Fill in the placeholder fields in _outcome.md — the first content paragraph is what find_prior_applications.py returns when another tailoring run hits the same company." ] } ``` Exit codes: - `0` — moved (or dry-run completed) - `1` — destination already exists; refused to clobber - `2` — application folder is not inside the working folder's applications directory - `3` — application folder does not exist - `4` — I/O error during move ### `scripts/find_someday_matches.py` Scan the Someday section of `TASKS.md` for items matching keywords from a JD. ``` python find_someday_matches.py \ --tasks-file "/path/to/TASKS.md" \ --keywords "healthcare,clinical,HIPAA" [--section-heading "Someday"] ``` Returns JSON: ```json { "keywords": ["healthcare", "clinical", "HIPAA"], "matches": [ { "item": "Build a healthcare-AI artifact for portfolio", "matched_keywords": ["healthcare"], "line_number": 23 } ] } ``` ## Integration with resume-tailor When `resume-tailor` runs and `application-tracker` is loaded: - **Step 0 (resume-tailor)** — `resume-tailor`'s Step 0 invokes the three scripts above with the JD's company + keywords. Results are appended to `tailoring_notes.md`'s "Project context" section. - **Step 6 (resume-tailor)** — `resume-tailor` quotes the prior-outcome excerpts (if any) verbatim in `tailoring_notes.md`'s "Prior outcomes" section. `application-tracker` does not modify `resume-tailor`'s output paths or DOCX rendering — it's strictly a context provider. ## Out of scope (for now) - **Recruiter thread parsing** — the skill returns matched markdown sections; it does not enforce a structured schema for recruiter entries. The LLM extracts structured fields per recruiter at runtime. - **Automatic mutation of user-curated context files** — `archive_application.py` surfaces follow-up nudges for TASKS.md / job-search memory / recruiter file changes but does not apply them. Conventions for those files vary too much across users to safely automate. ## Reference files - `examples/working-folder/` — bootstrap templates a new user copies in. - `scripts/find_prior_applications.py` — re-application detection. - `scripts/find_recruiter_threads.py` — recruiter cross-reference. - `scripts/find_someday_matches.py` — Someday-item matching. - `scripts/archive_application.py` — move an application to the archive, stub `_outcome.md`, surface follow-up nudges.