Metadata-Version: 2.4
Name: prospect-jobs
Version: 0.1.0
Summary: Autonomous AI job opportunity hunter for Twitter/X
Author-email: Ishrat Jahan Ananya <nahajtahanan@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/coreprinciple6/Prospect
Project-URL: Repository, https://github.com/coreprinciple6/Prospect
Project-URL: Issues, https://github.com/coreprinciple6/Prospect/issues
Keywords: job-search,twitter,ai,automation,llm
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: sqlalchemy>=2.0
Requires-Dist: apscheduler>=3.10
Requires-Dist: python-dotenv>=1.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: anthropic>=0.50
Requires-Dist: openai>=1.0
Requires-Dist: playwright>=1.40
Requires-Dist: pypdf>=4.0
Provides-Extra: dashboard
Requires-Dist: streamlit>=1.35; extra == "dashboard"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"

# Prospect

**Prospect** is an autonomous AI job opportunity hunter for Twitter/X. It searches for hiring tweets matching your target role and location, scores them against your profile using a local or cloud LLM, and surfaces the best leads in a review dashboard.

Works for any role, any location, any tech stack — all behaviour is driven by your config files.

## Quick Start

### 1. Install

```bash
# Install from PyPI
pip install prospect-jobs

# Or clone and install in dev mode
git clone <repo>
pip install -e ".[dashboard]"
playwright install chromium
```

### 2. Set up config files

```bash
cp profile.yaml.example profile.yaml    # Your target roles, skills, location
cp config.yaml.example config.yaml      # Search queries, LLM settings
cp .env.example .env                    # Twitter credentials + Anthropic API key
```

**Edit `profile.yaml`** — fill in your name, target roles, skills, and location preferences.

**Shortcut:** auto-generate `profile.yaml` from your resume PDF:
```bash
prospect init --resume path/to/resume.pdf
```
This uses your configured LLM (Anthropic if `ANTHROPIC_API_KEY` is set, otherwise Ollama) to extract your target roles, skills, and summary. Review the output before running searches.

**Edit `config.yaml`** — replace the example queries with ones relevant to your role and geography:
```yaml
search:
  queries:
    - "hiring ML engineer NYC"
    - "LLM engineer job remote"
    - "AI startup hiring [your city]"
```

**Edit `.env`** — add your Twitter login credentials:
```
X_USERNAME=your_twitter_username
X_EMAIL=your@email.com
X_PASSWORD=your_password
```

### 3. Pull the LLM model (if using Ollama)

```bash
ollama pull llama3.1:8b
```

Or switch to Anthropic Claude in `config.yaml` (requires `ANTHROPIC_API_KEY` in `.env`).

### 4. Run

```bash
# Generate profile.yaml from a resume PDF
prospect init --resume path/to/resume.pdf

# Single search cycle
prospect search

# Search without LLM scoring (faster, no model needed)
prospect search --no-score

# Limit to first N queries (good for testing)
prospect search --limit 5

# Continuous daemon (searches every 30 min by default, fires immediately on start)
prospect daemon

# Launch Streamlit dashboard
prospect dashboard

# Wipe the database (asks for confirmation)
prospect clear-db

# Wipe without prompt (for scripts)
prospect clear-db --confirm
```

## Customisation

### Profile (`profile.yaml`)

All scoring is derived from your profile — no Python changes needed:

| Field | Effect on scoring |
|---|---|
| `target_roles` | Roles closely matching score higher |
| `skills` | Tech stack alignment affects score |
| `preferences.locations` | Location match boosts score |
| `seniority` | `junior` / `mid` / `senior` / `any` |
| `resume_summary` | Embedded in every LLM scoring prompt |

### Search queries (`config.yaml`)

Queries run verbatim through the Twitter/X search bar. Short, conversational phrases work best — write them how a person would type them, not like a job board listing.

Useful angles to cover:
- `"hiring ML engineer [city]"` — geographic targeting
- `"founding engineer AI remote"` — startup-stage signals
- `"we're looking for LLM engineer"` — informal hiring language
- `"[specific skill] engineer job"` — stack-first signals

