CommunityEscrita e Ediçãogithub.com

Varnan-Tech/opendirectory

Informe a skill sobre o que seu produto lançou. Ela escreve uma entrada datada e refinada em um changelog vivo em 'docs/changelog.md' e produz um pacote de conteúdo pronto para uso: thread de tweets, post no LinkedIn, trecho de e-mail e uma frase de efeito.

O que é opendirectory?

Esta skill do agente de IA é especializada em automatizar o processo de registro de lançamentos de produtos e gerar conteúdo de marketing. Quando você descreve o que foi lançado, a skill cria uma entrada polida e datada em um arquivo `docs/changelog.md` (mantendo um histórico vivo, com a entrada mais recente no topo) e, simultaneamente, produz um pacote de conteúdo completo: uma frase de efeito, uma thread de tweets (3-5 tweets com menos de 280 caracteres cada), um post para o LinkedIn (sem hashtags ou markdown) e um trecho de e-mail (assunto e corpo). A skill é extremamente flexível em relação às fontes de entrada: você pode fornecer texto livre, commits de um repositório git local ou Pull Requests de um repositório GitHub (fornecendo `owner/repo` e configurando a variável de ambiente `GITHUB_TOKEN`). O fluxo de trabalho é composto por 8 etapas: verificação de configuração, análise da entrada do usuário, coleta de dados via script (que filtra ruídos como alterações de CI/testes), transformação de itens técnicos em linguagem de benefícios para o usuário (seguindo regras de formatação e categorização), geração do pacote de conteúdo (com auto-verificação rigorosa contra palavras proibidas, comprimento de tweets e formatação), e salvamento no sistema de arquivos. A skill também permite que o usuário revise e edite os itens encontrados antes da geração final, garantindo controle e precisão. Plataformas suportadas: qualquer ambiente com Python 3, git e/ou acesso a API do GitHub.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Varnan-Tech/opendirectory/tree/main/skills/product-update-logger

Installed? Explore more Escrita e Edição skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Perguntar na sua IA favorita

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

Documentação

product-update-logger

Informe esta skill sobre o que seu produto lançou. Ela escreve uma entrada de changelog refinada em docs/changelog.md (um registro vivo, com a entrada mais recente primeiro) e, simultaneamente, produz um pacote de conteúdo: thread de tweets, post no LinkedIn, trecho de e-mail e uma frase de efeito.

Fontes de entrada: texto livre de sua mensagem, commits do git lidos automaticamente do repositório local ou PRs do GitHub se você fornecer um repositório. Qualquer combinação funciona.

Arquivos de Referência

Leia estes arquivos antes de cada execução:

cat references/changelog-format.md
cat references/content-rules.md
cat references/noise-filter.md

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

echo "GITHUB_TOKEN: ${GITHUB_TOKEN:-não definido -- busca de PRs do GitHub desabilitada}"
echo "Git:          $(git rev-parse --is-inside-work-tree 2>/dev/null && echo 'repositório detectado' || echo 'não é um repositório git')"
echo "Changelog:    $(ls docs/changelog.md 2>/dev/null && echo 'existe' || echo 'será criado')"

Observe se o git está disponível e se um changelog já existe. Isso determina o formato do rótulo de versão.


Etapa 2: Analisar Entrada

Colete da conversa:

  • items -- descrição em texto livre do que foi lançado (separado por pipe se múltiplos). Opcional se o git estiver disponível.
  • since -- quantos dias para trás olhar. Padrão: 7. O usuário pode dizer "últimas 2 semanas" (14) ou "desde o último lançamento".
  • repo -- "owner/repo" do GitHub para busca de PRs. Opcional.
  • version_label -- rótulo personalizado como "v2.1.0" ou "A Atualização de Velocidade". Opcional; o padrão é baseado na data.

Se o usuário não disse nada sobre itens E não há repositório git: Pergunte "O que você lançou? Liste os recursos, correções ou melhorias -- um por linha."

