Communitygithub.com

Varnan-Tech/opendirectory

Forneça a URL ou descrição do seu produto. Ele encontra seus 5 principais concorrentes, realiza uma pesquisa de RP em três frentes (editorial, podcasts, comunidades), identifica quais canais aparecem com mais frequência, localiza o jornalista ou apresentador de cada um e retorna uma lista de divulgação hierarquizada com ângulos de história e rascunhos de pitches frios prontos para envio, adaptados ao seu produto.

O que é opendirectory?

Este skill, chamado 'Competitor PR Finder', automatiza a descoberta de oportunidades de relações públicas (RP) para startups e produtos. Ao receber a URL ou uma descrição do produto, ele realiza uma análise completa da concorrência. Primeiro, ele descobre os 5 principais concorrentes e, em seguida, para cada um deles, pesquisa em três frentes: editorial (grandes publicações como TechCrunch e Forbes), podcasts e comunidades online (como Reddit e Hacker News). O skill identifica os canais de RP que aparecem com mais frequência entre os concorrentes, classificando-os em níveis (Tier 1, 2 e 3) com base na frequência de ocorrência. Para cada canal de nível superior, ele localiza o jornalista ou apresentador específico, extrai ângulos de história dos títulos de artigos/episódios e gera rascunhos de pitches frios personalizados, sempre com base em evidências reais das pesquisas, sem alucinações. É ideal para founders, profissionais de marketing e growth hackers que desejam construir uma lista de divulgação para a imprensa de forma estratégica e baseada em dados. O skill é executado em um ambiente de linha de comando (CLI) e utiliza APIs como Tavily e Firecrawl para coleta de dados.

Funciona com✓Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/Varnan-Tech/opendirectory/tree/main/skills/competitor-pr-finder

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Encontrador de RP de Concorrentes

Forneça a URL do seu produto. Ele encontra seus concorrentes, pesquisa todos os canais de RP que eles usaram (notícias, podcasts, comunidades), revela os canais que aparecem em vários concorrentes (seus alvos comprovados), encontra o jornalista ou apresentador de cada um e elabora um pitch frio personalizado para o seu produto em cada canal de nível 1.


Política de zero alucinação: Cada canal, nome de jornalista, ângulo de história e detalhe do pitch na saída deve ser rastreável até um resultado de pesquisa específico do Tavily ou a página do produto buscada. Isso se aplica a:

  • Nomes de concorrentes: devem aparecer nos resultados de pesquisa do Tavily, não no conhecimento de treinamento da IA
  • Nomes de canais: devem ter uma URL nos resultados de pesquisa
  • Nomes de jornalistas/apresentadores: devem aparecer textualmente em um snippet do Tavily
  • Ângulos de história: extraídos apenas de títulos de artigos/episódios nos resultados de pesquisa
  • Rascunhos de pitches: referenciam evidências específicas dos dados de pesquisa + análise do produto

Erros Comuns

O agente vai querer...Por que isso está errado
Nomear um jornalista a partir do conhecimento de treinamentoCada nome de jornalista deve ser rastreável a um snippet de resultado de pesquisa. Escrever "Sarah Perez cobre startups no TechCrunch" de memória é alucinação.
Listar canais sem URLs de evidênciaCada canal na saída deve ter pelo menos uma URL dos resultados da pesquisa de RP comprovando que um concorrente foi apresentado lá.
Pular a etapa de confirmação do concorrenteSempre mostre os concorrentes descobertos e aguarde a confirmação do usuário. Concorrentes errados = pesquisas desperdiçadas e uma saída inútil.
Gerar pitches genéricos ("Adoraríamos ser apresentados")Cada pitch deve referenciar um ângulo específico da evidência E um diferenciador específico da análise do produto.
Marcar um canal como Nível 1 com apenas 1 ocorrência de concorrenteNível 1 = 3+ concorrentes. Nível 2 = exatamente 2. Nível 3 = 1. Não promova canais que não se provaram.
Usar travessões na saídaSubstitua todos os travessões (—) por hífens (-).

Leia os Arquivos de Referência Antes de Cada Execução

cat references/pr-channel-types.md
cat references/pitch-guide.md
cat references/tier-scoring.md

