/domain-expired-opportunity-finder
Evaluates expired domain candidates against a target niche, scores them by topical relevance, historical activity level, and history cleanliness, then outputs a ranked shortlist with explainable reasoning and risk flags.
$ npx -y skills add Varnan-Tech/opendirectory --skill domain-expired-opportunity-finder --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/domain-expired-opportunity-finder
Context preview
The summary Claude sees to decide when to auto-load this skill.
Evaluates expired domain candidates against a target niche, scores them by topical relevance, historical activity level, and history cleanliness, then outputs a ranked shortlist with explainable reasoning and risk flags.
SKILL.md
domain-expired-opportunity-finder.SKILL.mdname: domain-expired-opportunity-finder
description: Evaluates expired domain candidates against a target niche, scores them by topical relevance, historical activity level, and history cleanliness, then outputs a ranked shortlist with explainable reasoning and risk flags.
compatibility: [claude-code, gemini-cli, github-copilot]
author: ajaycodesitbetter
version: 1.0.0
Expired Domain Opportunity Finder
Evaluate expired domain candidates for a specific niche. Score them on topical fit, historical activity level, history cleanliness, and redirect suitability. Output a conservative, explainable shortlist for human review.
---
**Critical rule:** Every recommendation must include BOTH a positive rationale (`why_selected`) AND a caution rationale (`why_risky`). Never output a bare score without explanation.
**Conservative-by-default rule:** When signals are incomplete or contradictory, lower the confidence level. Do not surface ambiguous candidates as strong opportunities. Missing data reduces confidence, never inflates it.
**Anti-abuse rule:** Never encourage unrelated redirects, PBN construction, or domain repurposing where the historical topic does not match the target niche. Read `references/guardrails.md` for the full anti-abuse policy.
---
Step 1: Setup Check
Check the environment before doing anything else.
Verify that `curl` and `python3` (or `python`) are available:
curl --version > /dev/null 2>&1 && echo "curl: available" || echo "curl: MISSING"
python3 --version 2>/dev/null || python --version 2>/dev/null || echo "python: MISSING"
Check for an optional LLM API key for enhanced niche-relevance scoring:
echo "LLM_API_KEY: ${LLM_API_KEY:+set}"**If `curl` or `python` is missing:** Stop. Tell the user: "This skill requires curl and Python 3.10+. Please install them and try again."
**If `LLM_API_KEY` is not set:** Continue. The skill will use rule-based scoring only (domain string matching, Wayback title analysis, keyword overlap). Note to the user: "Running in rule-based-only mode. Set LLM_API_KEY for enhanced niche-relevance scoring."
**If `LLM_API_KEY` is set:** The skill will use LLM-enhanced scoring for topical relevance analysis. This provides deeper contextual assessment of niche fit.
QA: State the scoring mode (llm-enhanced or rule-based-only) and confirm tools are available.
---
Step 2: Input Collection
Collect the required and optional inputs from the user.
**Required:**
- `target_niche` (string): The core niche to evaluate against. Examples: "developer tools", "AI SaaS", "cybersecurity", "fintech".
**Optional (ask only if not provided):**
- `seed_keywords` (array): Keywords to refine topical matching. If not provided, extract 3–5 keywords from the niche name automatically.
- `candidate_domains` (array): Specific domains to evaluate. If not provided, prompt the user.
- `discovery_source` (string): Where candidates came from — `manual`, `expireddomains-net`, `external-feed`.
- `min_snapshots` (integer): Minimum historical snapshot threshold. Default: 10.
- `max_risk_level` (string): `low`, `medium`, or `high`. Controls how aggressively risky candidates are filtered. Default: `medium`.
- `intended_use` (string): `rebuild`, `redirect`, or `either`. Default: `either`.
**If no `candidate_domains` are provided:** Ask: "Please provide a list of expired domain candidates to evaluate. You can: 1. Paste domain names (one per line or comma-separated) 2. Provide a file path to a text file with one domain per line 3. Say 'example' to run with a built-in demo set for the 'developer tools' niche"
**If the user says 'example':** Use this demo set:
devtoolsweekly.com
codeshipnews.io
stackforgeapp.com
quickseorank.net
bestcheaphosting247.com
cloudbuildpro.dev
reactwidgetlib.com
megadealsshop.xyz
After collecting all inputs, confirm: "Target niche: [niche]. Evaluating [N] candidate domains. Scoring mode: [mode]. Intended use: [use]."
---
Step 3: Candidate Normalization
Clean and validate the candidate list before scoring.
python3 -c "
import sys, re
domains = '''CANDIDATE_LIST_HERE'''.strip().split('\n')
seen = set()
valid = []
invalid = []
for d in domains:
d = d.strip().lower()
# Strip protocols and paths
d = re.sub(r'^https?://', '', d)
d = d.split('/')[0]
d = d.strip('.')
if not d:
continue
# Basic TLD validation
if '.' not in d or len(d) < 4:
invalid.append(d)
continue
# Deduplicate
if d in seen:
continue
seen.add(d)
valid.append(d)
print(f'Valid candidates: {len(valid)}')
print(f'Removed (invalid/duplicate): {len(invalid)}')
for v in valid:
print(f' ✓ {v}')
for i in invalid:
print(f' ✗ {i} (invalid format)')
"Replace `CANDIDATE_LIST_HERE` with the actual domain list from Step 2.
State: "[N] valid candidates after normalization. [M] removed (invalid/duplicate)."
If 0 valid candidates remain, stop and tell the user: "No valid domain candidates found. Please provide domain names in the format 'example.com'."
---
Step 4: Signal Collection
For each valid candidate, collect signals from free public sources. Run these checks sequentially per domain.
4a: Wayback CDX API — History Snapshots
Query the Wayback Machine for all historical snapshots. We use `limit=100000` and explicit `from`/`to` parameters are intentionally omitted so that CDX returns snapshots from the full lifetime of the domain. The results are sorted ascending by timestamp (oldest first) so `first_capture` and `last_capture` are accurate:
curl -s "https://web.archive.org/cdx/search/cdx?url=DOMAIN_HERE&output=json&fl=timestamp,statuscode&collapse=timestamp:6&limit=100000" \
| python3 -c "
import sys, json
try:
data = json.load(sys.stdin)
if len(data) <= 1:
print(json.dumps({'domain': 'DOMAIN_HERE', 'snapshots': 0, 'first_capture': None, 'last_capture': None, 'status_codes': {}, 'years_active': 0}))
else:Read more
name: domain-expired-opportunity-finder description: Evaluates expired domain candidates against a target niche, scores them by topical relevance, historical activity level, and history cleanliness, then outputs a ranked shortlist with explainable reasoning and risk flags. compatibility: [claude-code, gemini-cli, github-copilot] author: ajaycodesitbetter version: 1.0.0
Expired Domain Opportunity Finder
Evaluate expired domain candidates for a specific niche. Score them on topical fit, historical activity level, history cleanliness, and redirect suitability. Output a conservative, explainable shortlist for human review.
---
**Critical rule:** Every recommendation must include BOTH a positive rationale (`why_selected`) AND a caution rationale (`why_risky`). Never output a bare score without explanation.
**Conservative-by-default rule:** When signals are incomplete or contradictory, lower the confidence level. Do not surface ambiguous candidates as strong opportunities. Missing data reduces confidence, never inflates it.
**Anti-abuse rule:** Never encourage unrelated redirects, PBN construction, or domain repurposing where the historical topic does not match the target niche. Read `references/guardrails.md` for the full anti-abuse policy.
---
Step 1: Setup Check
Check the environment before doing anything else.
Verify that `curl` and `python3` (or `python`) are available:
curl --version > /dev/null 2>&1 && echo "curl: available" || echo "curl: MISSING" python3 --version 2>/dev/null || python --version 2>/dev/null || echo "python: MISSING"
Check for an optional LLM API key for enhanced niche-relevance scoring:
echo "LLM_API_KEY: ${LLM_API_KEY:+set}"**If `curl` or `python` is missing:** Stop. Tell the user: "This skill requires curl and Python 3.10+. Please install them and try again."
**If `LLM_API_KEY` is not set:** Continue. The skill will use rule-based scoring only (domain string matching, Wayback title analysis, keyword overlap). Note to the user: "Running in rule-based-only mode. Set LLM_API_KEY for enhanced niche-relevance scoring."
**If `LLM_API_KEY` is set:** The skill will use LLM-enhanced scoring for topical relevance analysis. This provides deeper contextual assessment of niche fit.
QA: State the scoring mode (llm-enhanced or rule-based-only) and confirm tools are available.
---
Step 2: Input Collection
Collect the required and optional inputs from the user.
**Required:**
- `target_niche` (string): The core niche to evaluate against. Examples: "developer tools", "AI SaaS", "cybersecurity", "fintech".
**Optional (ask only if not provided):**
- `seed_keywords` (array): Keywords to refine topical matching. If not provided, extract 3–5 keywords from the niche name automatically.
- `candidate_domains` (array): Specific domains to evaluate. If not provided, prompt the user.
- `discovery_source` (string): Where candidates came from — `manual`, `expireddomains-net`, `external-feed`.
- `min_snapshots` (integer): Minimum historical snapshot threshold. Default: 10.
- `max_risk_level` (string): `low`, `medium`, or `high`. Controls how aggressively risky candidates are filtered. Default: `medium`.
- `intended_use` (string): `rebuild`, `redirect`, or `either`. Default: `either`.
**If no `candidate_domains` are provided:** Ask: "Please provide a list of expired domain candidates to evaluate. You can: 1. Paste domain names (one per line or comma-separated) 2. Provide a file path to a text file with one domain per line 3. Say 'example' to run with a built-in demo set for the 'developer tools' niche"
**If the user says 'example':** Use this demo set:
devtoolsweekly.com codeshipnews.io stackforgeapp.com quickseorank.net bestcheaphosting247.com cloudbuildpro.dev reactwidgetlib.com megadealsshop.xyz
After collecting all inputs, confirm: "Target niche: [niche]. Evaluating [N] candidate domains. Scoring mode: [mode]. Intended use: [use]."
---
Step 3: Candidate Normalization
Clean and validate the candidate list before scoring.
python3 -c "
import sys, re
domains = '''CANDIDATE_LIST_HERE'''.strip().split('\n')
seen = set()
valid = []
invalid = []
for d in domains:
d = d.strip().lower()
# Strip protocols and paths
d = re.sub(r'^https?://', '', d)
d = d.split('/')[0]
d = d.strip('.')
if not d:
continue
# Basic TLD validation
if '.' not in d or len(d) < 4:
invalid.append(d)
continue
# Deduplicate
if d in seen:
continue
seen.add(d)
valid.append(d)
print(f'Valid candidates: {len(valid)}')
print(f'Removed (invalid/duplicate): {len(invalid)}')
for v in valid:
print(f' ✓ {v}')
for i in invalid:
print(f' ✗ {i} (invalid format)')
"Replace `CANDIDATE_LIST_HERE` with the actual domain list from Step 2.
State: "[N] valid candidates after normalization. [M] removed (invalid/duplicate)."
If 0 valid candidates remain, stop and tell the user: "No valid domain candidates found. Please provide domain names in the format 'example.com'."
---
Step 4: Signal Collection
For each valid candidate, collect signals from free public sources. Run these checks sequentially per domain.
4a: Wayback CDX API — History Snapshots
Query the Wayback Machine for all historical snapshots. We use `limit=100000` and explicit `from`/`to` parameters are intentionally omitted so that CDX returns snapshots from the full lifetime of the domain. The results are sorted ascending by timestamp (oldest first) so `first_capture` and `last_capture` are accurate:
curl -s "https://web.archive.org/cdx/search/cdx?url=DOMAIN_HERE&output=json&fl=timestamp,statuscode&collapse=timestamp:6&limit=100000" \
| python3 -c "
import sys, json
try:
data = json.load(sys.stdin)
if len(data) <= 1:
print(json.dumps({'domain': 'DOMAIN_HERE', 'snapshots': 0, 'first_capture': None, 'last_capture': None, 'status_codes': {}, 'years_active': 0}))
else:AI Agent Skills built for Founders who hate Marketing
Repo: Varnan-Tech/opendirectory
Other skills on opendirectory-gtm-skills.
- /app-store-review-arbitrage
Fetches low-star App Store and Google Play reviews, clusters them into broken-promise patterns, and generates a ranked copy brief with positioning opportunities.
Open skill - /blog-cover-image-cli
Use when the user asks to generate a blog cover image, thumbnail, or article header. Automatically uses modern typography, brand logos, and Google Search grounding to create beautiful 16:9 images with Gemini 3.1 Flash Image Preview.
Open skill - /brand-alchemy
World-class brand strategist and naming expert. Uses an interrogation-led discovery phase to extract your brand's DNA, then applies scientific naming frameworks (Phonosemantics) and automated multi-TLD domain checking.
Open skill - /claude-md-generator
Use when the user asks to generate or update a project's CLAUDE or AGENTS context file from a codebase scan. Writes a focused file under 100 lines containing only the non-obvious build commands, conventions, and gotchas Claude Code needs.
Open skill - /cold-email-verifier
Use when the user wants to verify cold emails, enrich a lead list, or autonomously guess email addresses from a CSV using ValidEmail.co or the open-source Reacher engine.
Open skill - /company-radar
Competitive intelligence orchestrator tracking companies across 8+ platforms (GitHub, Twitter, Reddit, HN, PH, YC Jobs) with heat scores and AI briefings.
Open skill