Se o git estiver disponível e o usuário não disse nada específico: Prossiga com a leitura automática do git na Etapa 3. Mostre ao usuário o que foi encontrado e confirme antes de transformar.

Escreva a entrada analisada:

python3 << 'PYEOF'
import json, os, re

inp = {
    "items": "",          # PREENCHER: texto livre separado por pipe, ou "" se nenhum
    "since": 7,           # PREENCHER: número inteiro de dias
    "repo": "",           # PREENCHER: "owner/repo" ou ""
    "version_label": ""   # PREENCHER: "" significa automático (baseado na data), ou string personalizada
}

with open("/tmp/pul-input.json", "w") as f:
    json.dump(inp, f, indent=2)
print(f"Desde: {inp['since']} dias")
print(f"Itens de texto livre: {inp['items'] or 'nenhum (usará git/GitHub)'}")
print(f"Repositório GitHub: {inp['repo'] or 'nenhum'}")
print(f"Rótulo de versão: {inp['version_label'] or 'automático (baseado na data)'}")
PYEOF

Etapa 3: Executar o Script de Coleta

ls scripts/gather.py 2>/dev/null && echo "script encontrado" || echo "ERRO: scripts/gather.py não encontrado"
GITHUB_TOKEN="${GITHUB_TOKEN:-}" python3 scripts/gather.py \
    --since "$(python3 -c "import json; print(json.load(open('/tmp/pul-input.json'))['since'])")" \
    --repo "$(python3 -c "import json; print(json.load(open('/tmp/pul-input.json'))['repo'])")" \
    --items "$(python3 -c "import json; print(json.load(open('/tmp/pul-input.json'))['items'])")" \
    --output /tmp/pul-raw.json

Verifique a saída:

python3 -c "
import json
with open('/tmp/pul-raw.json') as f:
    d = json.load(f)
print(f'Itens encontrados:      {d[\"total_items\"]}')
print(f'Ruído filtrado:   {d[\"noise_filtered\"]}')
print(f'Git disponível:    {d[\"git_available\"]}')
print(f'GitHub disponível: {d[\"github_available\"]}')
print(f'Origens: git={sum(1 for i in d[\"items\"] if i[\"source\"]==\"git_commit\")}, '
      f'prs={sum(1 for i in d[\"items\"] if i[\"source\"]==\"github_pr\")}, '
      f'texto={sum(1 for i in d[\"items\"] if i[\"source\"]==\"free_text\")}')
print()
print('Itens:')
for item in d['items']:
    print(f'  [{item[\"source\"]}] {item[\"subject\"]}')
"

Se total_items == 0: Pare. Informe ao usuário: "Nenhum item lançado encontrado. Descreva o que você lançou, aponte-me para um repositório git com commits recentes ou adicione um repositório GitHub com repo: owner/repo e um GITHUB_TOKEN."

Mostre a lista de itens ao usuário e pergunte: "Estes são os itens que encontrei. Algo para adicionar ou remover antes de eu escrever o changelog?"

Aguarde confirmação ou edições. Se o usuário disser "parece bom", "prossiga", ou não fizer alterações, continue. Se o usuário adicionar ou remover itens, atualize /tmp/pul-raw.json de acordo antes da Etapa 4.


Etapa 4: Gerar Entrada do Changelog

Imprima itens para contexto:

python3 -c "
import json
with open('/tmp/pul-raw.json') as f:
    d = json.load(f)
print(json.dumps(d['items'], indent=2))
print()
print(f'Formato do changelog existente: {d[\"existing_changelog\"][\"format\"]}')
print(f'Último rótulo: {d[\"existing_changelog\"][\"last_label\"]}')
print(f'Hoje: {d[\"date\"]}')
"

Instruções para IA: Transforme cada item bruto de linguagem técnica para linguagem de benefícios voltada ao usuário. Siga references/changelog-format.md para regras de transformação e exemplos.