Etapa 1: Verificação de Configuração

echo "TAVILY_API_KEY:    ${TAVILY_API_KEY:+set}${TAVILY_API_KEY:-NÃO DEFINIDA -- obrigatório}"
echo "FIRECRAWL_API_KEY: ${FIRECRAWL_API_KEY:+set}${FIRECRAWL_API_KEY:-não definida, o Tavily extract será usado como fallback}"

Se TAVILY_API_KEY estiver faltando: Pare imediatamente. Diga ao usuário: "TAVILY_API_KEY é necessária para pesquisar concorrentes e encontrar cobertura de RP. Não há fallback. Obtenha-a em app.tavily.com -- nível gratuito: 1000 créditos/mês (cerca de 43 execuções completas a ~23 pesquisas/execução). Adicione-a ao seu arquivo .env."

Se apenas FIRECRAWL_API_KEY estiver faltando: Continue. O Tavily extract será usado para a busca da URL.


Etapa 2: Analisar Entrada

Colete da conversa:

  • product_url: a URL para buscar (obrigatório, a menos que o usuário cole uma descrição diretamente)
  • product_name: opcional, derivado da página se não fornecido
  • geography: opcional -- EUA / Europa / global. Padrão: EUA

Se o usuário fornecer apenas uma descrição colada (sem URL): Pule as Etapas 3 e 4. Vá diretamente para a Etapa 4 (análise do produto) usando o texto colado como product_content. Defina page_source como user_description e anote em data_quality_flags.

Se nem URL nem descrição: Pergunte: "Qual é a URL do seu produto ou startup? Ou cole uma breve descrição: o que faz, para quem é e o que o diferencia dos concorrentes."

Derive o slug do produto:

