network-scan

📁 proficientlyjobs/proficiently-claude-skills 📅 5 days ago
4
总安装量
4
周安装量
#50043
全站排名
安装命令
npx skills add https://github.com/proficientlyjobs/proficiently-claude-skills --skill network-scan

Agent 安装分布

opencode 4
gemini-cli 4
antigravity 4
claude-code 4
github-copilot 4
codex 4

Skill 文档

Network Scan Skill

Priority hierarchy: See shared/references/priority-hierarchy.md for conflict resolution.

Proactively check whether companies where you know someone are hiring for roles that match you. First run builds a cache of company careers page URLs. Subsequent runs reuse the cache, making weekly checks fast.

Quick Start

  • /proficiently:network-scan – Scan companies from your 25 most recent contacts
  • /proficiently:network-scan 50 – Check the 50 most recent contacts
  • /proficiently:network-scan all – Check all contacts (can be slow with 1500+)

File Structure

scripts/
  resolve-careers.md     # Subagent for resolving a batch of company careers URLs
  evaluate-company.md    # Subagent for scanning a batch of companies' open roles

User data (stored at ~/.proficiently/):

~/.proficiently/
  resume/                # Your resume PDF/DOCX
  preferences.md         # Job matching rules
  profile.md             # Work history from interview
  linkedin-contacts.csv  # LinkedIn contacts export
  company-careers.json   # Cached company careers URLs
  network-scan-history.md # Running log of scan results
  jobs/                  # Per-job application folders

Workflow

Step 0: Check Prerequisites

Resolve the data directory, then check prerequisites per shared/references/prerequisites.md. Resume, preferences, and linkedin-contacts.csv are all required.