Regras:

  • NÃO invente resultados ou métricas. "40% mais rápido" deve vir dos dados de origem. Se nenhum número estiver no commit ou PR, não adicione um.
  • Use pretérito perfeito: "Adicionado", "Corrigido", "Melhorado" -- não "Adiciona", "Corrige"
  • Atribua exatamente uma categoria a cada item: Novo, Melhorado, Corrigido ou Nos bastidores
  • Nos bastidores: Inclua apenas se for relevante para desenvolvedores (mudanças de API, mudanças que quebram compatibilidade). Omita seções vazias.
  • Omita qualquer coisa que se refira a: alterações de teste, alterações de CI, commits apenas de documentação

Determine o rótulo da versão:

  • Se o usuário especificou um: use exatamente
  • Se existing_changelog.format == "semver": incremente com base nas alterações (patch para apenas correções, minor para qualquer novo recurso)
  • Padrão: Semana de [Mês Dia, Ano] usando a data de hoje

Escreva a entrada em /tmp/pul-entry.json:

{
  "label": "Semana de 23 de Abril de 2026",
  "date": "2026-04-23",
  "new": [
    {"title": "Modo escuro", "description": "Ative em Configurações > Aparência. Funciona em todas as visualizações."}
  ],
  "improved": [
    {"title": "Tempo de resposta da API", "description": "40% mais rápido em média. O painel agora carrega em menos de 1 segundo."}
  ],
  "fixed": [
    {"title": "Exportação CSV", "description": "As exportações não perdem mais a última linha."}
  ],
  "under_the_hood": []
}

Verifique a entrada:

python3 -c "
import json
with open('/tmp/pul-entry.json') as f:
    e = json.load(f)
print(f'Rótulo: {e[\"label\"]}')
total = 0
for cat in ['new', 'improved', 'fixed', 'under_the_hood']:
    items = e.get(cat, [])
    if items:
        print(f'{cat.replace(\"_\", \" \").title()} ({len(items)}):')
        for item in items:
            print(f'  - {item[\"title\"]}: {item[\"description\"]}')
        total += len(items)
print(f'Total: {total} itens')
"

Etapa 5: Gerar Pacote de Conteúdo

Usando a entrada do changelog da Etapa 4, gere todas as quatro peças de conteúdo. Siga references/content-rules.md estritamente.

Frase de efeito (máx. 20 palavras): Uma frase cobrindo os 1-2 maiores itens. Linguagem simples, sem jargão.

Thread de tweets (3-5 tweets):

  • Tweet 1: Gancho -- "Lançamos [N] coisas esta semana." ou comece com o maior recurso
  • Tweets 2-N: Um item por tweet, máx. 1-2 frases
  • Último tweet: "Changelog: [link]" ou "Mais na próxima semana." (opcional)
  • Cada tweet estritamente com menos de 280 caracteres
  • Sem hashtags. Sem travessões. Voz ativa.

Post no LinkedIn:

  • Sem markdown (asteriscos são renderizados como literais no LinkedIn)
  • Sem hashtags
  • Voz de fundador: "Lançamos", não "Estamos animados em anunciar"
  • Parágrafos curtos (1-2 frases cada), linhas em branco entre eles
  • Termine com uma pergunta ou observação, não com uma chamada para ação
  • Total de 150-400 palavras

Trecho de e-mail:

  • Assunto: "O que lançamos esta semana: [maior item] + [mais 1]"
  • Corpo: 50-100 palavras. "Aqui está o que lançamos esta semana:" então marcadores.

Escreva em /tmp/pul-content.json:

