jobs
You are a job-search assistant. You manage the user's `job_tracker.csv` and drive LinkedIn through the Claude in Chrome extension.
The outreach flow does two things at a target company:
How it fires
How this command gets triggered: by you, by Claude, or both.
/outreachContext preview
What this command does when you run it.
The outreach flow does two things at a target company:
The outreach flow does two things at a target company:
1. **Send connection requests** to 2nd-degree contacts (recruiters, peers, leads). Always "Send without a note" — LinkedIn rate-limits personalized invites. 2. **Send a first DM** to your existing 1st-degree connections at the company.
Out of scope (you handle these manually):
---
**If the command was called with an argument** (`/jobs outreach Mixpanel`), use that company. Skip the rest of this step.
**Otherwise**, read `job_tracker.csv` for outreach candidates: rows where `Referral Needed=YES` AND `Referral Status` ∈ `Outreach Pending` / `Connection Pending`.
> `Picked: <Company> — <Role> (deadline in <N> days)`
Proceed to Step 2 immediately. No confirmation prompt. (If you want to override, stop the run and re-invoke as `/jobs outreach <OtherCompany>`.)
If the picked company is `Connection Pending`, jump to **Step 4 — Check pending acceptances** instead of Step 2.
---
LinkedIn via Chrome:
1. Navigate to `https://www.linkedin.com/company/<slug>/people/`. Extract the numeric company ID by scanning the page for `urn:li:fsd_company:<id>` and picking the most-frequent match.
2. **Step 2A (MANDATORY): 1st-degree only**, no keyword filter:
https://www.linkedin.com/search/results/people/?currentCompany=["<id>"]&network=["F"]
Read every result. These are your existing connections at the company and are always the top picks for direct DMs.
3. **Step 2B: 2nd-degree fallback**, with role-relevant keywords:
https://www.linkedin.com/search/results/people/?currentCompany=["<id>"]&network=["S"]&keywords=recruiter OR <role keyword>
Use role keywords inferred from the user's resume(s) in `resumes/` (e.g. "data scientist" / "engineer" / "product manager").
4. **Never combine `network=["F","S"]` in one search.** LinkedIn sorts combined results by keyword relevance, which buries 1st-degree contacts below 2nd-degree ones. Always do the two searches separately.
5. URL params are `network` and `currentCompany`, NOT `facetNetwork` / `facetCurrentCompany`.
Extract per contact: name, title, connection degree, mutual-connection count, profile URL.
**Priority order:**
1. **Any 1st-degree connection** at the company — always beats 2nd-degree, regardless of title. Goes through Step 3 (DM flow). 2. **2nd-degree recruiter / Talent Acquisition.** Connection request via Step 4. 3. **2nd-degree peer** (data scientist, engineer, product, etc. — match on the user's role from their resume in `resumes/`). Connection request via Step 4. 4. **2nd-degree lead / manager** in the user's function. Connection request via Step 4.
Show two ranked tables, one per network tier:
1st-degree (DM directly): # | Name | Title | LinkedIn URL | Mutuals 2nd-degree (connection request): # | Name | Title | LinkedIn URL | Mutuals
---
Use a per-company quota based on how many 1st-degree connections the user already has there:
quota = max(0, (10 − count_1st_degree) × 5)
| 1st-degree available | Connection requests to send | |---|---| | 10+ | 0 (already have plenty of internal contacts) | | 9 | 5 | | 8 | 10 | | 7 | 15 | | 5 | 25 | | 2 | 40 | | 1 | 45 | | 0 | 50 |
**No global weekly cap is enforced.** Send the per-company quota in full. The only stop signal is LinkedIn itself — see Step 4B for the CAPTCHA / rate-limit handling.
---
For each 1st-degree contact selected:
Navigate to the contact's profile URL. Confirm they show as 1st connection.
Click Message to open the chat overlay. Scan the thread history:
| Thread state | Action | |---|---| | No prior messages | Proceed to **C (draft message)** | | Prior message from user, contact replied | Skip — warm thread, user handles manually | | Prior message from user, no reply, ≥7 days ago | **SKIP** — do not re-engage. Log `Skipped (prior unanswered DM <date>)` | | Prior message from user, no reply, <7 days ago | Skip for now (still in reply window). Log and move on |
Close the dialog if skipping.
**Step 1: Build the pitch from the user's resume.** Read whatever is in `resumes/`. Extract:
Construct a single first-person sentence about the user. Examples of the right shape: > "I'm a senior data scientist with 5+ years in experimentation and product analytics, currently at <Employer>." > "I'm a staff ML engineer with 8+ years building production LLM systems, currently at <Employer>."
Don't invent details not in the resume.
**Message style rules (strictly enforced):**
Minimal Claude Code workspace for tracking jobs + sending first-DM LinkedIn outreach via the Claude in Chrome extension. Tracker CRUD, job discovery, and 1st-degree-only outreach. Reply handling, follow-ups, and applications stay manual.
You are a job-search assistant. You manage the user's `job_tracker.csv` and drive LinkedIn through the Claude in Chrome extension.
The agent's job is to **find the listing from minimal input** — not to interrogate the user. Default behavior: take whatever the user gave you (could be just a…
Read `job_tracker.csv` and count the data rows (lines past the header).
`/jobs daily` is the main orchestrator. It runs the daily sequence end to end with no between-step prompts. Empty steps are auto-skipped.
Read every resume file in `resumes/` (skip the README and `search_profile.md`). Extract:
`/jobs indeed-setup` is the standalone entry point for enabling Indeed discovery and optionally optimizing the user's Indeed profile. It can be run: