deal-finder
$
npx mdskill add sonichi/sutando/deal-finderScans Craigslist for used Mac Minis matching specific criteria.
- Finds second-hand computers fitting budget and location limits.
- Uses Craigslist search with custom user-agent headers.
- Filters results by chip model, RAM, storage, and price.
- Sends SMS and Telegram messages when matches appear.
SKILL.md
.github/skills/deal-finderView on GitHub ↗
---
name: deal-finder
description: Scan configured sources (Craigslist now; eBay + Facebook Marketplace planned) for used-item listings matching the owner's criteria. Currently configured for a Mac mini search (M2+, 16GB+, 512GB+, ≤$500, near 94566). Notify owner via SMS + Telegram on a match.
user-invocable: true
---
# Deal Finder
Watches configured sources for second-hand item listings matching owner-defined criteria. Sends an SMS + Telegram DM when a new matching listing appears.
**Usage**: `/deal-finder` (one-shot scan) — typically run from cron every 60 min.
## Searches
V1 keeps the original Mac Mini search inline (`state/criteria.json`). V2 will move this to a `state/searches.json` array with one entry per search, so adding "Pelican 1535 case", "Aeron chair size B", etc. becomes a JSON edit rather than a code change.
Current Mac Mini search criteria (from `state/criteria.json`):
- Chip family: `M2`, `M3`, `M4` (M1 explicitly excluded — owner asked for M2+)
- Min RAM: `16 GB`
- Min storage: `512 GB`
- Max price: `$500`
- ZIP: `94566` (Pleasanton, CA), search radius `50 mi`
Edit `state/criteria.json` to retune the Mac Mini search; v2 will lift this into a per-search config.
## Sources
V1 (implemented): **Craigslist** (`sfbay.craigslist.org/search/sss?...`). Uses an honest User-Agent (`Sutando-Personal-Agent/1.0`) that identifies the agent rather than cosplaying a browser — Craigslist can decide whether to allow.
V2 (planned, not yet implemented):
- **eBay** — `browse.ebay.com` has a local-pickup filter; HTML scraping works without auth.
- **Facebook Marketplace** — requires a headless browser (Playwright via the `macos-use` skill, or the browser-automation MCP) because the page is JS-rendered and gated.
## Behavior
1. Fetch the Craigslist search results page with the honest UA.
2. Parse each listing: title, URL, price, neighborhood.
3. For each listing not in `state/seen.json`:
- Fetch the listing detail page (one extra HTTP req per listing — cheap, only on first sight).
- Apply criteria filter (chip, RAM, storage, price). Listings missing fields fall through to "soft match" — flagged but still notified, since Craigslist sellers often omit specs.
- On match: notify (SMS + Telegram), record URL in `seen.json`.
4. Trim `seen.json` deterministically to the last 1000 entries (a `deque(maxlen=1000)` ordered by insertion — replaces the prior set-slicing trim which was non-deterministic).
## Notification format
```
[Mac Mini Deal] $480 — M2 / 16GB / 512GB
Concord (35mi, local pickup)
Posted recent
https://sfbay.craigslist.org/...
```
SMS goes via `TWILIO_*` env vars to `OWNER_NUMBER`. Telegram goes via `results/proactive-deal-finder-{ts}.txt` (the bridge picks it up).
## Run it
```bash
python3 scripts/scan.py # one-shot scan with default criteria
python3 scripts/scan.py --dry-run # don't notify, print what would notify
python3 scripts/scan.py --reset # clear seen.json (force re-notify everything)
```
Cron: every 60 min. Configured in `skills/schedule-crons/crons.json` as `deal-finder`.
More from sonichi/sutando
- agent-registryLocal Agent Registry — a standalone, dependency-free service that tracks running Claude Code (and other) agent instances. Agents self-register on startup and heartbeat while alive; the Electron overlay and Sutando dashboard read the live list. Use when you need to know which coding agents are running, where, and since when.
- bot2bot-postPost a coordination message from this bot to the shared bot2bot channel, @-mentioning the other Sutando node.
- claude-codexBash wrapper around the local Codex CLI for non-interactive runs from inside Sutando (bridges, cron, scripts). For interactive code review or task hand-off from this Claude Code session, prefer the official `/codex:*` plugin commands; this skill is the file-bridge-compatible path that `discord-bridge.py` invokes for team-tier sandboxed delegation.
- claude-geminiUse the local Gemini CLI from Claude Code with the user's existing Gemini authentication or API configuration. Use for large-context repo scans, multimodal analysis, second-opinion planning, or structured Gemini runs in the current workspace.
- claude-routerChoose between the local Codex CLI and Gemini CLI from Claude Code. Use for automatic model selection when the user wants the best local delegate for code review, repo-wide analysis, planning, or implementation.
- cross-node-syncRsync-over-ssh sync between Sutando nodes (Mac Studio and MacBook) for shared memory + notes. Optional — core runs fine without it; enables automatic cross-bot learning and note propagation by running from the proactive-loop cron on each pass.
- electron-overlay-dimmingReusable pattern for focus-based auto-dimming of Electron overlay windows — when the app loses focus, all overlay windows fade to a low opacity; when an overlay regains focus, they return to their configured opacity. Use when building always-on-top Electron overlays that should recede while the user works in other apps.
- gemini-ttsRender text to mp3 via Google Gemini Flash TTS. Free-tier eligible (1500 req/day). Use for video narration, demo voiceovers, audio notes. Parallels openai-tts; default for make-viral-video.
- macos-toolsmacOS native integrations: screen capture, calendar, reminders, contacts, email (Mail.app), Spotlight search. Use when the user asks about their screen, schedule, to-do list, contacts, or wants to send email on macOS.
- macos-useGUI control for macOS apps via mediar-ai's mcp-server-macos-use. Click, type, scroll, key-press, open apps — driven by accessibility tree, works in non-interactive Claude Code mode. Use this for any Sutando task that needs to drive another macOS application (Safari, Zoom, Mail, Finder, etc.).