Load these files for use in later steps:

  • DATA_DIR/preferences.md (target roles, must-haves, dealbreakers, nice-to-haves)
  • DATA_DIR/resume/* (candidate profile)
  • DATA_DIR/profile.md (work history, if it exists)

Step 1: Select Contacts & Extract Companies

Parse $ARGUMENTS:

  • If a number (e.g., 50): use that as the contact limit
  • If all: use all contacts (warn user this may be slow if > 200)
  • If empty/missing: default to 25

Read ~/.proficiently/linkedin-contacts.csv. Sort by “Connected On” descending (most recent first). Take the first N contacts based on the limit.

Extract unique company names from the selected contacts. Skip companies with empty or blank names.

Group contacts by company into a lookup:

{
  "Google": [{"name": "Jane Smith", "position": "PM Director", "url": "https://linkedin.com/in/janesmith"}, ...],
  "Stripe": [{"name": "John Doe", "position": "Eng Manager", "url": "https://linkedin.com/in/johndoe"}]
}

Report to user: “Found X unique companies from Y contacts. Checking careers pages…”

Step 2: Resolve Careers Pages (Parallelized)

Load ~/.proficiently/company-careers.json if it exists (the cache). If it doesn’t exist, start with an empty object.

Split companies into three groups:

  • Cached (fresh): last_checked within last 7 days – use as-is, no work needed
  • Cached (stale): last_checked older than 7 days – needs re-verification
  • Uncached: not in cache, or type is "not_found" and stale – needs full resolution

Report: “X companies from cache, Y need resolution…”

Parallel resolution using subagents:

Take all companies needing resolution (stale + uncached) and split them into batches of 10. Spawn one subagent per batch using the Task tool (subagent_type: "general-purpose"). Run all batches in parallel.

Each subagent receives:

  • A batch of company names to resolve
  • Instructions from scripts/resolve-careers.md

Each subagent uses WebSearch (NOT the browser) to find careers pages:

  1. Search: "[Company Name]" careers jobs site:[company domain if known]
  2. From the search results, identify the careers/jobs page URL
  3. Classify the URL type:
    • "direct" – company’s own careers page (e.g., careers.google.com)
    • "greenhouse" – Greenhouse ATS (boards.greenhouse.io/company or company.greenhouse.io)
    • "lever" – Lever ATS (jobs.lever.co/company)
    • "workday" – Workday ATS (company.wd5.myworkdayjobs.com)
    • "other_ats" – other ATS platforms (Ashby, BambooHR, etc.)
    • "not_found" – no careers page could be found (set careers_url to null)
  4. Return results for the batch

Collect results from all subagents and merge into the cache. Save ~/.proficiently/company-careers.json. Format:

{
  "Company Name": {
    "careers_url": "https://careers.example.com",
    "type": "direct",
    "last_checked": "YYYY-MM-DD",
    "last_found_roles": 0
  }
}

Report progress: “Resolved X new careers pages, Y from cache, Z not found.”

Step 3: Scan for Matching Jobs (Parallelized)

Take all companies with a valid careers_url (skip not_found and ignored entries). Split them into batches of 5 companies each.

Spawn parallel subagents using the Task tool (subagent_type: "general-purpose"). Run all batches in parallel (up to 5 concurrent subagents to avoid overwhelming the browser).

Each subagent receives:

  • A batch of companies (name, careers_url, ATS type, network contacts)
  • Candidate profile summary (from resume)
  • Preferences (target roles, must-haves, dealbreakers, nice-to-haves)
  • Instructions from scripts/evaluate-company.md

Each subagent:

  1. Creates its own browser tab (tabs_context_mcp then tabs_create_mcp)
  2. For each company in its batch: a. Navigate to the careers page b. Search/browse for roles matching target roles and keywords c. For ATS pages, use platform search/filter functionality:
    • Greenhouse: search box or department filters
    • Lever: search bar or team filter
    • Workday: keyword search field
    • Direct/other: browse the page, use any search, scan listed roles d. Extract listings: title, location, URL e. Score each listing (High/Medium/Low/Skip per fit criteria) f. Return only High and Medium fits
  3. Returns results for its entire batch

Fit scoring criteria: See shared/references/fit-scoring.md for the canonical definitions.

Collect results from all subagents. Update last_found_roles count in the cache for each company scanned.

If a subagent fails or times out, log the companies it was processing and move on. Do not retry – the user can re-run with those companies next time.

Step 4: Save Results

Update company-careers.json: Update last_checked and last_found_roles for every company that was scanned.

Append to ~/.proficiently/network-scan-history.md:

If the file doesn’t exist, create it with:

# Network Scan History

This file tracks all network scans run by the `/network-scan` skill.

---

Then append:

## YYYY-MM-DD - Network Scan (N contacts, M companies)

| Company | Contact | Role Found | Fit | URL |
|---------|---------|------------|-----|-----|
| Google | Jane Smith (PM Director) | Sr. Product Manager | High | https://... |
| Stripe | John Doe (Eng Manager) | No matching roles | - | - |

Include all companies scanned (both matches and non-matches) in the table.

Save full postings for High-fit matches: For each High-fit match, navigate to the job posting URL and save the full posting to ~/.proficiently/jobs/[company-slug]-[YYYY-MM-DD]/posting.md using the standard format:

# [Job Title] - [Company Name]

**Company**: [Company]
**Location**: [Location]
**Salary**: [Salary or N/A]
**Type**: [Type]
**Source**: network-scan
**Date Found**: YYYY-MM-DD
**Network Contact**: [Contact Name] ([Position]) - [LinkedIn URL]

## About the Role
[Description]

## Key Requirements
- [requirement]

## Direct Careers Page
- [URL]

## Fit Assessment
**Rating**: [High/Medium]
**Why**: [explanation]

Step 5: Present Results

Show matches grouped by fit, with contact info for warm introductions:

## Network Scan Results - YYYY-MM-DD
Scanned N companies from M contacts.

### Matches Found

#### 1. Senior Product Manager at Google
- **Fit**: High
- **Your contact**: Jane Smith (PM Director) - [LinkedIn](url)
- **Location**: Mountain View, CA
- **Apply**: https://careers.google.com/jobs/...
- **Why**: [brief match reason]

#### 2. Strategy Lead at Stripe
- **Fit**: Medium
- **Your contact**: John Doe (Eng Manager) - [LinkedIn](url)
- **Location**: Remote
- **Apply**: https://stripe.com/jobs/...
- **Why**: [brief match reason]

### Companies Checked (No Matches)
Google (3 open roles, none matching), Stripe (0 open roles), ...

### Companies Without Careers Pages
Acme Corp, Small Startup LLC, ...

If no matches were found across all companies:

## Network Scan Results - YYYY-MM-DD
Scanned N companies from M contacts. No matching roles found this time.

### Companies Checked
[List with role counts]

### Companies Without Careers Pages
[List]

Try again next week, or expand your search: `/proficiently:network-scan 100`

End with:

To tailor a resume: /proficiently:tailor-resume [job URL]
To write a cover letter: /proficiently:cover-letter [job URL]

Built by Proficiently. Want someone to find jobs, tailor resumes,
apply, and connect you with hiring managers? Visit proficiently.com

Step 6: Learn from Feedback

If the user provides feedback after seeing results:

  • “Skip [company]”: Add "ignored": true to that company’s entry in company-careers.json. Future scans will skip it.
  • Corrects a careers URL: Update the cache entry with the correct URL and type.
  • Adjusts preferences: Update ~/.proficiently/preferences.md accordingly (e.g., “add fintech to nice-to-haves”, “no crypto companies”).

Response Format

Structure user-facing output with these sections:

  1. Network Matches — list of High/Medium fits with company, role, fit rating, contact name, and apply URL
  2. Companies Checked — summary of companies with no matches and companies without careers pages
  3. Next Steps — suggest /proficiently:tailor-resume and /proficiently:cover-letter for top matches

Permissions Required

Add to ~/.claude/settings.json:

{
  "permissions": {
    "allow": [
      "Read(~/.claude/skills/**)",
      "Read(~/.proficiently/**)",
      "Write(~/.proficiently/**)",
      "Edit(~/.proficiently/**)",
      "mcp__claude-in-chrome__*"
    ]
  }
}