### Switching LLM providers

Edit `config.yaml`:

```yaml
# Local (free, runs on your machine)
scoring:
  provider: "ollama"
  model: "llama3.1:8b"

# Cloud (better quality, costs money)
scoring:
  provider: "anthropic"
  model: "claude-haiku-4-5-20251001"
```

## Configuration Reference

### config.yaml

| Key | Default | Description |
|---|---|---|
| `search.queries` | `[]` | Seed search queries — **replace with your own** |
| `search.interval_minutes` | `30` | Daemon search interval |
| `search.use_generated_queries` | `true` | Expand seed queries via LLM (cached 24h) |
| `filters.min_followers` | `200` | Discard authors below this (reduces bots) |
| `filters.exclude_keywords` | list | Pre-LLM discard — saves API costs |
| `scoring.provider` | `ollama` | `ollama` or `anthropic` |
| `scoring.model` | `llama3.1:8b` | Model name |
| `scoring.auto_irrelevant_threshold` | `3` | Score below this → auto-marked irrelevant |
| `scoring.hot_lead_threshold` | `7` | Score above this → hot lead |
| `scoring.hard_disqualifiers` | list | Role types that always score low |

### profile.yaml

| Field | Description |
|---|---|
| `name` | Your name (included in scoring context) |
| `target_roles` | List of job titles you're targeting |
| `skills` | Your technical skills |
| `preferences.locations` | Cities/regions/`remote` you're open to |
| `preferences.remote_ok` | `true` / `false` |
| `seniority` | `junior` / `mid` / `senior` / `any` |
| `resume_summary` | 2-4 sentence background (verbatim in prompt) |

## Project Structure

```
src/prospect/
├── core/              # Search, parse, score logic
│   ├── searcher.py   # Twitter/X search via Playwright
│   ├── parser.py     # Extract job details from tweets
│   ├── scorer.py     # LLM-based relevance scoring
│   ├── llm.py        # Provider abstraction (Ollama / Anthropic)
│   └── query_generator.py  # LLM-generated query expansion (cached)
├── db/               # Database layer
│   ├── models.py     # SQLAlchemy ORM models
│   └── database.py   # Session management
├── cli/              # Command-line interface
│   └── commands.py   # Search, daemon, and clear-db logic
├── dashboard/        # Optional Streamlit UI
│   ├── app.py        # Home page with stats
│   └── pages/        # Feed, Contacts, Outreach pipeline, Settings
└── __main__.py       # CLI entry point
```

## Dashboard

Launch with `prospect dashboard`, then open `http://localhost:8501`.

| Page | Description |
|---|---|
| Home | Stats overview and score distribution |
| Feed | Review and action opportunities |
| Contacts | Manage contacts and outreach status |
| Outreach | Kanban pipeline (reviewed → contacted → applied) |
| Settings | Edit queries, run searches manually, manage database |

## Data & Security

- Credentials are stored only in `.env` (gitignored by default)
- `profile.yaml` and `config.yaml` are gitignored — create them from the `.example` files
- Twitter session cookies are stored in `data/cookies.json` with `600` permissions (owner-only)
- All data is stored locally in `data/prospect.db` (SQLite)
- The dashboard runs on `localhost` only — no external access
- Set `PROSPECT_HOME=/path/to/dir` to run the CLI from anywhere (data, config, and profile resolve relative to that path)

## Troubleshooting

**`profile.yaml not found` or `config.yaml not found`**
- Copy the `.example` files: `cp profile.yaml.example profile.yaml && cp config.yaml.example config.yaml`
- Run `prospect` from the directory containing those files, or set `PROSPECT_HOME`

**No tweets found**
- Verify your search queries in `config.yaml` are relevant to your role/location
- Make sure Twitter cookies are valid (re-run triggers auto-login)

**LLM scoring failing**
- Make sure Ollama is running: `ollama serve`
- Confirm the model is pulled: `ollama list`
- If >50% of tweets fail scoring, a warning is printed with the likely cause

**Daemon not running searches**
- Check logs — after 3 consecutive failures the daemon pauses and prints a clear message

## License

MIT