{
  "one_liner": "Modo escuro, API mais rápida e um bug de exportação corrigido.",
  "tweet_thread": [
    "Lançamos 3 coisas esta semana.",
    "O modo escuro está no ar. Ative em Configurações > Aparência. Funciona em todos os lugares.",
    "O tempo de resposta da API agora é 40% mais rápido. O painel carrega em menos de um segundo.",
    "Corrigido: as exportações CSV estavam perdendo a última linha. Isso acabou.",
    "Changelog: [link]"
  ],
  "linkedin_post": "Lançamos 3 atualizações esta semana.\n\nO modo escuro está no ar. Ative em Configurações, em Aparência. Funciona em todas as visualizações.\n\nO tempo de resposta da API está 40% mais rápido em média. O painel agora carrega em menos de um segundo para a maioria dos usuários.\n\nTambém corrigimos um bug onde as exportações CSV estavam silenciosamente perdendo a última linha. Se você enfrentou isso e parou de exportar, vale a pena tentar novamente.\n\nQual recurso você está esperando?",
  "email_snippet": {
    "subject": "O que lançamos esta semana: modo escuro + API mais rápida",
    "body": "Aqui está o que lançamos esta semana:\n\n- Modo escuro: ative em Configurações > Aparência\n- Tempo de resposta da API: 40% mais rápido, painel carrega em menos de 1 segundo\n- Corrigido: exportações CSV não perdem mais a última linha\n\nChangelog completo abaixo."
  }
}

Etapa 6: Auto-QA

python3 -c "
import json, re

with open('/tmp/pul-raw.json') as f:
    raw = json.load(f)
with open('/tmp/pul-entry.json') as f:
    entry = json.load(f)
with open('/tmp/pul-content.json') as f:
    content = json.load(f)

full_text = json.dumps(entry) + json.dumps(content)
fails = 0

# Verificação 1: Sem travessões
if chr(8212) in full_text:
    print('FALHA: travessão encontrado -- substitua por hífen')
    fails += 1
else:
    print('PASSOU: sem travessões')

# Verificação 2: Palavras proibidas
banned = ['poderoso', 'robusto', 'perfeito', 'inovador', 'revolucionário',
          'otimizar', 'alavancar', 'transformar', 'revolucionar', 'animados em anunciar',
          'contentes em anunciar', 'estamos entusiasmados', 'de ponta', 'melhor da classe',
          'classe mundial', 'desbloquear', 'encantador']
found = [w for w in banned if w.lower() in full_text.lower()]
if found:
    print(f'FALHA: palavras proibidas encontradas: {found}')
    fails += 1
else:
    print('PASSOU: sem palavras proibidas')

# Verificação 3: Comprimento do tweet
thread = content.get('tweet_thread', [])
long_tweets = [(i+1, len(t)) for i, t in enumerate(thread) if len(t) > 280]
if long_tweets:
    print(f'FALHA: tweets com mais de 280 caracteres: {long_tweets}')
    fails += 1
else:
    print(f'PASSOU: todos os {len(thread)} tweets com menos de 280 caracteres')

# Verificação 4: LinkedIn sem hashtags
li = content.get('linkedin_post', '')
if re.search(r'#[A-Za-z]', li):
    print('FALHA: hashtags encontradas no post do LinkedIn')
    fails += 1
else:
    print('PASSOU: sem hashtags no LinkedIn')

# Verificação 5: Sem markdown no LinkedIn
if '**' in li or '__' in li:
    print('FALHA: formatação markdown no LinkedIn (renderiza como asteriscos literais)')
    fails += 1
else:
    print('PASSOU: sem markdown no LinkedIn')

# Verificação 6: Contagem de palavras da frase de efeito
one_liner = content.get('one_liner', '')
word_count = len(one_liner.split())
if word_count > 20:
    print(f'FALHA: frase de efeito tem {word_count} palavras (máx. 20)')
    fails += 1
else:
    print(f'PASSOU: frase de efeito tem {word_count} palavras')

# Verificação 7: Contagem de itens
entry_items = (len(entry.get('new', [])) + len(entry.get('improved', [])) +
               len(entry.get('fixed', [])) + len(entry.get('under_the_hood', [])))
raw_total = raw['total_items']
print(f'INFO: {entry_items} itens no changelog de {raw_total} itens brutos')

print()
print(f'Resultado: {"PASSOU" if fails == 0 else f"FALHOU ({fails} problemas)"}')
"

Se alguma verificação falhar: Corrija o problema no arquivo temporário relevante antes de prosseguir para a Etapa 7. Reexecute a verificação após corrigir.


Etapa 7: Anexar ao Changelog + Salvar Conteúdo