PRODUCT_SLUG=$(python3 -c "
from urllib.parse import urlparse
import sys
url = 'URL_AQUI'
if url.startswith('http'):
    host = urlparse(url).netloc.replace('www.', '')
    print(host.split('.')[0])
else:
    import re
    print(re.sub(r'[^a-z0-9]', '-', url[:30].lower()).strip('-'))
")
echo "Slug do produto: $PRODUCT_SLUG"

Etapa 3: Buscar Página do Produto

Principal: Firecrawl (se FIRECRAWL_API_KEY estiver definida)

curl -s -X POST https://api.firecrawl.dev/v1/scrape \
  -H "Authorization: Bearer $FIRECRAWL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "URL_AQUI", "formats": ["markdown"], "onlyMainContent": true}' \
  | python3 -c "
import sys, json
d = json.load(sys.stdin)
content = d.get('data', {}).get('markdown', '') or d.get('markdown', '')
print(f'Buscado via Firecrawl: {len(content)} caracteres')
open('/tmp/cprf-product-raw.md', 'w').write(content)
"

Fallback: Tavily extract (se FIRECRAWL_API_KEY não estiver definida)

curl -s -X POST https://api.tavily.com/extract \
  -H "Content-Type: application/json" \
  -d "{\"api_key\": \"$TAVILY_API_KEY\", \"urls\": [\"URL_AQUI\"]}" \
  | python3 -c "
import sys, json
d = json.load(sys.stdin)
content = d.get('results', [{}])[0].get('raw_content', '')
print(f'Buscado via Tavily extract: {len(content)} caracteres')
open('/tmp/cprf-product-raw.md', 'w').write(content)
"

Ponto de verificação:

python3 -c "
content = open('/tmp/cprf-product-raw.md').read()
if len(content) < 200:
    print('ERRO: menos de 200 caracteres buscados')
else:
    print(f'Conteúdo OK: {len(content)} caracteres')
"

Se o conteúdo < 200 caracteres: Pare a busca. Diga ao usuário: "A página do produto não retornou conteúdo legível -- o site provavelmente é renderizado por JavaScript e bloqueou a busca. Cole uma breve descrição diretamente: o que faz, para quem é e o que o diferencia."


Etapa 4: Análise do Produto (IA)

Imprimir o conteúdo da página:

python3 -c "
content = open('/tmp/cprf-product-raw.md').read()[:5000]
print('=== PÁGINA DO PRODUTO (primeiros 5000 caracteres) ===')
print(content)
"

Instruções de IA: Analise a página do produto acima e extraia:

  • product_name: o nome do produto ou empresa
  • one_line_description: o que faz, para quem, proposta de valor principal. Menos de 20 palavras. Sem linguagem de marketing. Exemplo: "Automação de CI/CD para equipes de desenvolvedores que auto-hospedam seus pipelines."
  • industry_taxonomy: l1 (nível superior: ex. ferramentas de desenvolvedor / fintech / healthtech / consumidor), l2 (setor: ex. devops / pagamentos / telemedicina), l3 (nicho específico: ex. automação de CI/CD / pagamentos incorporados / consulta por vídeo assíncrona). Rótulos vagos como "tecnologia" sozinhos não são aceitáveis.
  • differentiators: exatamente 2-3 coisas específicas que distinguem este produto de concorrentes genéricos. Eles alimentam diretamente os rascunhos de pitches -- seja específico. Exemplo: ["Runner de pipeline auto-hospedado -- nenhum dado sai da sua infraestrutura", "Suporte nativo para monorepos com geração dinâmica de etapas"]
  • icp: buyer_persona (cargo), company_type, company_size
  • geography_bias: EUA / Europa / global / não claro
  • page_source: "live_page" ou "user_description"

Escreva em /tmp/cprf-product-analysis.json:

python3 << 'PYEOF'
import json

analysis = {
    # PREENCHA a partir de sua análise acima
    "product_name": "",
    "one_line_description": "",
    "industry_taxonomy": {"l1": "", "l2": "", "l3": ""},
    "differentiators": [],
    "icp": {"buyer_persona": "", "company_type": "", "company_size": ""},
    "geography_bias": "EUA",
    "page_source": "live_page"
}

json.dump(analysis, open('/tmp/cprf-product-analysis.json', 'w'), indent=2)
print('Análise do produto escrita.')
PYEOF

Verifique:

python3 -c "
import json
a = json.load(open('/tmp/cprf-product-analysis.json'))
print('Produto:', a['product_name'])
print('Indústria:', a['industry_taxonomy']['l1'], '>', a['industry_taxonomy']['l2'], '>', a['industry_taxonomy']['l3'])
print('Diferenciadores:')
for d in a['differentiators']:
    print(f'  - {d}')
"

Etapa 4b: Fase 1 -- Descoberta de Concorrentes

ls scripts/research.py 2>/dev/null && echo "script encontrado" || echo "ERRO: scripts/research.py não encontrado -- não é possível continuar"
python3 scripts/research.py \
  --phase discover \
  --product-analysis /tmp/cprf-product-analysis.json \
  --tavily-key "$TAVILY_API_KEY" \
  --output /tmp/cprf-competitors-raw.json

Imprima os resultados para revisão da IA:

python3 -c "
import json
data = json.load(open('/tmp/cprf-competitors-raw.json'))
print(f'Pesquisas executadas: {len(data[\"competitor_searches\"])}')
for s in data['competitor_searches']:
    print(f'\nConsulta: {s[\"query\"]}')
    print(f'Resposta: {s.get(\"answer\",\"\")[:400]}')
    for r in s.get('results', [])[:5]:
        print(f'  - {r[\"title\"]} | {r[\"url\"]}')
        print(f'    {r.get(\"content\",\"\")[:200]}')
"

Instruções de IA: Leia os resultados de pesquisa acima. Escolha exatamente 5 empresas concorrentes que:

  1. Estejam nomeadas nos títulos, respostas ou snippets dos resultados de pesquisa
  2. Estejam no mesmo nicho L3 que o produto que está sendo analisado
  3. Sejam produtos concorrentes reais (não agências, consultorias ou artigos de lista)
  4. Sejam distintas umas das outras (não a mesma empresa sob nomes diferentes)

Para cada concorrente, escreva: name, url (do resultado de pesquisa onde apareceu), description (uma frase do snippet), source_url (a URL do resultado de pesquisa onde foram encontrados).


Etapa 5: Confirmação do Concorrente

Mostre os concorrentes descobertos ao usuário:

python3 << 'PYEOF'
import json

analysis = json.load(open('/tmp/cprf-product-analysis.json'))

# PREENCHA: 5 concorrentes dos resultados de pesquisa acima
candidates = [
    # {"name": str, "url": str, "description": str, "source_url": str}
]

print(f"\nEncontrados 5 concorrentes para {analysis['product_name']} em {analysis['industry_taxonomy']['l3']}:\n")
for i, c in enumerate(candidates, 1):
    print(f"  {i}. {c['name']} -- {c['description']}")
    print(f"     {c['url']}")

data = json.load(open('/tmp/cprf-competitors-raw.json'))
data['competitor_candidates'] = candidates
json.dump(data, open('/tmp/cprf-competitors-raw.json', 'w'), indent=2)
PYEOF

Diga ao usuário: "Estes são os 5 concorrentes que pesquisarei para cobertura de RP. Adicione, remova ou troque qualquer um -- ou diga 'parece bom' para continuar."

Aguarde a confirmação. Se o usuário editar a lista (adicionar/remover/trocar), atualize os candidatos de acordo. Em seguida, escreva a lista confirmada:

python3 << 'PYEOF'
import json

# PREENCHA: lista de concorrentes confirmada (após revisão do usuário)
confirmed = [
    # {"name": str, "url": str}
]

json.dump({"confirmed_competitors": confirmed}, open('/tmp/cprf-competitors-confirmed.json', 'w'), indent=2)
print(f"Confirmados {len(confirmed)} concorrentes para pesquisa de RP.")
for c in confirmed:
    print(f"  - {c['name']} ({c['url']})")
PYEOF

Etapa 6: Pesquisa de RP em Três Frentes (Fase 2)

python3 scripts/research.py \
  --phase pr-research \
  --competitors /tmp/cprf-competitors-confirmed.json \
  --product-analysis /tmp/cprf-product-analysis.json \
  --tavily-key "$TAVILY_API_KEY" \
  --output /tmp/cprf-pr-raw.json

Isso executa 3 pesquisas por concorrente (15 no total):

  • Trilha A (Editorial): "[concorrente]" featured press coverage TechCrunch Forbes Wired article interview
  • Trilha B (Podcasts): "[concorrente]" founder CEO podcast interview appeared on episode
  • Trilha C (Comunidades): "[concorrente]" site:reddit.com OR site:news.ycombinator.com OR site:producthunt.com

Imprima o resumo da cobertura:

python3 -c "
import json
data = json.load(open('/tmp/cprf-pr-raw.json'))
print(f'Concorrentes pesquisados: {data[\"competitors_researched\"]}')
print()
for r in data['results']:
    print(f'{r[\"competitor\"]}:')
    for track, tdata in r['tracks'].items():
        n = len(tdata.get('results', []))
        print(f'  {track:12}: {n} resultados')
"

Se todas as 3 trilhas para um concorrente retornarem 0 resultados: Este concorrente tem cobertura de imprensa muito baixa. Anote em data_quality_flags e prossiga -- o padrão entre concorrentes ainda funcionará com os 4 restantes.


Etapa 7: Análise de Padrões (IA)

Imprima todos os resultados brutos de RP:

python3 -c "
import json
data = json.load(open('/tmp/cprf-pr-raw.json'))
for r in data['results']:
    print(f'\n=== {r[\"competitor\"]} ===')
    for track, tdata in r['tracks'].items():
        print(f'\n--- Trilha {track.upper()} ---')
        print(f'Consulta: {tdata[\"query\"]}')
        print(f'Resposta: {tdata.get(\"answer\",\"\")[:400]}')
        for item in tdata.get('results', [])[:5]:
            print(f'  Título: {item[\"title\"]}')
            print(f'  URL:   {item[\"url\"]}')
            print(f'  Snippet: {item.get(\"content\",\"\")[:200]}')
"

Instruções de IA: Leia TODOS os resultados de pesquisa acima. Construa um mapa de frequência de canais.

Passo 1 -- Normalizar URLs para domínio raiz: https://techcrunch.com/2023/06/article-title → techcrunch.com. https://open.spotify.com/episode/... → identificar como podcast (episódio do spotify). https://www.reddit.com/r/devops/ → reddit.com/r/devops.

Passo 2 -- Contar ocorrências: Quantos concorrentes diferentes apareceram nos resultados de cada canal raiz? Um canal que aparece nas Trilhas A do Concorrente A E nas Trilhas A do Concorrente B conta como frequência 2.

Passo 3 -- Hierarquizar canais (siga references/tier-scoring.md):

  • Nível 1: apareceu em 3+ concorrentes
  • Nível 2: apareceu em exatamente 2 concorrentes
  • Nível 3: apareceu em 1 concorrente

Passo 4 -- Extrair ângulos de história dos títulos de artigos/episódios nos resultados. Classifique cada um como: anúncio-de-financiamento / lançamento-de-produto / história-do-fundador / artigo-de-tendência / criação-de-categoria / tutorial / comparação / prêmio. Não infira -- apenas classifique ângulos visíveis nos títulos.

Passo 5 -- Classificar tipo de canal para cada um: editorial / podcast / comunidade / newsletter.

Escreva em /tmp/cprf-pr-patterns.json:

python3 << 'PYEOF'
import json

patterns = {
    "tier_1_channels": [
        # PREENCHA -- canais que aparecem em 3+ concorrentes
        # Cada: {"channel_name": str, "channel_url": str, "channel_type": str,
        #        "frequency": int, "found_in_competitors": [str],
        #        "evidence_urls": [str], "story_angles_used": [str],
        #        "journalist_name": "", "journalist_beat": ""}
    ],
    "tier_2_channels": [
        # PREENCHA -- canais que aparecem em exatamente 2 concorrentes
        # Cada: {"channel_name": str, "channel_url": str, "channel_type": str,
        #        "frequency": int, "found_in_competitors": [str],
        #        "evidence_urls": [str], "story_angles_used": [str],
        #        "journalist_name": "", "journalist_beat": ""}
    ],
    "tier_3_channels": [
        # PREENCHA -- canais que aparecem em 1 concorrente
        # Cada: {"channel_name": str, "channel_url": str, "channel_type": str,
        #        "frequency": int, "found_in_competitors": [str],
        #        "evidence_urls": [str], "story_angles_used": [str],
        #        "journalist_name": "", "journalist_beat": ""}
    ],
    "data_quality_flags": []
}

json.dump(patterns, open('/tmp/cprf-pr-patterns.json', 'w'), indent=2)
print('Padrões de PR escritos.')
PYEOF

...

A saída foi truncada, mas o fluxo continua para gerar a lista de divulgação final e os rascunhos de pitch.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

Varnan-Tech/opendirectory

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.

Varnan-Tech/opendirectory

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.

Varnan-Tech/opendirectory

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.

Varnan-Tech/opendirectory

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.

Varnan-Tech/opendirectory

Competitive intelligence orchestrator tracking companies across 8+ platforms (GitHub, Twitter, Reddit, HN, PH, YC Jobs) with heat scores and AI briefings.

Varnan-Tech/opendirectory

Generate high-converting, deep-dive growth case studies in MDX format. Use this skill when asked to write a case study or blog post about a company's growth, tech stack, or product-led strategy. It handles the full pipeline (researching the company via Tavily, generating a 16:9 cover image, quality checking the draft, uploading assets to cloud storage, and pushing directly to the target repository).

Varnan-Tech/opendirectory

Scans your project for outdated npm, pip, Cargo, Go, or Ruby packages. Runs a CVE security audit. Fetches changelogs, summarizes breaking changes with Gemini, and opens one PR per risk group (patch, minor, major). Includes Diagnosis Mode for install conflicts. Use when asked to update dependencies, check for outdated packages, open dependency PRs, scan for package updates, audit for CVEs, or flag breaking changes in upgrades. Trigger when a user says "check for outdated packages", "update my dependencies", "open PRs for dependency updates", "scan for CVEs", or "which packages need upgrading".

Varnan-Tech/opendirectory

Generates and updates README.md and API reference docs by reading your codebase's functions, routes, types, schemas, and architecture. Uses graphify to build a knowledge graph first, then writes accurate docs from it. Use when asked to write docs, generate a README, document an API, update stale docs, create an API reference from code, add an architecture section, or document a project in any language. Trigger when a user says their docs are missing, outdated, or wants to document their codebase without writing it manually.

Varnan-Tech/opendirectory

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.

Varnan-Tech/opendirectory

Brutally honest developer-experience audit for a GitHub repo. Scores 10 DX dimensions (time-to-first-success, README clarity, visual proof, install, quick-start, docs, examples, community, trust, marketing), writes a shareable roast in the requested tone (brutal/honest/kind), produces a prioritized action plan ranked by impact × effort, and sketches an ideal README. Trigger when user says "roast my repo", "audit my README", "dx audit", "developer experience review", "score my GitHub project", "before launch checklist", or "make my repo shareable".

Varnan-Tech/opendirectory

Drafts and designs a complete HTML email newsletter from a topic or content brief. Outputs paste-ready HTML for Loops, Mailchimp, Beehiiv, Resend, or any standard email platform. Includes subject line options and plain-text fallback. Trigger when a user says "write a newsletter", "draft an email newsletter", "create an HTML email", "design an email for my subscribers", or "write a newsletter about [topic]".

Varnan-Tech/opendirectory

Takes a GitHub PR URL or the current branch and writes a plain-English explanation of what it does and why, then posts it as a PR comment. Use when asked to explain a PR, summarize a pull request, write a plain-English description of a PR, add a summary comment to a PR, or understand what a PR changes. Trigger when a user says "explain this PR", "summarize this pull request", "what does this PR do", "add a comment explaining the PR", or shares a GitHub PR URL and asks what it does.

Varnan-Tech/opendirectory

Audit how often LLMs recommend your brand vs competitors and generate a GEO action plan.

Varnan-Tech/opendirectory

Takes a competitor's public GitHub repo URL, fetches their open issues via the GitHub REST API, filters noise locally, clusters issues into 6 demand categories, computes a demand score per issue and per cluster, and outputs a ranked demand gap report with a GTM messaging brief. Use when asked to scan a competitor's GitHub issues, find what their users are begging for, turn GitHub complaints into product positioning, identify competitor feature gaps, or generate messaging from real user demand. Trigger when a user says "scan competitor issues", "what are users asking for on X repo", "find demand gaps in Y", "turn GitHub issues into messaging", or "what should I build based on competitor complaints".

Varnan-Tech/opendirectory

Find recurring confusion in your repo's GitHub Discussions, rank it by urgency, and draft the actual docs fixes and content angles — with verbatim community quotes and source links as evidence.

Varnan-Tech/opendirectory

SEO keyword research workflow for blog generation using Google Trends data. Use when writing blog posts, planning content calendars, or optimizing articles for search engines. Finds breakout keywords, builds content structure, and generates SEO-optimized blog outlines targeting tech and developer audiences.

Varnan-Tech/opendirectory

Generates a professionally designed case study PDF for B2B SaaS sales and marketing. Supports 7 page layouts, 9 style presets, 1-4 page output. Trigger when user says "create a case study", "write a customer story", "make a case study PDF", "design a success story", "turn this customer win into a PDF".

Varnan-Tech/opendirectory

Generates data visualization charts (bar, line, area, pie, doughnut, scatter, radar, treemap) as PNG using Apache ECharts v6. 1080×1080px default, 5 style presets, highlight annotations. Trigger when user says "create a chart", "visualize data", "make a bar chart", "line graph", "pie chart", "data visualization", "chart this data", "plot", "graph", or "visualize these numbers".

Varnan-Tech/opendirectory

Creates professionally designed B2B SaaS e-books in HTML + CSS, exported as print-ready PDF. 3–10 pages, 9 style presets, 11 page layout types. Trigger when user says "create an ebook", "design a lead magnet", "make a PDF guide", "build a gated content piece", "write a B2B ebook", "design a white paper", "create a nurture asset", or "make a PDF report".

Varnan-Tech/opendirectory

Fetches low-star App Store and Google Play reviews, clusters them into broken-promise patterns, and generates a ranked copy brief with positioning opportunities.

Habilidades Relacionadas