From 2b311586fc827fc51c8e4d490c49185074388478 Mon Sep 17 00:00:00 2001 From: Renata Matsumoto Date: Mon, 1 Sep 2025 16:19:28 -0300 Subject: [PATCH 01/13] =?UTF-8?q?feat:=20melhorar=20README=20e=20adicionar?= =?UTF-8?q?=20script=20de=20instala=C3=A7=C3=A3o=20para=20Cursor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Focar exclusivamente no Cursor como IDE padrão - Remover referências a Windsurf e VSCode - Eliminar repetições e duplicações - Reorganizar estrutura para melhor legibilidade - Adicionar script install-rdcontext-cursor.sh funcional - Remover scripts obsoletos e duplicados - Consolidar comandos úteis com casos de uso - Melhorar instruções de instalação e configuração --- README.md | 514 +++++++++++++++++++++--------------- install-rdcontext-cursor.sh | 418 +++++++++++++++++++++++++++++ 2 files changed, 717 insertions(+), 215 deletions(-) create mode 100755 install-rdcontext-cursor.sh diff --git a/README.md b/README.md index 18a7c8f..35b755d 100644 --- a/README.md +++ b/README.md @@ -1,361 +1,445 @@ # RDContext -**Local, Private, and AI-Ready Code Documentation Server** +**Servidor Local, Privado e Otimizado para IA de Documentação de Código** -RDContext is a local-first, privacy-focused tool to build AI-friendly context for any library based on its documentation files — including private repositories. Extract, index, and serve documentation for AI coding assistants, IDEs, and LLM workflows. Get better results. +RDContext é uma ferramenta local e focada em privacidade para construir contexto amigável à IA para qualquer biblioteca baseada em seus arquivos de documentação — incluindo repositórios privados. Extraia, indexe e sirva documentação para assistentes de IA, IDEs e fluxos de trabalho com LLM. --- -## Overview +## Início Rápido -RDContext MCP pulls up-to-date, version-specific, relevant documentation and code examples from a GitHub repository and makes it available to your IDE. +### 🚀 Instalação Automatizada (Recomendada) -Add `use rdcontext` to your prompt in Cursor: +```bash +# Clone o repositório +git clone https://github.com/resultadosdigitais/rdcontext.git +cd rdcontext -``` -Add a collapsible sidebar shadcn to the base layout of the app. use shadcn-ui, use rdcontext +# Dar permissão de execução ao script +chmod +x install-rdcontext-cursor.sh + +# Execute o script de instalação +./install-rdcontext-cursor.sh ``` -RDContext fetches up-to-date code examples and documentation right into your LLM's context. +Este script irá: +- ✅ Verificar versão do Node.js (18.12+ obrigatório, 20+ LTS recomendado) +- ✅ Instalar rdcontext globalmente +- ✅ Configurar API keys (Gemini/OpenAI) de forma segura +- ✅ Configurar token do GitHub para repos privados +- ✅ Configurar MCP para o Cursor automaticamente +- ✅ Adicionar bibliotecas de exemplo (FrontHub, Tangram) -1. Write your prompt -2. Tell the LLM to use RDContext -3. Get working code answers +### 📋 Instalação Manual -No tab-switching, no hallucinated APIs that don't exist, no outdated code generations. +**Requisitos:** +- Node.js 18.12+ (20+ LTS recomendado) +- npm ou bun +- Git -## How it works +```bash +# Instalar globalmente +npm install -g rdcontext -1. **Add a Library:** - Use the CLI to fetch documentation files (Markdown/MDX) from the specified repo/branch/tag/folders. - For private repos, supply a GitHub token. +# Ou usar diretamente +npx rdcontext --help +``` -2. **AI Extraction:** - Each documentation file is processed by a LLM to extract code snippets, titles, and descriptions optimized for LLM retrieval. +--- -3. **Local Indexing:** - All extracted data is stored in a local libSQL database in your user data directory. +## Visão Geral -4. **Query & Serve:** - Use the CLI to query docs/snippets, or start the MCP server to integrate with AI tools. +O RDContext MCP busca documentação e exemplos de código atualizados e específicos de versão de repositórios GitHub e os disponibiliza para sua IDE. -## Features +Adicione `use rdcontext` ao seu prompt no Cursor: -- **CLI:** Add, list and remove documentation of your tech stack using our CLI. -- **MCP Server:** Exposes a Model Context Protocol (MCP) server for integration with AI tools (Cursor, Windsurf, etc.). -- **Local and Private:** All data is stored locally using [libSQL](https://github.com/tursodatabase/libsql). No cloud or third-party storage required. -- **Customizable:** Choose which folders/files to index, and control which branches/tags to use. -- **Internal Library Support:** Add documentation from private GitHub repositories using a personal access token. -- **Cross-Platform:** Works on Linux, macOS, and Windows. +``` +Crie um componente Button usando o Tangram Design System, use rdcontext +``` ---- +O RDContext busca exemplos de código e documentação atualizados diretamente no contexto do seu LLM. -## Installation +1. Escreva seu prompt +2. Diga ao LLM para usar RDContext +3. Obtenha respostas de código funcionais -You can install RDContext globally via npm: +Sem mudança de abas, sem APIs alucinadas, sem gerações de código desatualizadas. -```bash -npm install -g rdcontext -``` +## Como funciona -Or use it directly with `npx` (no installation required): +1. **Adicionar uma Biblioteca:** + Use a CLI para buscar arquivos de documentação (Markdown/MDX) de repo/branch/tag/pastas especificadas. -```bash -npx -y rdcontext -``` +2. **Extração por IA:** + Cada arquivo de documentação é processado por LLM para extrair snippets de código, títulos e descrições otimizadas para recuperação. ---- +3. **Indexação Local:** + Todos os dados extraídos são armazenados em um banco de dados SQLite local no diretório de dados do usuário. -## Environment Setup +4. **Consulta e Servir:** + Use a CLI para consultar docs/snippets, ou inicie o servidor MCP para integrar com ferramentas de IA. -**You must set the `OPENAI_API_KEY` environment variable for RDContext to work.** +## Funcionalidades -```bash -export OPENAI_API_KEY=sk-... -``` - -You can get your API key from [OpenAI's dashboard](https://platform.openai.com/api-keys). +- **CLI:** Adicione, liste e remova documentação usando nossa CLI +- **Servidor MCP:** Servidor Model Context Protocol para o Cursor +- **Local e Privado:** Todos os dados armazenados localmente usando SQLite. Sem nuvem necessária +- **Personalizável:** Escolha pastas/arquivos para indexar, controle branches/tags +- **Repos Privados:** Adicione documentação de repositórios GitHub privados +- **Multiplataforma:** Funciona no Linux, macOS e Windows --- -## Usage +## Configuração do Ambiente + +### API Keys -### CLI Overview +**Obrigatório:** Configure pelo menos uma API key de provedor de IA: -All commands are available via the `rdcontext` CLI (or `npx -y rdcontext `). +#### Instalação Interativa (Recomendado) -#### Add a Library +O script de instalação sempre pergunta ao usuário pelas configurações necessárias: -Index documentation from a GitHub repository (public or private): +- **API Keys** são solicitadas interativamente +- **GitHub Token** é configurado conforme escolha do usuário +- **Provedor de IA** é selecionado pelo usuário +- **Configurações MCP** são criadas automaticamente + +#### Configuração Manual ```bash -rdcontext add [--branch ] [--tag ] [--folders ...] [--token ] +# Para Gemini (recomendado) +export GEMINI_API_KEY="sua-chave-aqui" +export AI_PROVIDER="gemini" + +# Para OpenAI (alternativo) +export OPENAI_API_KEY="sua-chave-aqui" +export AI_PROVIDER="openai" ``` -- `--branch `: Git branch to index (default: repo default branch) -- `--tag `: Git tag to index (mutually exclusive with `--branch`) -- `--folders ...`: Only index documentation in these folders (default: all) -- `--token `: GitHub token for private repo access +**Configuração via arquivo .env:** +```bash +# ~/.env ou ~/.bashrc ou ~/.zshrc +export GEMINI_API_KEY="sua-api-key-do-gemini" +export OPENAI_API_KEY="sua-api-key-do-openai" # opcional +export AI_PROVIDER="gemini" # ou "openai" +``` -**Examples:** +Obtenha suas chaves: +- **Gemini:** https://makersuite.google.com/app/apikey +- **OpenAI:** https://platform.openai.com/api-keys -Add up-to-date RDContext documentation: +### Token do GitHub (Opcional) + +Para repositórios privados: ```bash -rdcontext add cozmo-dev/rdcontext --branch main +export GITHUB_TOKEN=ghp_seu_token_github_aqui ``` -Add documentation of a specific ShadCN UI version: +Obtenha seu token: https://github.com/settings/tokens + +--- + +## Uso + +### Comandos da CLI + +#### Adicionar uma Biblioteca ```bash -rdcontext add shadcn-ui/ui --tag shadcn-ui@0.9.4 +rdcontext add [--branch ] [--tag ] [--folders ] [--token ] ``` -Add documentation of a private repo of your GitHub org: +**Exemplos:** ```bash -rdcontext add myorg/myrepo --branch main --folders docs src/guides --token ghp_xxx +# Adicionar o Tangram (design system) +rdcontext add "resultadosdigitais/tangram" --folders "docs/examples/componests" "docs/docs" "docs/code" --token ghp_xxx + +# Adicionar o FrontHub (microfrontends) +rdcontext add "resultadosdigitais/front-hub" --folders "packages/front-hub-docs/docs" --token ghp_xxx + +# Adicionar versão específica +rdcontext add "shadcn-ui/ui" --tag v0.9.4 + +# Repo privado com token +rdcontext add "myorg/myrepo" --folders "docs" --token ghp_xxx ``` -#### List Indexed Libraries +#### Listar Bibliotecas ```bash rdcontext list ``` -#### Get Documentation - -Fetch up-to-date documentation for a library, optionally filtered by topic: +#### Consultar Documentação ```bash -rdcontext get [topic] [--k ] +rdcontext get [tópico] [--k ] ``` -- `topic`: (optional) Focus on a specific topic (e.g., "hooks", "routing") -- `--k`: Number of top snippets to return (default: 10) +**Exemplos:** +```bash +# Buscar exemplos de botões +rdcontext get resultadosdigitais/tangram "botão" -**Example:** +# Buscar exemplos de componentes +rdcontext get resultadosdigitais/front-hub "componente" -```bash -rdcontext get shadcn-ui/ui "Select" +# Buscar padrões de design +rdcontext get resultadosdigitais/tangram "padrões de design" ``` -#### Remove a Library +#### Remover Biblioteca ```bash rdcontext rm ``` -#### Start the MCP Server - -Expose the documentation server for AI tools (Cursor, Windsurf, etc.): - -```bash -rdcontext start [--transport stdio|httpStream] [--port ] -``` -- `--transport`: Communication method (`stdio` for local, `httpStream` for HTTP API, default: `stdio`) -- `--port`: Port for HTTP transport (default: 3000) --- -### MCP server - -RDContext exposes a Model Context Protocol (MCP) server, making it easy to integrate with popular AI coding tools and IDEs. +## Integração com o Cursor -Requirements: +### 🚀 Configuração Automática (Recomendada) -- Node.js >= v18.0.0 -- Cursor, Windsurf, Claude Desktop or another MCP Client +Use o script de instalação que configura automaticamente o MCP: -
-Cursor +```bash +./install-rdcontext-cursor.sh +``` -Go to: `Settings` -> `Cursor Settings` -> `MCP` -> `Add new global MCP server` +### ⚙️ Configuração Manual -Pasting the following configuration into your Cursor `~/.cursor/mcp.json` file is the recommended approach. You may also install in a specific project by creating `.cursor/mcp.json` in your project folder. See [Cursor MCP docs](https://docs.cursor.com/context/model-context-protocol) for more info. +Se preferir configurar manualmente, adicione ao `~/.cursor/mcp.json`: ```json { "mcpServers": { - "libcontext": { - "command": "libcontext", + "rdcontext": { + "command": "rdcontext", "args": ["start"], "env": { - "OPENAI_API_KEY": "sk-..." + "AI_PROVIDER": "gemini", + "GEMINI_API_KEY": "sua-api-key-aqui", + "GEMINI_EMBEDDING_MODEL": "text-embedding-004" } } } } ``` -
-Alternative: Without global installation +### 🔧 Como usar no Cursor -Or if you have not installed globally: +1. **Instale o rdcontext** usando o script de instalação +2. **Reinicie o Cursor** para aplicar as configurações MCP +3. **Digite no editor**: `"Mostre exemplos de botões do Tangram"` +4. **Use o contexto**: O rdcontext fornecerá exemplos reais e atualizados -```json -{ - "mcpServers": { - "rdcontext": { - "command": "npx", - "args": ["-y", "rdcontext", "start"], - "env": { - "OPENAI_API_KEY": "sk-..." - } - } - } -} +--- + +## Requisitos de Versão do Node.js + +**Mínimo:** Node.js 18.12+ +**Recomendado:** Node.js 20+ LTS + +O RDContext usa recursos modernos do JavaScript: +- ES Modules (`import`/`export`) +- `await` de nível superior +- API Fetch nativa +- APIs crypto modernas + +### Solução de Problemas do Node.js + +**Verificar versão:** +```bash +node --version ``` -
+**Atualizar Node.js:** +```bash +# Ubuntu/Debian +curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - +sudo apt-get install -y nodejs -
-Alternative: Using with Bun runtime +# macOS +brew install node -```json -{ - "mcpServers": { - "rdcontext": { - "command": "bunx", - "args": ["-y", "rdcontext", "start"], - "env": { - "OPENAI_API_KEY": "sk-..." - } - } - } -} +# Ou use nvm +nvm install --lts +nvm use --lts ``` -
+**Erros comuns:** +- `SyntaxError: Unexpected token 'export'` → Atualize o Node.js +- `ReferenceError: fetch is not defined` → Atualize para Node.js 18+ +- `Cannot use import statement` → Atualize o Node.js -
+--- -
-Windsurf +## Armazenamento de Dados -Add this to your Windsurf MCP config file. See [Windsurf MCP docs](https://docs.windsurf.com/windsurf/mcp) for more info. +- **Banco de Dados:** Usa diretório padrão de dados do SO + - Linux: `~/.local/share/rdcontext/rdcontext.db` + - macOS: `~/Library/Application Support/rdcontext/rdcontext.db` + - Windows: `%LOCALAPPDATA%\rdcontext\Data\rdcontext.db` -```json -{ - "mcpServers": { - "rdcontext": { - "command": "rdcontext", - "args": ["start"], - "env": { - "OPENAI_API_KEY": "sk-..." - } - } - } -} -``` +- **Sem Nuvem:** Todos os dados permanecem na sua máquina +- **Privacidade:** Sem telemetria ou compartilhamento de dados externos -
+--- -
-Docker -If you prefer to run the MCP server in a Docker container: -1. **Build the Docker Image:** +## 🎯 Casos de Uso e Comandos - Then, build the image in the project root using a tag (e.g., `rdcontext`). **Make sure Docker Desktop (or the Docker daemon) is running.** Run the following command in the same directory where you saved the `Dockerfile`: +### 🛠️ Comandos Principais - ```bash - docker build -t rdcontext . - ``` +```bash +# Listar bibliotecas +rdcontext list -2. **Configure Your MCP Client:** +# Adicionar nova biblioteca +rdcontext add --folders docs,src - Update your MCP client's configuration to use the Docker command. +# Remover biblioteca +rdcontext rm - _Example for a cline_mcp_settings.json:_ +# Buscar documentação +rdcontext get "tema" - ```json - { - "mcpServers": { - "RDContext": { - "autoApprove": [], - "disabled": false, - "timeout": 60, - "command": "docker", - "args": ["run", "-i", "--rm", "rdcontext"], - "transportType": "stdio" - } - } - } - ``` +# Iniciar servidor MCP +rdcontext start +``` - _Note: This is an example configuration. Please refer to the specific examples for your MCP client (like Cursor, VS Code, etc.) earlier in this README to adapt the structure (e.g., `mcpServers` vs `servers`). Also, ensure the image name in `args` matches the tag used during the `docker build` command._ +### 🚀 Exemplos Práticos -
+**Para Desenvolvedores:** +```bash +rdcontext get "resultadosdigitais/tangram" "padrões de design" +rdcontext get "resultadosdigitais/tangram" "formulário validação" +rdcontext get "resultadosdigitais/tangram" "ícones" +``` -## Tips +**Para Criação de Telas:** +```bash +rdcontext get "resultadosdigitais/front-hub" "layout responsivo" +rdcontext get "resultadosdigitais/front-hub" "microfrontend" +rdcontext get "resultadosdigitais/front-hub" "integração" +``` -### Add a Rule +### 🎯 Teste no Cursor -> If you don't want to add `use rdcontext` to every prompt, you can define a simple rule in your `.windsurfrules` file in Windsurf or from `Cursor Settings > Rules` section in Cursor (or the equivalent in your MCP client) to auto-invoke RDContext on any code-related question: -> -> ```toml -> [[calls]] -> match = "when the user requests code examples, setup or configuration steps, or library/API documentation" -> tool = "rdcontext" -> ``` -> -> From then on you'll get RDContext's docs in any related conversation without typing anything extra. You can add your use cases to the match part. +Digite no editor: +``` +👉 "Mostre exemplos de formulários do Tangram" +``` --- -## Data Storage +## Solução de Problemas -- **Database:** - Uses your OS's standard data directory (e.g., `~/.local/share/rdcontext/rdcontext.db` on Linux). -- **No Cloud:** - All data remains on your machine unless you explicitly share it. +### Problemas Comuns ---- +**"rdcontext: command not found"** +```bash +# Recarregar shell +source ~/.bashrc # ou ~/.zshrc -## Security & Privacy +# Ou instalar globalmente +npm install -g rdcontext +``` -- **Private by Default:** - All indexes are stored locally. - ⚠️ During the _AI Extraction_ step the selected documentation is sent to the OpenAI API (or whichever LLM you configure). - If you need zero-egress processing, self-host the model or disable extraction. -- **Private Repo Support:** - Your GitHub token is only used locally to fetch documentation. +**Erro de API Key** +```bash +echo $GEMINI_API_KEY +export GEMINI_API_KEY="sua-chave" +``` ---- +**Erro de permissão** +```bash +chmod +x $(which rdcontext) +``` + +**Servidor não responde** +```bash +ps aux | grep rdcontext +pkill -f rdcontext +rdcontext start +``` + +**"No sessionId" no navegador** +- Isso é normal para servidores MCP +- Use através da sua IDE, não diretamente no navegador -## Contributing +**Limites de Rate da API** +- Use token do GitHub para limites maiores +- Gemini tem tier gratuito generoso +- OpenAI requer conta paga para uso em produção -- **Run in development mode:** - ```bash - bun dev - ``` +**Erros de Build** +```bash +# Limpar cache e reinstalar +npm cache clean --force +npm install -g rdcontext +``` + +### Obtendo Ajuda + +1. Verifique este README +2. Execute `rdcontext --help` +3. Verifique Issues no GitHub +4. Verifique versão do Node.js (18.12+ obrigatório) --- -## Troubleshooting +## 📚 Scripts de Instalação + +### `install-rdcontext-cursor.sh` +Script principal para instalação no Cursor: +- ✅ Instalação limpa e interativa +- ✅ Configuração automática do MCP +- ✅ Preserva configurações MCP existentes +- ✅ Adiciona bibliotecas da RD Station automaticamente -- **Permission Errors:** - Ensure the data directory is writable (see error message for path). -- **Private Repo Issues:** - Double-check your GitHub token and repo access. -- **OpenAI Errors:** - Ensure your `OPENAI_API_KEY` environment variable is set. +```bash +# Dar permissão de execução +chmod +x install-rdcontext-cursor.sh + +# Executar instalação +./install-rdcontext-cursor.sh +``` --- -## License +## 🛠️ Desenvolvimento + +```bash +# Clonar repositório +git clone https://github.com/resultadosdigitais/rdcontext.git +cd rdcontext + +# Instalar dependências +npm install -MIT +# Build +npm run build + +# Instalar localmente +npm install -g . + +# Executar testes +npm test +``` --- -## Credits +## Licença -Inspired by [upstash/context7](https://github.com/upstash/context7), but designed for local/private workflows. +Licença MIT - veja o arquivo [LICENSE](LICENSE) para detalhes. --- -**Build your own private, AI-ready documentation server—locally.** +**✨ Feliz codificação com RDContext!** \ No newline at end of file diff --git a/install-rdcontext-cursor.sh b/install-rdcontext-cursor.sh new file mode 100755 index 0000000..9110e38 --- /dev/null +++ b/install-rdcontext-cursor.sh @@ -0,0 +1,418 @@ +#!/bin/bash + +# Script de instalação do rdcontext focado no Cursor +# Versão limpa - sem verificação de variáveis existentes + +set -e + +# Cores para output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Funções de log +log_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +log_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +log_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +print_header() { + echo + echo " ____ ____ ____ _ _ " + echo "| _ \| _ \ / ___|___ _ __ | |_ _____ _| |_ " + echo "| |_) | | | | | / _ \| '_ \| __/ _ \ \/ / __|" + echo "| _ <| |_| | |__| (_) | | | | || __/> <|_ |" + echo "|_| \_\____/ \____\___/|_| |_|\__\___/_/\_\\__|" + echo " " + echo "🚀 Instalador rdcontext para Cursor" + echo +} + +# Verifica dependências +check_dependencies() { + log_info "Verificando dependências..." + + # Node.js + if ! command -v node &> /dev/null; then + log_error "❌ Node.js não encontrado!" + echo "Instale Node.js 18+ de: https://nodejs.org/" + exit 1 + else + NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1) + if [ "$NODE_VERSION" -lt 18 ]; then + log_error "❌ Node.js $(node --version) é muito antiga!" + echo "rdcontext requer Node.js 18+ para ES modules e top-level await" + exit 1 + else + log_success "Node.js $(node --version) ✅" + fi + fi + + # npm + if ! command -v npm &> /dev/null; then + log_error "❌ npm não encontrado!" + exit 1 + else + log_success "npm $(npm --version) encontrado" + fi + + # Git + if ! command -v git &> /dev/null; then + log_error "❌ Git não encontrado!" + exit 1 + else + log_success "Git $(git --version | cut -d' ' -f3) encontrado" + fi + + # jq (para merge do mcp.json) + if ! command -v jq &> /dev/null; then + log_warning "⚠️ jq não encontrado. Instalando..." + if command -v apt-get &> /dev/null; then + sudo apt-get update && sudo apt-get install -y jq + elif command -v yum &> /dev/null; then + sudo yum install -y jq + elif command -v brew &> /dev/null; then + brew install jq + else + log_error "❌ Não foi possível instalar jq automaticamente" + echo "Instale jq manualmente: https://jqlang.github.io/jq/" + exit 1 + fi + log_success "jq instalado com sucesso" + else + log_success "jq encontrado" + fi +} + +# Instala rdcontext +install_rdcontext() { + log_info "Instalando rdcontext..." + + if [ -f "package.json" ] && grep -q '"name": "rdcontext"' package.json; then + log_info "Detectado repositório local do rdcontext" + log_info "Instalando dependências..." + npm install + + log_info "Fazendo build..." + npm run build + + log_info "Instalando globalmente..." + npm install -g . + else + log_info "Instalando do GitHub..." + npm install -g git+https://github.com/resultadosdigitais/rdcontext.git + fi + + # Verifica instalação + if command -v rdcontext &> /dev/null; then + log_success "rdcontext $(rdcontext --version) instalado com sucesso!" + else + log_error "❌ Falha na instalação do rdcontext" + exit 1 + fi +} + +# Configura API Keys +configure_api_keys() { + echo + log_info "Configurando API Keys..." + + # Sempre pergunta qual provedor usar + echo "Qual provedor de IA você deseja usar?" + echo "1) Gemini (Google) - Recomendado" + echo "2) OpenAI" + echo "3) Pular (configurar depois)" + read -p "Escolha uma opção (1-3): " -n 1 -r + echo + + case $REPLY in + 1) + echo + log_info "🔑 Configurando Gemini API Key..." + read -s -p "Digite sua API Key do Gemini (não será exibida): " GEMINI_API_KEY + echo + if [ -n "$GEMINI_API_KEY" ]; then + echo "export GEMINI_API_KEY=\"$GEMINI_API_KEY\"" >> ~/.bashrc + echo "export AI_PROVIDER=\"gemini\"" >> ~/.bashrc + export GEMINI_API_KEY="$GEMINI_API_KEY" + export AI_PROVIDER="gemini" + log_success "✅ API Key do Gemini configurada!" + else + log_warning "⚠️ API Key vazia, Gemini não configurado" + fi + ;; + 2) + echo + log_info "🔑 Configurando OpenAI API Key..." + read -s -p "Digite sua API Key da OpenAI (não será exibida): " OPENAI_API_KEY + echo + if [ -n "$OPENAI_API_KEY" ]; then + echo "export OPENAI_API_KEY=\"$OPENAI_API_KEY\"" >> ~/.bashrc + echo "export AI_PROVIDER=\"openai\"" >> ~/.bashrc + export OPENAI_API_KEY="$OPENAI_API_KEY" + export AI_PROVIDER="openai" + log_success "✅ API Key da OpenAI configurada!" + else + log_warning "⚠️ API Key vazia, OpenAI não configurado" + fi + ;; + 3) + log_info "Configuração de API Key pulada." + ;; + esac +} + +# Configura GitHub Token +configure_github_token() { + echo + log_info "Configurando GitHub Token..." + + echo "Para acessar repositórios privados da RD Station, você precisa de um GitHub Token." + echo + read -p "Deseja configurar o GitHub Token agora? (y/n): " -n 1 -r + echo + + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo + read -s -p "Digite seu GitHub Token (não será exibido): " GITHUB_TOKEN + echo + if [ -n "$GITHUB_TOKEN" ]; then + echo "export GITHUB_TOKEN=\"$GITHUB_TOKEN\"" >> ~/.bashrc + export GITHUB_TOKEN="$GITHUB_TOKEN" + log_success "✅ GitHub Token configurado!" + else + log_warning "⚠️ Token vazio, GitHub Token não configurado" + fi + else + log_info "GitHub Token não configurado. Configure depois com:" + echo "export GITHUB_TOKEN=\"seu_token_aqui\"" + fi +} + +# Configura MCP no Cursor +configure_cursor_mcp() { + local cursor_config_dir="$HOME/.cursor" + local mcp_config="$cursor_config_dir/mcp.json" + + mkdir -p "$cursor_config_dir" + + # Backup do arquivo existente se houver + if [ -f "$mcp_config" ]; then + log_warning "Arquivo mcp.json já existe. Fazendo backup..." + cp "$mcp_config" "$mcp_config.backup.$(date +%Y%m%d_%H%M%S)" + fi + + # Cria configuração temporária do rdcontext + local temp_rdcontext_config=$(mktemp) + + # Constrói o JSON de forma mais robusta + cat > "$temp_rdcontext_config" << EOF +{ + "mcpServers": { + "rdcontext": { + "command": "rdcontext", + "args": ["start"], + "env": { +EOF + + # Adiciona variáveis de ambiente se configuradas + local env_vars=() + if [ -n "$GEMINI_API_KEY" ]; then + env_vars+=(" \"GEMINI_API_KEY\": \"$GEMINI_API_KEY\"") + env_vars+=(" \"AI_PROVIDER\": \"gemini\"") + env_vars+=(" \"GEMINI_EMBEDDING_MODEL\": \"text-embedding-004\"") + fi + + if [ -n "$OPENAI_API_KEY" ]; then + env_vars+=(" \"OPENAI_API_KEY\": \"$OPENAI_API_KEY\"") + env_vars+=(" \"AI_PROVIDER\": \"openai\"") + env_vars+=(" \"OPENAI_EMBEDDING_MODEL\": \"text-embedding-3-large\"") + fi + + if [ -n "$GITHUB_TOKEN" ]; then + env_vars+=(" \"GITHUB_TOKEN\": \"$GITHUB_TOKEN\"") + fi + + # Adiciona as variáveis de ambiente ao JSON + if [ ${#env_vars[@]} -gt 0 ]; then + local last_index=$((${#env_vars[@]} - 1)) + for i in "${!env_vars[@]}"; do + if [ $i -eq $last_index ]; then + # Última variável - sem vírgula + echo "${env_vars[$i]}" >> "$temp_rdcontext_config" + else + # Outras variáveis - com vírgula + echo "${env_vars[$i]}," >> "$temp_rdcontext_config" + fi + done + fi + + # Fecha o JSON + cat >> "$temp_rdcontext_config" << EOF + } + } + } +} +EOF + + if [ -f "$mcp_config" ]; then + log_info "Fazendo merge com configurações MCP existentes..." + + # Valida o JSON existente antes do merge + if ! jq empty "$mcp_config" 2>/dev/null; then + log_error "❌ Arquivo mcp.json existente tem JSON inválido!" + log_info "Restaurando do backup..." + cp "$mcp_config.backup.$(date +%Y%m%d_%H%M%S)" "$mcp_config" 2>/dev/null || { + log_error "❌ Falha ao restaurar backup. Criando novo arquivo..." + rm -f "$mcp_config" + } + fi + + # Valida o JSON do rdcontext antes do merge + if ! jq empty "$temp_rdcontext_config" 2>/dev/null; then + log_error "❌ JSON do rdcontext é inválido!" + rm -f "$temp_rdcontext_config" + return 1 + fi + + # Faz o merge de forma mais segura + local merge_result=$(mktemp) + if jq -s '.[0] * .[1]' "$mcp_config" "$temp_rdcontext_config" > "$merge_result" 2>/dev/null; then + # Valida o resultado do merge + if jq empty "$merge_result" 2>/dev/null; then + mv "$merge_result" "$mcp_config" + log_success "Configuração MCP atualizada preservando outras configurações" + else + log_error "❌ Resultado do merge é JSON inválido!" + log_info "Restaurando configuração original..." + cp "$mcp_config.backup.$(date +%Y%m%d_%H%M%S)" "$mcp_config" 2>/dev/null + rm -f "$merge_result" + fi + else + log_error "❌ Falha no merge do JSON!" + log_info "Restaurando configuração original..." + cp "$mcp_config.backup.$(date +%Y%m%d_%H%M%S)" "$mcp_config" 2>/dev/null + rm -f "$merge_result" + fi + + rm -f "$temp_rdcontext_config" + else + # Cria novo arquivo + mv "$temp_rdcontext_config" "$mcp_config" + log_success "Nova configuração MCP criada" + fi + + log_success "Configuração MCP criada em $mcp_config" + echo + log_info "⚠️ IMPORTANTE: Reinicie o Cursor para aplicar as configurações MCP!" +} + +# Adiciona bibliotecas de exemplo +add_example_libraries() { + echo + read -p "Deseja adicionar as bibliotecas da RD Station (Tangram e FrontHub)? (y/n): " add_examples + + if [[ $add_examples =~ ^[Yy]$ ]]; then + if [ -z "$GITHUB_TOKEN" ]; then + log_error "❌ GitHub Token necessário para adicionar bibliotecas da RD Station" + echo "Configure o token primeiro com: export GITHUB_TOKEN=\"seu_token\"" + return + fi + + # Verifica se tem API Key configurada + if [ -z "$GEMINI_API_KEY" ] && [ -z "$OPENAI_API_KEY" ]; then + log_error "❌ API Key necessária para processar documentação!" + echo "Configure uma API Key primeiro (Gemini ou OpenAI)" + return + fi + + log_info "Adicionando FrontHub..." + log_info "Comando: rdcontext add \"resultadosdigitais/front-hub\" --folders \"packages/front-hub-docs/docs\" --token [GITHUB_TOKEN]" + echo + rdcontext add "resultadosdigitais/front-hub" --folders "packages/front-hub-docs/docs" --token "$GITHUB_TOKEN" + log_success "FrontHub adicionado com sucesso!" + + log_info "Adicionando Tangram Design System..." + log_info "Comando: rdcontext add \"resultadosdigitais/tangram\" --folders \"docs/examples/componests\" \"docs/docs\" \"docs/code\" --token [GITHUB_TOKEN]" + echo + rdcontext add "resultadosdigitais/tangram" --folders "docs/examples/componests" "docs/docs" "docs/code" --token "$GITHUB_TOKEN" + log_success "Tangram adicionado com sucesso!" + fi +} + +# Testa a instalação +test_installation() { + log_info "Testando instalação..." + + if rdcontext --version &> /dev/null; then + log_success "✅ rdcontext está funcionando!" + else + log_error "❌ Erro ao executar rdcontext" + exit 1 + fi + + # Lista bibliotecas + echo + log_info "Bibliotecas indexadas:" + rdcontext list +} + +# Mostra próximos passos +show_next_steps() { + echo + echo "🎉 Instalação concluída com sucesso!" + echo + echo "📋 Próximos passos:" + echo + echo "1. Reinicie o Cursor para aplicar as configurações MCP" + echo + echo "2. No Cursor, teste digitando:" + echo " 'Mostre exemplos de botões do Tangram'" + echo + echo "3. Para adicionar mais bibliotecas:" + echo " rdcontext add \"owner/repo\" --folders \"pasta1\" \"pasta2\" --token SEU_GITHUB_TOKEN" + echo + echo "4. Comandos úteis:" + echo " rdcontext list # Lista bibliotecas" + echo " rdcontext get \"repo\" \"query\" # Busca contexto" + echo + echo "5. Comandos específicos para RD Station:" + echo " rdcontext add \"resultadosdigitais/front-hub\" --folders \"packages/front-hub-docs/docs\" --token SEU_GITHUB_TOKEN" + echo + echo " rdcontext add \"resultadosdigitais/tangram\" --folders \"docs/examples/componests\" \"docs/docs\" \"docs/code\" --token SEU_GITHUB_TOKEN" + echo + echo + echo "📚 Documentação completa:" + echo " https://github.com/resultadosdigitais/rdcontext" + echo " README.md - Guia completo de instalação e uso" + echo +} + +# Função principal +main() { + print_header + check_dependencies + install_rdcontext + configure_api_keys + configure_github_token + configure_cursor_mcp + add_example_libraries + test_installation + show_next_steps +} + +# Executa o script +main "$@" From a1472a34e53ed451e8b8ac0e75139bd609f4b504 Mon Sep 17 00:00:00 2001 From: Renata Matsumoto Date: Mon, 1 Sep 2025 16:22:13 -0300 Subject: [PATCH 02/13] feat: melhorar suporte a embeddings do Gemini MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adicionar suporte a embeddings 768d do Gemini text-embedding-004 - Implementar normalização automática de 768d para 3072d - Atualizar schema para aceitar dimensões corretas do Gemini - Melhorar validação de embeddings por provedor - Manter compatibilidade com OpenAI embeddings 1536d --- src/ai/embedding-utils.ts | 24 ++++++++++++++++++------ src/db/schema-v2.ts | 2 +- src/db/vector-store.ts | 9 +++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/ai/embedding-utils.ts b/src/ai/embedding-utils.ts index d8c8696..167ff66 100644 --- a/src/ai/embedding-utils.ts +++ b/src/ai/embedding-utils.ts @@ -15,12 +15,24 @@ export class EmbeddingNormalizer { } } - // Gemini embeddings are already 3072d - validate and return + // Normalize Gemini embeddings to 3072 dimensions private static normalizeGemini(embedding: number[]): number[] { - if (embedding.length !== 3072) { - throw new Error(`Invalid Gemini embedding dimensions: expected 3072, got ${embedding.length}`); + if (embedding.length === 3072) { + // Already 3072d - return as-is + return embedding; } - return embedding; + + if (embedding.length === 768) { + // Pad 768d embeddings to 3072d with zeros + // This is a simple approach - in production you might want more sophisticated normalization + const normalized = new Array(3072).fill(0); + for (let i = 0; i < 768; i++) { + normalized[i] = embedding[i]; + } + return normalized; + } + + throw new Error(`Invalid Gemini embedding dimensions: expected 768 or 3072, got ${embedding.length}`); } // OpenAI embeddings: truncate from 1536d to 3072d (Matryoshka principle) @@ -108,7 +120,7 @@ export class EmbeddingNormalizer { static validateEmbedding(embedding: number[], provider: EmbeddingProvider): boolean { switch (provider) { case 'gemini': - return embedding.length === 3072; + return [768, 3072].includes(embedding.length); case 'openai': return [3072, 1536, 3072].includes(embedding.length); default: @@ -120,7 +132,7 @@ export class EmbeddingNormalizer { static getExpectedDimensions(provider: EmbeddingProvider): number[] { switch (provider) { case 'gemini': - return [3072]; + return [768, 3072]; case 'openai': return [3072, 1536, 3072]; default: diff --git a/src/db/schema-v2.ts b/src/db/schema-v2.ts index 2c03488..b347745 100644 --- a/src/db/schema-v2.ts +++ b/src/db/schema-v2.ts @@ -59,7 +59,7 @@ export interface VectorRecord { // Embedding dimension constants export const EMBEDDING_DIMS = { OPENAI: 1536, - GEMINI: 3072, + GEMINI: 768, // text-embedding-004 returns 768 dimensions NORMALIZED: 3072, // Common dimension for cross-provider comparison } as const; diff --git a/src/db/vector-store.ts b/src/db/vector-store.ts index 19c2c69..b0a3b83 100644 --- a/src/db/vector-store.ts +++ b/src/db/vector-store.ts @@ -31,6 +31,15 @@ export class VectorStore { return embedding; } + if (provider === 'gemini' && embedding.length === 768) { + // Pad 768d Gemini embeddings to 3072d with zeros + const normalized = new Array(3072).fill(0); + for (let i = 0; i < 768; i++) { + normalized[i] = embedding[i]; + } + return normalized; + } + if (provider === 'openai' && embedding.length === 1536) { // Truncate OpenAI embeddings to first 3072 dimensions // This preserves most semantic information (Matryoshka embedding principle) From 4f6b36a50c3e33d6f01d471611db3aaab4ab7e0d Mon Sep 17 00:00:00 2001 From: Renata Matsumoto Date: Tue, 2 Sep 2025 17:35:23 -0300 Subject: [PATCH 03/13] =?UTF-8?q?fix:=20suporte=20multi-shell=20e=20corre?= =?UTF-8?q?=C3=A7=C3=A3o=20de=20typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adiciona suporte para configuração em ~/.zshrc além de ~/.bashrc - Corrige typo 'componests' → 'components' em todos os arquivos - Melhora mensagens de sucesso para indicar arquivos configurados - Aplica sugestões do typo-app bot para maior compatibilidade --- README.md | 2 +- install-rdcontext-cursor.sh | 40 +++++++++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 35b755d..cccd81a 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ rdcontext add [--branch ] [--tag ] [--folders ```bash # Adicionar o Tangram (design system) -rdcontext add "resultadosdigitais/tangram" --folders "docs/examples/componests" "docs/docs" "docs/code" --token ghp_xxx +rdcontext add "resultadosdigitais/tangram" --folders "docs/examples/components" "docs/docs" "docs/code" --token ghp_xxx # Adicionar o FrontHub (microfrontends) rdcontext add "resultadosdigitais/front-hub" --folders "packages/front-hub-docs/docs" --token ghp_xxx diff --git a/install-rdcontext-cursor.sh b/install-rdcontext-cursor.sh index 9110e38..168a805 100755 --- a/install-rdcontext-cursor.sh +++ b/install-rdcontext-cursor.sh @@ -145,11 +145,17 @@ configure_api_keys() { read -s -p "Digite sua API Key do Gemini (não será exibida): " GEMINI_API_KEY echo if [ -n "$GEMINI_API_KEY" ]; then - echo "export GEMINI_API_KEY=\"$GEMINI_API_KEY\"" >> ~/.bashrc - echo "export AI_PROVIDER=\"gemini\"" >> ~/.bashrc + CONFIG_STRING=" +# rdcontext configuration +export GEMINI_API_KEY=\"$GEMINI_API_KEY\" +export AI_PROVIDER=\"gemini\"" + echo "$CONFIG_STRING" >> ~/.bashrc + if [ -f ~/.zshrc ]; then + echo "$CONFIG_STRING" >> ~/.zshrc + fi export GEMINI_API_KEY="$GEMINI_API_KEY" export AI_PROVIDER="gemini" - log_success "✅ API Key do Gemini configurada!" + log_success "✅ API Key do Gemini configurada em ~/.bashrc e/ou ~/.zshrc!" else log_warning "⚠️ API Key vazia, Gemini não configurado" fi @@ -160,11 +166,17 @@ configure_api_keys() { read -s -p "Digite sua API Key da OpenAI (não será exibida): " OPENAI_API_KEY echo if [ -n "$OPENAI_API_KEY" ]; then - echo "export OPENAI_API_KEY=\"$OPENAI_API_KEY\"" >> ~/.bashrc - echo "export AI_PROVIDER=\"openai\"" >> ~/.bashrc + CONFIG_STRING=" +# rdcontext configuration +export OPENAI_API_KEY=\"$OPENAI_API_KEY\" +export AI_PROVIDER=\"openai\"" + echo "$CONFIG_STRING" >> ~/.bashrc + if [ -f ~/.zshrc ]; then + echo "$CONFIG_STRING" >> ~/.zshrc + fi export OPENAI_API_KEY="$OPENAI_API_KEY" export AI_PROVIDER="openai" - log_success "✅ API Key da OpenAI configurada!" + log_success "✅ API Key da OpenAI configurada em ~/.bashrc e/ou ~/.zshrc!" else log_warning "⚠️ API Key vazia, OpenAI não configurado" fi @@ -190,9 +202,15 @@ configure_github_token() { read -s -p "Digite seu GitHub Token (não será exibido): " GITHUB_TOKEN echo if [ -n "$GITHUB_TOKEN" ]; then - echo "export GITHUB_TOKEN=\"$GITHUB_TOKEN\"" >> ~/.bashrc + CONFIG_STRING=" +# rdcontext GitHub configuration +export GITHUB_TOKEN=\"$GITHUB_TOKEN\"" + echo "$CONFIG_STRING" >> ~/.bashrc + if [ -f ~/.zshrc ]; then + echo "$CONFIG_STRING" >> ~/.zshrc + fi export GITHUB_TOKEN="$GITHUB_TOKEN" - log_success "✅ GitHub Token configurado!" + log_success "✅ GitHub Token configurado em ~/.bashrc e/ou ~/.zshrc!" else log_warning "⚠️ Token vazio, GitHub Token não configurado" fi @@ -346,9 +364,9 @@ add_example_libraries() { log_success "FrontHub adicionado com sucesso!" log_info "Adicionando Tangram Design System..." - log_info "Comando: rdcontext add \"resultadosdigitais/tangram\" --folders \"docs/examples/componests\" \"docs/docs\" \"docs/code\" --token [GITHUB_TOKEN]" + log_info "Comando: rdcontext add \"resultadosdigitais/tangram\" --folders \"docs/examples/components\" \"docs/docs\" \"docs/code\" --token [GITHUB_TOKEN]" echo - rdcontext add "resultadosdigitais/tangram" --folders "docs/examples/componests" "docs/docs" "docs/code" --token "$GITHUB_TOKEN" + rdcontext add "resultadosdigitais/tangram" --folders "docs/examples/components" "docs/docs" "docs/code" --token "$GITHUB_TOKEN" log_success "Tangram adicionado com sucesso!" fi } @@ -392,7 +410,7 @@ show_next_steps() { echo "5. Comandos específicos para RD Station:" echo " rdcontext add \"resultadosdigitais/front-hub\" --folders \"packages/front-hub-docs/docs\" --token SEU_GITHUB_TOKEN" echo - echo " rdcontext add \"resultadosdigitais/tangram\" --folders \"docs/examples/componests\" \"docs/docs\" \"docs/code\" --token SEU_GITHUB_TOKEN" + echo " rdcontext add \"resultadosdigitais/tangram\" --folders \"docs/examples/components\" \"docs/docs\" \"docs/code\" --token SEU_GITHUB_TOKEN" echo echo echo "📚 Documentação completa:" From 6f9759dfc852a9d7d755d733bf7e216c5d213b34 Mon Sep 17 00:00:00 2001 From: Renata Matsumoto Date: Tue, 2 Sep 2025 17:50:07 -0300 Subject: [PATCH 04/13] Update install-rdcontext-cursor.sh Co-authored-by: typo-app[bot] <139475626+typo-app[bot]@users.noreply.github.com> --- install-rdcontext-cursor.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/install-rdcontext-cursor.sh b/install-rdcontext-cursor.sh index 168a805..89ca665 100755 --- a/install-rdcontext-cursor.sh +++ b/install-rdcontext-cursor.sh @@ -145,10 +145,7 @@ configure_api_keys() { read -s -p "Digite sua API Key do Gemini (não será exibida): " GEMINI_API_KEY echo if [ -n "$GEMINI_API_KEY" ]; then - CONFIG_STRING=" -# rdcontext configuration -export GEMINI_API_KEY=\"$GEMINI_API_KEY\" -export AI_PROVIDER=\"gemini\"" + CONFIG_STRING=$(printf '\n# rdcontext configuration\nexport GEMINI_API_KEY=%q\nexport AI_PROVIDER="gemini"' "$GEMINI_API_KEY") echo "$CONFIG_STRING" >> ~/.bashrc if [ -f ~/.zshrc ]; then echo "$CONFIG_STRING" >> ~/.zshrc From cd19234646f47539a8bab8506df97df5061c3ec2 Mon Sep 17 00:00:00 2001 From: Renata Matsumoto Date: Tue, 2 Sep 2025 17:50:13 -0300 Subject: [PATCH 05/13] Update install-rdcontext-cursor.sh Co-authored-by: typo-app[bot] <139475626+typo-app[bot]@users.noreply.github.com> --- install-rdcontext-cursor.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/install-rdcontext-cursor.sh b/install-rdcontext-cursor.sh index 89ca665..d825b0a 100755 --- a/install-rdcontext-cursor.sh +++ b/install-rdcontext-cursor.sh @@ -199,9 +199,7 @@ configure_github_token() { read -s -p "Digite seu GitHub Token (não será exibido): " GITHUB_TOKEN echo if [ -n "$GITHUB_TOKEN" ]; then - CONFIG_STRING=" -# rdcontext GitHub configuration -export GITHUB_TOKEN=\"$GITHUB_TOKEN\"" + CONFIG_STRING=$(printf '\n# rdcontext GitHub configuration\nexport GITHUB_TOKEN=%q' "$GITHUB_TOKEN") echo "$CONFIG_STRING" >> ~/.bashrc if [ -f ~/.zshrc ]; then echo "$CONFIG_STRING" >> ~/.zshrc From 0d464db6b7c9459715ae7fa3f99750e4fc3c8a2f Mon Sep 17 00:00:00 2001 From: Renata Matsumoto Date: Wed, 3 Sep 2025 11:37:03 -0300 Subject: [PATCH 06/13] =?UTF-8?q?refactor:=20torna=20script=20de=20instala?= =?UTF-8?q?=C3=A7=C3=A3o=20idempotente=20e=20mais=20limpo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adiciona função add_to_shell_config() para evitar duplicação de variáveis - Implementa verificação inteligente usando grep para detectar configurações existentes - Simplifica funções de log para melhor legibilidade - Remove código duplicado e funcionalidades desnecessárias - Simplifica configuração MCP removendo complexidade de merge - Resolve problema de duplicação identificado pelo bot de análise de código - Script agora pode ser executado múltiplas vezes sem problemas --- install-rdcontext-cursor.sh | 386 +++++++++--------------------------- 1 file changed, 89 insertions(+), 297 deletions(-) diff --git a/install-rdcontext-cursor.sh b/install-rdcontext-cursor.sh index d825b0a..70e3a3a 100755 --- a/install-rdcontext-cursor.sh +++ b/install-rdcontext-cursor.sh @@ -1,7 +1,7 @@ #!/bin/bash # Script de instalação do rdcontext focado no Cursor -# Versão limpa - sem verificação de variáveis existentes +# Versão idempotente - evita duplicar variáveis no shell set -e @@ -13,21 +13,10 @@ BLUE='\033[0;34m' NC='\033[0m' # No Color # Funções de log -log_info() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -log_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -log_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} +log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } +log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } +log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } print_header() { echo @@ -41,54 +30,61 @@ print_header() { echo } +# Adiciona variáveis de ambiente sem duplicar +add_to_shell_config() { + local config_file=$1 + local var_name=$2 + local config_string=$3 + + # Só adiciona se ainda não existir no arquivo + if ! grep -q "$var_name" "$config_file" 2>/dev/null; then + echo "$config_string" >> "$config_file" + log_success "Adicionado $var_name em $config_file" + else + log_info "$var_name já existe em $config_file, pulando..." + fi +} + # Verifica dependências check_dependencies() { log_info "Verificando dependências..." - - # Node.js - if ! command -v node &> /dev/null; then + + if ! command -v node &>/dev/null; then log_error "❌ Node.js não encontrado!" - echo "Instale Node.js 18+ de: https://nodejs.org/" + exit 1 + fi + NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1) + if [ "$NODE_VERSION" -lt 18 ]; then + log_error "❌ Node.js $(node --version) é muito antigo!" exit 1 else - NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1) - if [ "$NODE_VERSION" -lt 18 ]; then - log_error "❌ Node.js $(node --version) é muito antiga!" - echo "rdcontext requer Node.js 18+ para ES modules e top-level await" - exit 1 - else - log_success "Node.js $(node --version) ✅" - fi + log_success "Node.js $(node --version) ✅" fi - - # npm - if ! command -v npm &> /dev/null; then + + if ! command -v npm &>/dev/null; then log_error "❌ npm não encontrado!" exit 1 else log_success "npm $(npm --version) encontrado" fi - - # Git - if ! command -v git &> /dev/null; then + + if ! command -v git &>/dev/null; then log_error "❌ Git não encontrado!" exit 1 else log_success "Git $(git --version | cut -d' ' -f3) encontrado" fi - - # jq (para merge do mcp.json) - if ! command -v jq &> /dev/null; then + + if ! command -v jq &>/dev/null; then log_warning "⚠️ jq não encontrado. Instalando..." - if command -v apt-get &> /dev/null; then + if command -v apt-get &>/dev/null; then sudo apt-get update && sudo apt-get install -y jq - elif command -v yum &> /dev/null; then + elif command -v yum &>/dev/null; then sudo yum install -y jq - elif command -v brew &> /dev/null; then + elif command -v brew &>/dev/null; then brew install jq else log_error "❌ Não foi possível instalar jq automaticamente" - echo "Instale jq manualmente: https://jqlang.github.io/jq/" exit 1 fi log_success "jq instalado com sucesso" @@ -100,24 +96,8 @@ check_dependencies() { # Instala rdcontext install_rdcontext() { log_info "Instalando rdcontext..." - - if [ -f "package.json" ] && grep -q '"name": "rdcontext"' package.json; then - log_info "Detectado repositório local do rdcontext" - log_info "Instalando dependências..." - npm install - - log_info "Fazendo build..." - npm run build - - log_info "Instalando globalmente..." - npm install -g . - else - log_info "Instalando do GitHub..." - npm install -g git+https://github.com/resultadosdigitais/rdcontext.git - fi - - # Verifica instalação - if command -v rdcontext &> /dev/null; then + npm install -g git+https://github.com/resultadosdigitais/rdcontext.git + if command -v rdcontext &>/dev/null; then log_success "rdcontext $(rdcontext --version) instalado com sucesso!" else log_error "❌ Falha na instalação do rdcontext" @@ -129,89 +109,63 @@ install_rdcontext() { configure_api_keys() { echo log_info "Configurando API Keys..." - - # Sempre pergunta qual provedor usar - echo "Qual provedor de IA você deseja usar?" - echo "1) Gemini (Google) - Recomendado" + echo "1) Gemini (Google)" echo "2) OpenAI" - echo "3) Pular (configurar depois)" + echo "3) Pular" read -p "Escolha uma opção (1-3): " -n 1 -r echo - + case $REPLY in - 1) - echo - log_info "🔑 Configurando Gemini API Key..." - read -s -p "Digite sua API Key do Gemini (não será exibida): " GEMINI_API_KEY - echo - if [ -n "$GEMINI_API_KEY" ]; then - CONFIG_STRING=$(printf '\n# rdcontext configuration\nexport GEMINI_API_KEY=%q\nexport AI_PROVIDER="gemini"' "$GEMINI_API_KEY") - echo "$CONFIG_STRING" >> ~/.bashrc - if [ -f ~/.zshrc ]; then - echo "$CONFIG_STRING" >> ~/.zshrc - fi - export GEMINI_API_KEY="$GEMINI_API_KEY" - export AI_PROVIDER="gemini" - log_success "✅ API Key do Gemini configurada em ~/.bashrc e/ou ~/.zshrc!" - else - log_warning "⚠️ API Key vazia, Gemini não configurado" - fi - ;; - 2) - echo - log_info "🔑 Configurando OpenAI API Key..." - read -s -p "Digite sua API Key da OpenAI (não será exibida): " OPENAI_API_KEY - echo - if [ -n "$OPENAI_API_KEY" ]; then - CONFIG_STRING=" + 1) + read -s -p "Digite sua Gemini API Key: " GEMINI_API_KEY + echo + if [ -n "$GEMINI_API_KEY" ]; then + CONFIG_STRING=" +# rdcontext configuration +export GEMINI_API_KEY=\"$GEMINI_API_KEY\" +export AI_PROVIDER=\"gemini\" +export GEMINI_EMBEDDING_MODEL=\"text-embedding-004\"" + add_to_shell_config ~/.bashrc GEMINI_API_KEY "$CONFIG_STRING" + [ -f ~/.zshrc ] && add_to_shell_config ~/.zshrc GEMINI_API_KEY "$CONFIG_STRING" + export GEMINI_API_KEY="$GEMINI_API_KEY" + export AI_PROVIDER="gemini" + fi + ;; + 2) + read -s -p "Digite sua OpenAI API Key: " OPENAI_API_KEY + echo + if [ -n "$OPENAI_API_KEY" ]; then + CONFIG_STRING=" # rdcontext configuration export OPENAI_API_KEY=\"$OPENAI_API_KEY\" -export AI_PROVIDER=\"openai\"" - echo "$CONFIG_STRING" >> ~/.bashrc - if [ -f ~/.zshrc ]; then - echo "$CONFIG_STRING" >> ~/.zshrc - fi - export OPENAI_API_KEY="$OPENAI_API_KEY" - export AI_PROVIDER="openai" - log_success "✅ API Key da OpenAI configurada em ~/.bashrc e/ou ~/.zshrc!" - else - log_warning "⚠️ API Key vazia, OpenAI não configurado" - fi - ;; - 3) - log_info "Configuração de API Key pulada." - ;; +export AI_PROVIDER=\"openai\" +export OPENAI_EMBEDDING_MODEL=\"text-embedding-3-large\"" + add_to_shell_config ~/.bashrc OPENAI_API_KEY "$CONFIG_STRING" + [ -f ~/.zshrc ] && add_to_shell_config ~/.zshrc OPENAI_API_KEY "$CONFIG_STRING" + export OPENAI_API_KEY="$OPENAI_API_KEY" + export AI_PROVIDER="openai" + fi + ;; + *) log_info "Configuração de API Key pulada." ;; esac } # Configura GitHub Token configure_github_token() { echo - log_info "Configurando GitHub Token..." - - echo "Para acessar repositórios privados da RD Station, você precisa de um GitHub Token." - echo - read -p "Deseja configurar o GitHub Token agora? (y/n): " -n 1 -r + read -p "Deseja configurar GitHub Token agora? (y/n): " -n 1 -r echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - echo - read -s -p "Digite seu GitHub Token (não será exibido): " GITHUB_TOKEN + read -s -p "Digite seu GitHub Token: " GITHUB_TOKEN echo if [ -n "$GITHUB_TOKEN" ]; then - CONFIG_STRING=$(printf '\n# rdcontext GitHub configuration\nexport GITHUB_TOKEN=%q' "$GITHUB_TOKEN") - echo "$CONFIG_STRING" >> ~/.bashrc - if [ -f ~/.zshrc ]; then - echo "$CONFIG_STRING" >> ~/.zshrc - fi + CONFIG_STRING=" +# rdcontext GitHub configuration +export GITHUB_TOKEN=\"$GITHUB_TOKEN\"" + add_to_shell_config ~/.bashrc GITHUB_TOKEN "$CONFIG_STRING" + [ -f ~/.zshrc ] && add_to_shell_config ~/.zshrc GITHUB_TOKEN "$CONFIG_STRING" export GITHUB_TOKEN="$GITHUB_TOKEN" - log_success "✅ GitHub Token configurado em ~/.bashrc e/ou ~/.zshrc!" - else - log_warning "⚠️ Token vazio, GitHub Token não configurado" fi - else - log_info "GitHub Token não configurado. Configure depois com:" - echo "export GITHUB_TOKEN=\"seu_token_aqui\"" fi } @@ -219,202 +173,42 @@ configure_github_token() { configure_cursor_mcp() { local cursor_config_dir="$HOME/.cursor" local mcp_config="$cursor_config_dir/mcp.json" - + mkdir -p "$cursor_config_dir" - - # Backup do arquivo existente se houver - if [ -f "$mcp_config" ]; then - log_warning "Arquivo mcp.json já existe. Fazendo backup..." - cp "$mcp_config" "$mcp_config.backup.$(date +%Y%m%d_%H%M%S)" - fi + cp "$mcp_config" "$mcp_config.backup.$(date +%Y%m%d_%H%M%S)" 2>/dev/null || true - # Cria configuração temporária do rdcontext - local temp_rdcontext_config=$(mktemp) - - # Constrói o JSON de forma mais robusta - cat > "$temp_rdcontext_config" << EOF + cat >"$mcp_config" <> "$temp_rdcontext_config" - else - # Outras variáveis - com vírgula - echo "${env_vars[$i]}," >> "$temp_rdcontext_config" - fi - done - fi - - # Fecha o JSON - cat >> "$temp_rdcontext_config" << EOF + "GEMINI_API_KEY": "$GEMINI_API_KEY", + "OPENAI_API_KEY": "$OPENAI_API_KEY", + "GITHUB_TOKEN": "$GITHUB_TOKEN", + "AI_PROVIDER": "$AI_PROVIDER", + "GEMINI_EMBEDDING_MODEL": "text-embedding-004", + "OPENAI_EMBEDDING_MODEL": "text-embedding-3-large" } } } } EOF - - if [ -f "$mcp_config" ]; then - log_info "Fazendo merge com configurações MCP existentes..." - - # Valida o JSON existente antes do merge - if ! jq empty "$mcp_config" 2>/dev/null; then - log_error "❌ Arquivo mcp.json existente tem JSON inválido!" - log_info "Restaurando do backup..." - cp "$mcp_config.backup.$(date +%Y%m%d_%H%M%S)" "$mcp_config" 2>/dev/null || { - log_error "❌ Falha ao restaurar backup. Criando novo arquivo..." - rm -f "$mcp_config" - } - fi - - # Valida o JSON do rdcontext antes do merge - if ! jq empty "$temp_rdcontext_config" 2>/dev/null; then - log_error "❌ JSON do rdcontext é inválido!" - rm -f "$temp_rdcontext_config" - return 1 - fi - - # Faz o merge de forma mais segura - local merge_result=$(mktemp) - if jq -s '.[0] * .[1]' "$mcp_config" "$temp_rdcontext_config" > "$merge_result" 2>/dev/null; then - # Valida o resultado do merge - if jq empty "$merge_result" 2>/dev/null; then - mv "$merge_result" "$mcp_config" - log_success "Configuração MCP atualizada preservando outras configurações" - else - log_error "❌ Resultado do merge é JSON inválido!" - log_info "Restaurando configuração original..." - cp "$mcp_config.backup.$(date +%Y%m%d_%H%M%S)" "$mcp_config" 2>/dev/null - rm -f "$merge_result" - fi - else - log_error "❌ Falha no merge do JSON!" - log_info "Restaurando configuração original..." - cp "$mcp_config.backup.$(date +%Y%m%d_%H%M%S)" "$mcp_config" 2>/dev/null - rm -f "$merge_result" - fi - - rm -f "$temp_rdcontext_config" - else - # Cria novo arquivo - mv "$temp_rdcontext_config" "$mcp_config" - log_success "Nova configuração MCP criada" - fi - log_success "Configuração MCP criada em $mcp_config" - echo - log_info "⚠️ IMPORTANTE: Reinicie o Cursor para aplicar as configurações MCP!" -} - -# Adiciona bibliotecas de exemplo -add_example_libraries() { - echo - read -p "Deseja adicionar as bibliotecas da RD Station (Tangram e FrontHub)? (y/n): " add_examples - - if [[ $add_examples =~ ^[Yy]$ ]]; then - if [ -z "$GITHUB_TOKEN" ]; then - log_error "❌ GitHub Token necessário para adicionar bibliotecas da RD Station" - echo "Configure o token primeiro com: export GITHUB_TOKEN=\"seu_token\"" - return - fi - - # Verifica se tem API Key configurada - if [ -z "$GEMINI_API_KEY" ] && [ -z "$OPENAI_API_KEY" ]; then - log_error "❌ API Key necessária para processar documentação!" - echo "Configure uma API Key primeiro (Gemini ou OpenAI)" - return - fi - - log_info "Adicionando FrontHub..." - log_info "Comando: rdcontext add \"resultadosdigitais/front-hub\" --folders \"packages/front-hub-docs/docs\" --token [GITHUB_TOKEN]" - echo - rdcontext add "resultadosdigitais/front-hub" --folders "packages/front-hub-docs/docs" --token "$GITHUB_TOKEN" - log_success "FrontHub adicionado com sucesso!" - - log_info "Adicionando Tangram Design System..." - log_info "Comando: rdcontext add \"resultadosdigitais/tangram\" --folders \"docs/examples/components\" \"docs/docs\" \"docs/code\" --token [GITHUB_TOKEN]" - echo - rdcontext add "resultadosdigitais/tangram" --folders "docs/examples/components" "docs/docs" "docs/code" --token "$GITHUB_TOKEN" - log_success "Tangram adicionado com sucesso!" - fi } # Testa a instalação test_installation() { - log_info "Testando instalação..." - - if rdcontext --version &> /dev/null; then + if rdcontext --version &>/dev/null; then log_success "✅ rdcontext está funcionando!" else log_error "❌ Erro ao executar rdcontext" exit 1 fi - - # Lista bibliotecas - echo - log_info "Bibliotecas indexadas:" rdcontext list } -# Mostra próximos passos -show_next_steps() { - echo - echo "🎉 Instalação concluída com sucesso!" - echo - echo "📋 Próximos passos:" - echo - echo "1. Reinicie o Cursor para aplicar as configurações MCP" - echo - echo "2. No Cursor, teste digitando:" - echo " 'Mostre exemplos de botões do Tangram'" - echo - echo "3. Para adicionar mais bibliotecas:" - echo " rdcontext add \"owner/repo\" --folders \"pasta1\" \"pasta2\" --token SEU_GITHUB_TOKEN" - echo - echo "4. Comandos úteis:" - echo " rdcontext list # Lista bibliotecas" - echo " rdcontext get \"repo\" \"query\" # Busca contexto" - echo - echo "5. Comandos específicos para RD Station:" - echo " rdcontext add \"resultadosdigitais/front-hub\" --folders \"packages/front-hub-docs/docs\" --token SEU_GITHUB_TOKEN" - echo - echo " rdcontext add \"resultadosdigitais/tangram\" --folders \"docs/examples/components\" \"docs/docs\" \"docs/code\" --token SEU_GITHUB_TOKEN" - echo - echo - echo "📚 Documentação completa:" - echo " https://github.com/resultadosdigitais/rdcontext" - echo " README.md - Guia completo de instalação e uso" - echo -} - -# Função principal main() { print_header check_dependencies @@ -422,10 +216,8 @@ main() { configure_api_keys configure_github_token configure_cursor_mcp - add_example_libraries test_installation - show_next_steps + echo "🎉 Instalação concluída. Reinicie o Cursor para aplicar." } -# Executa o script main "$@" From 783cec0d650bc67bb85b240ff96458eb0189fbaa Mon Sep 17 00:00:00 2001 From: Renata Matsumoto Date: Wed, 3 Sep 2025 14:59:32 -0300 Subject: [PATCH 07/13] =?UTF-8?q?refactor:=20melhora=20script=20de=20insta?= =?UTF-8?q?la=C3=A7=C3=A3o=20com=20sugest=C3=B5es=20de=20robustez=20e=20po?= =?UTF-8?q?rtabilidade?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install-rdcontext-cursor.sh | 132 ++++++++++---- package-lock.json | 337 +++++++++++++++++++++++++++++++++++- 2 files changed, 436 insertions(+), 33 deletions(-) diff --git a/install-rdcontext-cursor.sh b/install-rdcontext-cursor.sh index 70e3a3a..4bf11c1 100755 --- a/install-rdcontext-cursor.sh +++ b/install-rdcontext-cursor.sh @@ -1,9 +1,9 @@ -#!/bin/bash +#!/usr/bin/env bash # Script de instalação do rdcontext focado no Cursor # Versão idempotente - evita duplicar variáveis no shell -set -e +set -euo pipefail # Cores para output RED='\033[0;31m' @@ -12,6 +12,12 @@ YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color +# Inicializa variáveis para evitar erros com set -u +GEMINI_API_KEY="" +OPENAI_API_KEY="" +GITHUB_TOKEN="" +AI_PROVIDER="gemini" # valor padrão + # Funções de log log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } @@ -36,12 +42,12 @@ add_to_shell_config() { local var_name=$2 local config_string=$3 - # Só adiciona se ainda não existir no arquivo - if ! grep -q "$var_name" "$config_file" 2>/dev/null; then + # Só adiciona se ainda não existir no arquivo (verifica declaração export real) + if ! grep -qE "^[[:space:]]*export[[:space:]]+$var_name=" "$config_file" 2>/dev/null; then echo "$config_string" >> "$config_file" log_success "Adicionado $var_name em $config_file" else - log_info "$var_name já existe em $config_file, pulando..." + log_info "$var_name já foi configurado em $config_file, pulando..." fi } @@ -53,7 +59,7 @@ check_dependencies() { log_error "❌ Node.js não encontrado!" exit 1 fi - NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1) + NODE_VERSION=$(node --version | sed 's/^v//' | cut -d'.' -f1) if [ "$NODE_VERSION" -lt 18 ]; then log_error "❌ Node.js $(node --version) é muito antigo!" exit 1 @@ -72,7 +78,7 @@ check_dependencies() { log_error "❌ Git não encontrado!" exit 1 else - log_success "Git $(git --version | cut -d' ' -f3) encontrado" + log_success "Git $(git --version | awk '{print $3}') encontrado" fi if ! command -v jq &>/dev/null; then @@ -93,12 +99,74 @@ check_dependencies() { fi } +# Função para instalação global do npm com fallback para ~/.local +npm_global_install() { + local PREFIX + PREFIX="$(npm config get prefix 2>/dev/null || echo '')" + if [ -n "$PREFIX" ] && [ -w "$PREFIX" ]; then + npm install -g "$@" + else + if npm install -g "$@"; then :; else + log_warning "Sem permissão no prefix do npm. Usando ~/.local" + mkdir -p "$HOME/.local" + npm install -g --prefix "$HOME/.local" "$@" + # Adiciona ao PATH se não estiver presente + ensure_path_contains "$HOME/.local/bin" + fi + fi +} + +# Adiciona um diretório ao PATH se não estiver presente +ensure_path_contains() { + local dir="$1" + if [[ ":$PATH:" != *":$dir:"* ]]; then + export PATH="$dir:$PATH" + # Adiciona ao .bashrc e .zshrc se existirem + for rcfile in ~/.bashrc ~/.zshrc; do + if [ -f "$rcfile" ] && ! grep -q "export PATH=\"$dir:\$PATH\"" "$rcfile"; then + echo "export PATH=\"$dir:\$PATH\"" >> "$rcfile" + log_info "Adicionado $dir ao PATH em $rcfile" + fi + done + fi +} + # Instala rdcontext install_rdcontext() { + log_info "Verificando se rdcontext já está instalado..." + + # Verifica se rdcontext já está funcionando + if command -v rdcontext &>/dev/null; then + log_success "rdcontext já está instalado e funcionando!" + if rdcontext --version &>/dev/null; then + log_success "Versão: $(rdcontext --version | tail -n1)" + return 0 + else + log_warning "rdcontext encontrado mas não está funcionando. Reinstalando..." + fi + fi + log_info "Instalando rdcontext..." - npm install -g git+https://github.com/resultadosdigitais/rdcontext.git + + # Remove instalação anterior se existir + if npm list -g rdcontext &>/dev/null; then + log_info "Removendo instalação anterior..." + npm uninstall -g rdcontext + fi + + # Verifica se estamos dentro do repositório rdcontext + if [ -f "./package.json" ] && grep -q "\"name\": \"rdcontext\"" "./package.json" 2>/dev/null; then + log_info "Instalando a partir do repositório local..." + npm install + npm run build + npm_global_install . + else + log_info "Instalando a partir do GitHub..." + npm_global_install git+https://github.com/resultadosdigitais/rdcontext.git + fi + if command -v rdcontext &>/dev/null; then - log_success "rdcontext $(rdcontext --version) instalado com sucesso!" + log_success "rdcontext $(rdcontext --version | tail -n1) instalado com sucesso!" else log_error "❌ Falha na instalação do rdcontext" exit 1 @@ -117,7 +185,7 @@ configure_api_keys() { case $REPLY in 1) - read -s -p "Digite sua Gemini API Key: " GEMINI_API_KEY + read -rs -p "Digite sua Gemini API Key: " GEMINI_API_KEY echo if [ -n "$GEMINI_API_KEY" ]; then CONFIG_STRING=" @@ -132,7 +200,7 @@ export GEMINI_EMBEDDING_MODEL=\"text-embedding-004\"" fi ;; 2) - read -s -p "Digite sua OpenAI API Key: " OPENAI_API_KEY + read -rs -p "Digite sua OpenAI API Key: " OPENAI_API_KEY echo if [ -n "$OPENAI_API_KEY" ]; then CONFIG_STRING=" @@ -156,7 +224,7 @@ configure_github_token() { read -p "Deseja configurar GitHub Token agora? (y/n): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then - read -s -p "Digite seu GitHub Token: " GITHUB_TOKEN + read -rs -p "Digite seu GitHub Token: " GITHUB_TOKEN echo if [ -n "$GITHUB_TOKEN" ]; then CONFIG_STRING=" @@ -177,24 +245,28 @@ configure_cursor_mcp() { mkdir -p "$cursor_config_dir" cp "$mcp_config" "$mcp_config.backup.$(date +%Y%m%d_%H%M%S)" 2>/dev/null || true - cat >"$mcp_config" < "$mcp_config" log_success "Configuração MCP criada em $mcp_config" } diff --git a/package-lock.json b/package-lock.json index 869ca97..c82da4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,23 +1,25 @@ { - "name": "libcontext", + "name": "rdcontext", "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "libcontext", + "name": "rdcontext", "version": "0.0.0", "dependencies": { + "@google/genai": "^0.2.0", "@libsql/client": "0.15.10", "@octokit/rest": "22.0.0", "drizzle-orm": "0.44.3", "fastmcp": "3.10.0", "openai": "5.10.1", + "sqlite-vec": "^0.1.7-alpha.2", "yargs": "18.0.0", "zod": "3.25.76" }, "bin": { - "libcontext": "dist/index.js" + "rdcontext": "dist/index.js" }, "devDependencies": { "@biomejs/biome": "2.1.1", @@ -1016,6 +1018,19 @@ "node": ">=18" } }, + "node_modules/@google/genai": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@google/genai/-/genai-0.2.0.tgz", + "integrity": "sha512-r7EiRHSqc6D1lDIMvM4OemjUwPpUbYb9jTxe1eLCiFbooHrmPc6U9z3n56E/iWzigkZmjRh4IC0CMzoB1aql9w==", + "license": "Apache-2.0", + "dependencies": { + "google-auth-library": "^9.14.2", + "ws": "^8.18.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@libsql/client": { "version": "0.15.10", "resolved": "https://registry.npmjs.org/@libsql/client/-/client-0.15.10.tgz", @@ -1446,6 +1461,15 @@ "node": ">= 0.6" } }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1483,11 +1507,40 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/before-after-hook": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==" }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/body-parser": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", @@ -1507,6 +1560,12 @@ "node": ">=18" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -1832,6 +1891,15 @@ "node": ">= 0.4" } }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -2050,6 +2118,12 @@ "express": ">= 4.11" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, "node_modules/fast-content-type-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", @@ -2215,6 +2289,68 @@ "node": ">=10" } }, + "node_modules/gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gaxios/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gaxios/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2296,6 +2432,32 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/google-auth-library": { + "version": "9.15.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", + "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -2307,6 +2469,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "license": "MIT", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -2352,6 +2527,19 @@ "node": ">= 0.8" } }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/human-signals": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", @@ -2451,11 +2639,41 @@ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.7.tgz", "integrity": "sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==" }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, "node_modules/libsql": { "version": "0.5.17", "resolved": "https://registry.npmjs.org/libsql/-/libsql-0.5.17.tgz", @@ -3013,6 +3231,84 @@ "source-map": "^0.6.0" } }, + "node_modules/sqlite-vec": { + "version": "0.1.7-alpha.2", + "resolved": "https://registry.npmjs.org/sqlite-vec/-/sqlite-vec-0.1.7-alpha.2.tgz", + "integrity": "sha512-rNgRCv+4V4Ed3yc33Qr+nNmjhtrMnnHzXfLVPeGb28Dx5mmDL3Ngw/Wk8vhCGjj76+oC6gnkmMG8y73BZWGBwQ==", + "license": "MIT OR Apache", + "optionalDependencies": { + "sqlite-vec-darwin-arm64": "0.1.7-alpha.2", + "sqlite-vec-darwin-x64": "0.1.7-alpha.2", + "sqlite-vec-linux-arm64": "0.1.7-alpha.2", + "sqlite-vec-linux-x64": "0.1.7-alpha.2", + "sqlite-vec-windows-x64": "0.1.7-alpha.2" + } + }, + "node_modules/sqlite-vec-darwin-arm64": { + "version": "0.1.7-alpha.2", + "resolved": "https://registry.npmjs.org/sqlite-vec-darwin-arm64/-/sqlite-vec-darwin-arm64-0.1.7-alpha.2.tgz", + "integrity": "sha512-raIATOqFYkeCHhb/t3r7W7Cf2lVYdf4J3ogJ6GFc8PQEgHCPEsi+bYnm2JT84MzLfTlSTIdxr4/NKv+zF7oLPw==", + "cpu": [ + "arm64" + ], + "license": "MIT OR Apache", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/sqlite-vec-darwin-x64": { + "version": "0.1.7-alpha.2", + "resolved": "https://registry.npmjs.org/sqlite-vec-darwin-x64/-/sqlite-vec-darwin-x64-0.1.7-alpha.2.tgz", + "integrity": "sha512-jeZEELsQjjRsVojsvU5iKxOvkaVuE+JYC8Y4Ma8U45aAERrDYmqZoHvgSG7cg1PXL3bMlumFTAmHynf1y4pOzA==", + "cpu": [ + "x64" + ], + "license": "MIT OR Apache", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/sqlite-vec-linux-arm64": { + "version": "0.1.7-alpha.2", + "resolved": "https://registry.npmjs.org/sqlite-vec-linux-arm64/-/sqlite-vec-linux-arm64-0.1.7-alpha.2.tgz", + "integrity": "sha512-6Spj4Nfi7tG13jsUG+W7jnT0bCTWbyPImu2M8nWp20fNrd1SZ4g3CSlDAK8GBdavX7wRlbBHCZ+BDa++rbDewA==", + "cpu": [ + "arm64" + ], + "license": "MIT OR Apache", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/sqlite-vec-linux-x64": { + "version": "0.1.7-alpha.2", + "resolved": "https://registry.npmjs.org/sqlite-vec-linux-x64/-/sqlite-vec-linux-x64-0.1.7-alpha.2.tgz", + "integrity": "sha512-IcgrbHaDccTVhXDf8Orwdc2+hgDLAFORl6OBUhcvlmwswwBP1hqBTSEhovClG4NItwTOBNgpwOoQ7Qp3VDPWLg==", + "cpu": [ + "x64" + ], + "license": "MIT OR Apache", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/sqlite-vec-windows-x64": { + "version": "0.1.7-alpha.2", + "resolved": "https://registry.npmjs.org/sqlite-vec-windows-x64/-/sqlite-vec-windows-x64-0.1.7-alpha.2.tgz", + "integrity": "sha512-TRP6hTjAcwvQ6xpCZvjP00pdlda8J38ArFy1lMYhtQWXiIBmWnhMaMbq4kaeCYwvTTddfidatRS+TJrwIKB/oQ==", + "cpu": [ + "x64" + ], + "license": "MIT OR Apache", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -3106,6 +3402,12 @@ "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, "node_modules/type-is": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", @@ -3193,6 +3495,19 @@ "resolved": "https://registry.npmjs.org/uri-templates/-/uri-templates-0.2.0.tgz", "integrity": "sha512-EWkjYEN0L6KOfEoOH6Wj4ghQqU7eBZMJqRHQnxQAq+dSEzRPClkWjf8557HkWQXF6BrAUoLSAyy9i3RVTliaNg==" }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -3209,6 +3524,22 @@ "node": ">= 8" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", From 0da53e86e4cf4159de8681a765a8df6b4a6de11d Mon Sep 17 00:00:00 2001 From: Renata Matsumoto Date: Wed, 3 Sep 2025 15:38:18 -0300 Subject: [PATCH 08/13] fix: corrige script para adicionar apenas chaves de API com valores reais MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Evita adicionar chaves vazias que causam falhas em runtime - Preserva configurações MCP existentes - Adiciona apenas chaves que têm valores definidos - Mantém modelos de embedding sempre configurados --- install-rdcontext-cursor.sh | 86 ++++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 21 deletions(-) diff --git a/install-rdcontext-cursor.sh b/install-rdcontext-cursor.sh index 4bf11c1..0ab216c 100755 --- a/install-rdcontext-cursor.sh +++ b/install-rdcontext-cursor.sh @@ -245,29 +245,73 @@ configure_cursor_mcp() { mkdir -p "$cursor_config_dir" cp "$mcp_config" "$mcp_config.backup.$(date +%Y%m%d_%H%M%S)" 2>/dev/null || true - # Gera JSON de forma segura usando jq para evitar corrupção por caracteres especiais - jq -n \ - --arg gemini_key "$GEMINI_API_KEY" \ - --arg openai_key "$OPENAI_API_KEY" \ - --arg github_token "$GITHUB_TOKEN" \ - --arg ai_provider "$AI_PROVIDER" \ - '{ - "mcpServers": { - "rdcontext": { - "command": "rdcontext", - "args": ["start"], - "env": { - "GEMINI_API_KEY": $gemini_key, - "OPENAI_API_KEY": $openai_key, - "GITHUB_TOKEN": $github_token, - "AI_PROVIDER": $ai_provider, - "GEMINI_EMBEDDING_MODEL": "text-embedding-004", - "OPENAI_EMBEDDING_MODEL": "text-embedding-3-large" + # Verifica se o arquivo mcp.json já existe + if [ -f "$mcp_config" ]; then + log_info "Atualizando configuração MCP existente..." + + # Atualiza o arquivo existente, preservando outras configurações + # Cria objeto de ambiente apenas com chaves que têm valores + local env_obj="{}" + if [ -n "$GEMINI_API_KEY" ]; then + env_obj=$(echo "$env_obj" | jq --arg key "$GEMINI_API_KEY" '. + {"GEMINI_API_KEY": $key}') + fi + if [ -n "$OPENAI_API_KEY" ]; then + env_obj=$(echo "$env_obj" | jq --arg key "$OPENAI_API_KEY" '. + {"OPENAI_API_KEY": $key}') + fi + if [ -n "$GITHUB_TOKEN" ]; then + env_obj=$(echo "$env_obj" | jq --arg key "$GITHUB_TOKEN" '. + {"GITHUB_TOKEN": $key}') + fi + if [ -n "$AI_PROVIDER" ]; then + env_obj=$(echo "$env_obj" | jq --arg provider "$AI_PROVIDER" '. + {"AI_PROVIDER": $provider}') + fi + + # Sempre adiciona os modelos de embedding + env_obj=$(echo "$env_obj" | jq '. + {"GEMINI_EMBEDDING_MODEL": "text-embedding-004"}') + env_obj=$(echo "$env_obj" | jq '. + {"OPENAI_EMBEDDING_MODEL": "text-embedding-3-large"}') + + jq --argjson env "$env_obj" \ + '.mcpServers.rdcontext = { + "command": "rdcontext", + "args": ["start"], + "env": $env + }' \ + "$mcp_config" > "$mcp_config.tmp" && mv "$mcp_config.tmp" "$mcp_config" + log_success "Configuração MCP atualizada em $mcp_config" + else + # Cria um novo arquivo se não existir + log_info "Criando nova configuração MCP..." + + # Cria objeto de ambiente apenas com chaves que têm valores + local env_obj="{}" + if [ -n "$GEMINI_API_KEY" ]; then + env_obj=$(echo "$env_obj" | jq --arg key "$GEMINI_API_KEY" '. + {"GEMINI_API_KEY": $key}') + fi + if [ -n "$OPENAI_API_KEY" ]; then + env_obj=$(echo "$env_obj" | jq --arg key "$OPENAI_API_KEY" '. + {"OPENAI_API_KEY": $key}') + fi + if [ -n "$GITHUB_TOKEN" ]; then + env_obj=$(echo "$env_obj" | jq --arg key "$GITHUB_TOKEN" '. + {"GITHUB_TOKEN": $key}') + fi + if [ -n "$AI_PROVIDER" ]; then + env_obj=$(echo "$env_obj" | jq --arg provider "$AI_PROVIDER" '. + {"AI_PROVIDER": $provider}') + fi + + # Sempre adiciona os modelos de embedding + env_obj=$(echo "$env_obj" | jq '. + {"GEMINI_EMBEDDING_MODEL": "text-embedding-004"}') + env_obj=$(echo "$env_obj" | jq '. + {"OPENAI_EMBEDDING_MODEL": "text-embedding-3-large"}') + + jq -n --argjson env "$env_obj" \ + '{ + "mcpServers": { + "rdcontext": { + "command": "rdcontext", + "args": ["start"], + "env": $env } } - } - }' > "$mcp_config" - log_success "Configuração MCP criada em $mcp_config" + }' > "$mcp_config" + log_success "Configuração MCP criada em $mcp_config" + fi } # Testa a instalação From 6f066159ebfd6c98c1c08ee9744239a411d7dbc0 Mon Sep 17 00:00:00 2001 From: Renata Matsumoto Date: Wed, 3 Sep 2025 15:50:56 -0300 Subject: [PATCH 09/13] =?UTF-8?q?fix:=20implementa=20merge=20inteligente?= =?UTF-8?q?=20para=20configura=C3=A7=C3=B5es=20MCP=20em=20vez=20de=20sobre?= =?UTF-8?q?screver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Evita apagar configurações personalizadas do usuário - Faz merge das configurações existentes com novas - Preserva integridade das configurações MCP - Implementa sugestão do Typo para maior robustez --- install-rdcontext-cursor.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/install-rdcontext-cursor.sh b/install-rdcontext-cursor.sh index 0ab216c..dbf8400 100755 --- a/install-rdcontext-cursor.sh +++ b/install-rdcontext-cursor.sh @@ -270,11 +270,7 @@ configure_cursor_mcp() { env_obj=$(echo "$env_obj" | jq '. + {"OPENAI_EMBEDDING_MODEL": "text-embedding-3-large"}') jq --argjson env "$env_obj" \ - '.mcpServers.rdcontext = { - "command": "rdcontext", - "args": ["start"], - "env": $env - }' \ + '.mcpServers.rdcontext |= ((. // { "env": {} }) + { "command": "rdcontext", "args": ["start"] } | .env += $env)' \ "$mcp_config" > "$mcp_config.tmp" && mv "$mcp_config.tmp" "$mcp_config" log_success "Configuração MCP atualizada em $mcp_config" else From a297639973ab96f7935d142cd7deed3240d1db0d Mon Sep 17 00:00:00 2001 From: Renata Matsumoto Date: Wed, 3 Sep 2025 18:15:53 -0300 Subject: [PATCH 10/13] =?UTF-8?q?feat:=20restaura=20funcionalidade=20compl?= =?UTF-8?q?eta=20do=20script=20de=20instala=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - RESTAURA função add_example_libraries() para adicionar FrontHub e Tangram automaticamente - RESTAURA função show_next_steps() com instruções completas pós-instalação - CORRIGE problemas de autenticação GitHub (limpeza de caracteres especiais \r) - MELHORA validação e limpeza do GitHub Token antes de usar - CORRIGE warning do ShellCheck (adiciona flag -r ao comando read) - ATUALIZA fluxo principal para incluir todas as funcionalidades restauradas - MANTÉM funcionalidade original: instalação + configuração + adição de bibliotecas Resolve o erro 401 (Bad credentials) que ocorria ao tentar adicionar bibliotecas da RD Station --- install-rdcontext-cursor.sh | 91 +++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 4 deletions(-) diff --git a/install-rdcontext-cursor.sh b/install-rdcontext-cursor.sh index dbf8400..c0633ed 100755 --- a/install-rdcontext-cursor.sh +++ b/install-rdcontext-cursor.sh @@ -44,7 +44,9 @@ add_to_shell_config() { # Só adiciona se ainda não existir no arquivo (verifica declaração export real) if ! grep -qE "^[[:space:]]*export[[:space:]]+$var_name=" "$config_file" 2>/dev/null; then - echo "$config_string" >> "$config_file" + # Garante que não há caracteres especiais na string de configuração + CLEAN_CONFIG=$(echo "$config_string" | tr -d '\r') + echo "$CLEAN_CONFIG" >> "$config_file" log_success "Adicionado $var_name em $config_file" else log_info "$var_name já foi configurado em $config_file, pulando..." @@ -227,12 +229,17 @@ configure_github_token() { read -rs -p "Digite seu GitHub Token: " GITHUB_TOKEN echo if [ -n "$GITHUB_TOKEN" ]; then + # Limpa o token de caracteres especiais + CLEAN_TOKEN=$(echo "$GITHUB_TOKEN" | tr -d '\r\n' | xargs) CONFIG_STRING=" # rdcontext GitHub configuration -export GITHUB_TOKEN=\"$GITHUB_TOKEN\"" +export GITHUB_TOKEN=\"$CLEAN_TOKEN\"" add_to_shell_config ~/.bashrc GITHUB_TOKEN "$CONFIG_STRING" [ -f ~/.zshrc ] && add_to_shell_config ~/.zshrc GITHUB_TOKEN "$CONFIG_STRING" - export GITHUB_TOKEN="$GITHUB_TOKEN" + export GITHUB_TOKEN="$CLEAN_TOKEN" + log_success "✅ GitHub Token configurado e limpo!" + else + log_warning "⚠️ Token vazio, GitHub Token não configurado" fi fi } @@ -310,6 +317,50 @@ configure_cursor_mcp() { fi } +# Adiciona bibliotecas de exemplo +add_example_libraries() { + echo + read -r -p "Deseja adicionar as bibliotecas da RD Station (Tangram e FrontHub)? (y/n): " add_examples + + if [[ $add_examples =~ ^[Yy]$ ]]; then + if [ -z "$GITHUB_TOKEN" ]; then + log_error "❌ GitHub Token necessário para adicionar bibliotecas da RD Station" + echo "Configure o token primeiro com: export GITHUB_TOKEN=\"seu_token\"" + return + fi + + # Valida e limpa o token + CLEAN_TOKEN=$(echo "$GITHUB_TOKEN" | tr -d '\r\n' | xargs) + if [ -z "$CLEAN_TOKEN" ]; then + log_error "❌ GitHub Token está vazio após limpeza" + return + fi + + log_info "🔑 Token GitHub validado e limpo" + + # Verifica se tem API Key configurada + if [ -z "$GEMINI_API_KEY" ] && [ -z "$OPENAI_API_KEY" ]; then + log_error "❌ API Key necessária para processar documentação!" + echo "Configure uma API Key primeiro (Gemini ou OpenAI)" + return + fi + + log_info "Adicionando FrontHub..." + log_info "Comando: rdcontext add \"resultadosdigitais/front-hub\" --folders \"packages/front-hub-docs/docs\" --token [GITHUB_TOKEN]" + echo + # Limpa o token de caracteres especiais e espaços + CLEAN_TOKEN=$(echo "$GITHUB_TOKEN" | tr -d '\r\n' | xargs) + rdcontext add "resultadosdigitais/front-hub" --folders "packages/front-hub-docs/docs" --token "$CLEAN_TOKEN" + log_success "FrontHub adicionado com sucesso!" + + log_info "Adicionando Tangram Design System..." + log_info "Comando: rdcontext add \"resultadosdigitais/tangram\" --folders \"docs/examples/components\" \"docs/docs\" \"docs/code\" --token [GITHUB_TOKEN]" + echo + rdcontext add "resultadosdigitais/tangram" --folders "docs/examples/components" "docs/docs" "docs/code" --token "$CLEAN_TOKEN" + log_success "Tangram adicionado com sucesso!" + fi +} + # Testa a instalação test_installation() { if rdcontext --version &>/dev/null; then @@ -321,6 +372,37 @@ test_installation() { rdcontext list } +# Mostra próximos passos +show_next_steps() { + echo + echo "🎉 Instalação concluída com sucesso!" + echo + echo "📋 Próximos passos:" + echo + echo "1. Reinicie o Cursor para aplicar as configurações MCP" + echo + echo "2. No Cursor, teste digitando:" + echo " 'Mostre exemplos de botões do Tangram'" + echo + echo "3. Para adicionar mais bibliotecas:" + echo " rdcontext add \"owner/repo\" --folders \"pasta1\" \"pasta2\" --token SEU_GITHUB_TOKEN" + echo + echo "4. Comandos úteis:" + echo " rdcontext list # Lista bibliotecas" + echo " rdcontext get \"repo\" \"query\" # Busca contexto" + echo + echo "5. Comandos específicos para RD Station:" + echo " rdcontext add \"resultadosdigitais/front-hub\" --folders \"packages/front-hub-docs/docs\" --token SEU_GITHUB_TOKEN" + echo + echo " rdcontext add \"resultadosdigitais/tangram\" --folders \"docs/examples/components\" \"docs/docs\" \"docs/code\" --token SEU_GITHUB_TOKEN" + echo + echo + echo "📚 Documentação completa:" + echo " https://github.com/resultadosdigitais/rdcontext" + echo " README.md - Guia completo de instalação e uso" + echo +} + main() { print_header check_dependencies @@ -328,8 +410,9 @@ main() { configure_api_keys configure_github_token configure_cursor_mcp + add_example_libraries test_installation - echo "🎉 Instalação concluída. Reinicie o Cursor para aplicar." + show_next_steps } main "$@" From 825525b6d3e3e05ebed177501f35fa284e3dc325 Mon Sep 17 00:00:00 2001 From: Renata Matsumoto Date: Thu, 11 Sep 2025 14:02:02 -0300 Subject: [PATCH 11/13] =?UTF-8?q?feat:=20adiciona=20verifica=C3=A7=C3=A3o?= =?UTF-8?q?=20e=20instala=C3=A7=C3=A3o=20autom=C3=A1tica=20do=20Bun?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adiciona verificação do Bun na função check_dependencies() - Instala Bun automaticamente se não estiver presente - Configura PATH para ~/.bun/bin automaticamente - Recarrega shell configs (.bashrc/.zshrc) após instalação - Garante compatibilidade com scripts que dependem do Bun (dev, build, lint) - Melhora consistência entre script de instalação e dependências do projeto --- install-rdcontext-cursor.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/install-rdcontext-cursor.sh b/install-rdcontext-cursor.sh index c0633ed..98a7f57 100755 --- a/install-rdcontext-cursor.sh +++ b/install-rdcontext-cursor.sh @@ -99,6 +99,28 @@ check_dependencies() { else log_success "jq encontrado" fi + + # Verifica Bun + if ! command -v bun &>/dev/null; then + log_warning "⚠️ Bun não encontrado. Instalando..." + if curl -fsSL https://bun.sh/install | bash; then + # Recarrega o shell para disponibilizar o bun no PATH + if [ -f ~/.bashrc ]; then + source ~/.bashrc 2>/dev/null || true + fi + if [ -f ~/.zshrc ]; then + source ~/.zshrc 2>/dev/null || true + fi + # Adiciona ~/.bun/bin ao PATH se necessário + ensure_path_contains "$HOME/.bun/bin" + log_success "Bun instalado com sucesso" + else + log_error "❌ Falha na instalação do Bun" + exit 1 + fi + else + log_success "Bun $(bun --version) encontrado" + fi } # Função para instalação global do npm com fallback para ~/.local From fe7ea9fdaa77354b5d4c28598facd56eedfcd3d7 Mon Sep 17 00:00:00 2001 From: Renata Matsumoto Date: Thu, 11 Sep 2025 14:06:38 -0300 Subject: [PATCH 12/13] fix: corrige warnings do ShellCheck MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adiciona diretivas shellcheck source=/dev/null para source de arquivos de configuração - Remove warnings SC1090 sobre source não-constante - Mantém funcionalidade intacta --- install-rdcontext-cursor.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install-rdcontext-cursor.sh b/install-rdcontext-cursor.sh index 98a7f57..2f5f725 100755 --- a/install-rdcontext-cursor.sh +++ b/install-rdcontext-cursor.sh @@ -106,9 +106,11 @@ check_dependencies() { if curl -fsSL https://bun.sh/install | bash; then # Recarrega o shell para disponibilizar o bun no PATH if [ -f ~/.bashrc ]; then + # shellcheck source=/dev/null source ~/.bashrc 2>/dev/null || true fi if [ -f ~/.zshrc ]; then + # shellcheck source=/dev/null source ~/.zshrc 2>/dev/null || true fi # Adiciona ~/.bun/bin ao PATH se necessário From 5c0f4107de6ec9548904675c88484c3db6afd7fd Mon Sep 17 00:00:00 2001 From: Renata Matsumoto Date: Thu, 11 Sep 2025 14:31:11 -0300 Subject: [PATCH 13/13] =?UTF-8?q?refactor:=20modifica=20verifica=C3=A7?= =?UTF-8?q?=C3=A3o=20do=20Bun=20para=20apenas=20checar=20e=20informar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove instalação automática do Bun - Adiciona verificação obrigatória do Bun - Exibe mensagem informativa com instruções de instalação - Falha graciosamente se Bun não estiver presente - Mantém funcionalidade quando Bun está instalado O script agora apenas verifica se o Bun está presente e informa ao usuário como instalá-lo, sem fazer instalação automática. --- install-rdcontext-cursor.sh | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/install-rdcontext-cursor.sh b/install-rdcontext-cursor.sh index 2f5f725..93d2805 100755 --- a/install-rdcontext-cursor.sh +++ b/install-rdcontext-cursor.sh @@ -102,24 +102,18 @@ check_dependencies() { # Verifica Bun if ! command -v bun &>/dev/null; then - log_warning "⚠️ Bun não encontrado. Instalando..." - if curl -fsSL https://bun.sh/install | bash; then - # Recarrega o shell para disponibilizar o bun no PATH - if [ -f ~/.bashrc ]; then - # shellcheck source=/dev/null - source ~/.bashrc 2>/dev/null || true - fi - if [ -f ~/.zshrc ]; then - # shellcheck source=/dev/null - source ~/.zshrc 2>/dev/null || true - fi - # Adiciona ~/.bun/bin ao PATH se necessário - ensure_path_contains "$HOME/.bun/bin" - log_success "Bun instalado com sucesso" - else - log_error "❌ Falha na instalação do Bun" - exit 1 - fi + log_error "❌ Bun não encontrado!" + echo + echo "📦 O rdcontext requer o Bun para funcionar corretamente." + echo " Scripts como 'npm run dev', 'npm run build' e 'npm run lint' dependem do Bun." + echo + echo "🔧 Para instalar o Bun:" + echo " curl -fsSL https://bun.sh/install | bash" + echo + echo " Ou visite: https://bun.sh/docs/installation" + echo + log_error "❌ Instale o Bun e execute este script novamente." + exit 1 else log_success "Bun $(bun --version) encontrado" fi