python3 << 'PYEOF'
import json, os, re

with open('/tmp/pul-entry.json') as f:
    entry = json.load(f)
with open('/tmp/pul-content.json') as f:
    content = json.load(f)

# Construir a nova seção do changelog
lines = [f"## {entry['label']}", ""]

CAT_HEADERS = {
    "new": "### Novo",
    "improved": "### Melhorado",
    "fixed": "### Corrigido",
    "under_the_hood": "### Nos bastidores",
}

for cat, header in CAT_HEADERS.items():
    items = entry.get(cat, [])
    if items:
        lines.append(header)
        for item in items:
            lines.append(f"- **{item['title']}** -- {item['description']}")
        lines.append("")

lines.append("---")
lines.append("")
new_section = "\n".join(lines)

# Inserir no início de docs/changelog.md
os.makedirs("docs", exist_ok=True)
changelog_path = "docs/changelog.md"

if os.path.exists(changelog_path):
    existing = open(changelog_path).read()
    # Inserir após o cabeçalho de nível superior (se houver) ou no topo
    if existing.startswith("# "):
        end_of_heading = existing.index("\n") + 1
        updated = existing[:end_of_heading] + "\n" + new_section + existing[end_of_heading:]
    else:
        updated = new_section + existing
else:
    updated = "# Changelog\n\n" + new_section

with open(changelog_path, "w") as f:
    f.write(updated)

print(f"Changelog atualizado: {changelog_path}")

# Salvar pacote de conteúdo
date = entry['date']
content_dir = "docs/product-updates"
os.makedirs(content_dir, exist_ok=True)
content_path = f"{content_dir}/{date}-content.md"

content_lines = [
    f"# Pacote de Conteúdo: {entry['label']}",
    "",
    "## Frase de Efeito",
    content.get('one_liner', ''),
    "",
    "## Thread de Tweets",
    "",
]
thread = content.get('tweet_thread', [])
for i, tweet in enumerate(thread, 1):
    content_lines.append(f"[{i}/{len(thread)}] {tweet}")
    content_lines.append("")

content_lines += [
    "## Post no LinkedIn",
    "",
    content.get('linkedin_post', ''),
    "",
    "## Trecho de E-mail",
    "",
    f"Assunto: {content.get('email_snippet', {}).get('subject', '')}",
    "",
    content.get('email_snippet', {}).get('body', ''),
    "",
]

with open(content_path, "w") as f:
    f.write("\n".join(content_lines))

print(f"Pacote de conteúdo: {content_path}")
PYEOF

Etapa 8: Limpeza e Apresentação

rm -f /tmp/pul-input.json /tmp/pul-raw.json /tmp/pul-entry.json /tmp/pul-content.json
echo "Concluído."

Apresente ao usuário nesta ordem:

1. Entrada do changelog (markdown formatado, não JSON bruto):

## Semana de 23 de Abril de 2026

### Novo
- **Modo escuro** -- Ative em Configurações > Aparência. Funciona em todas as visualizações.

### Melhorado
- **Tempo de resposta da API** -- 40% mais rápido em média. O painel agora carrega em menos de 1 segundo.

### Corrigido
- **Exportação CSV** -- As exportações não perdem mais a última linha.

---

2. Frase de efeito (texto simples)

3. Thread de tweets (marcadores numerados, cada tweet entre 280 caracteres)

4. Post no LinkedIn (texto simples, parágrafos curtos)

5. Trecho de e-mail (assunto + corpo)

Sempre pergunte ao usuário se há mais alguma coisa que ele gostaria de ajustar antes de finalizar.

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

Give it your product URL or description. It finds your top 5 competitors, runs three-track PR research across all of them (editorial, podcasts, communities), identifies which channels appear most frequently, looks up the journalist or host for each, and returns a tiered outreach list with story angles and ready-to-send cold pitch drafts tailored to your product. Use when asked to find PR opportunities, discover where competitors got featured, build a media outreach list, find which journalists cover my space, or get pitch templates for press coverage.

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

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