mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-04-25 00:16:29 +02:00
- Add step-by-step testing procedures for all components - Include manual Device Flow authentication testing - Add LLM provider testing examples - Include token storage and refresh verification - Add model discovery and disconnection tests - Provide troubleshooting guide - Add security notes and best practices
7.7 KiB
7.7 KiB
GitHub Copilot Integration - End-to-End Testing Guide
Este documento describe cómo realizar pruebas end-to-end completas de la integración de GitHub Copilot en Rowboat.
Requisitos Previos
- Rowboat compilado y funcionando (
npm run depssin errores) - Cuenta de GitHub activa
- Acceso a GitHub Copilot (Student, Pro, o Enterprise)
Test 1: Verificar Compilación
cd /home/wilber/rowboat/apps/x
# Compilar todas las dependencias
npm run deps
# Verificar que no hay errores de TypeScript
npm run lint
# Expected output:
# ✓ shared compiled successfully
# ✓ core compiled successfully
# ✓ preload compiled successfully
Test 2: Verificar Tests Unitarios
# Ejecutar tests de GitHub Copilot
npm test -- github-copilot.test.ts
# Expected output:
# ✓ GitHub Copilot Device Flow
# ✓ requestDeviceCode
# ✓ pollForToken
# ✓ startGitHubCopilotAuth
# ✓ OAuthTokens validation
# ✓ GitHub Copilot Models
# ✓ Model availability
# ✓ Model constants
#
# Tests: 25+ passed
Test 3: Device Flow Authentication (Manual)
Paso 1: Crear un script de prueba
Crea /tmp/test-github-copilot-auth.ts:
import container from '@x/core/di/container';
import { startGitHubCopilotAuthentication, isGitHubCopilotAuthenticated, getGitHubCopilotAuthStatus } from '@x/core/auth/github-copilot-auth';
async function testAuth() {
console.log('Starting GitHub Copilot authentication test...\n');
// Paso 1: Iniciar autenticación
console.log('1️⃣ Iniciando Device Flow...');
const { userCode, verificationUri, tokenPromise } = await startGitHubCopilotAuthentication();
console.log(`\n📱 Código de dispositivo: ${userCode}`);
console.log(`🔗 Visita: ${verificationUri}`);
console.log('\n⏳ Esperando autorización... (timeout en 15 minutos)\n');
try {
// Paso 2: Esperar autenticación
await tokenPromise;
console.log('✅ ¡Autenticado exitosamente!\n');
// Paso 3: Verificar estado
const authenticated = await isGitHubCopilotAuthenticated();
console.log(`2️⃣ ¿Autenticado? ${authenticated ? '✅ Sí' : '❌ No'}`);
const status = await getGitHubCopilotAuthStatus();
console.log(`3️⃣ Estado:`, JSON.stringify(status, null, 2));
console.log('\n✨ Test completo exitosamente');
} catch (error) {
console.error('\n❌ Error:', error);
process.exit(1);
}
}
testAuth();
Paso 2: Ejecutar el test
cd /home/wilber/rowboat/apps/x
npx ts-node /tmp/test-github-copilot-auth.ts
# Expected output:
# 1️⃣ Iniciando Device Flow...
#
# 📱 Código de dispositivo: ABCD-1234
# 🔗 Visita: https://github.com/login/device
#
# ⏳ Esperando autorización... (timeout en 15 minutos)
#
# (Usuario visita GitHub, ingresa código ABCD-1234)
#
# ✅ ¡Autenticado exitosamente!
#
# 2️⃣ ¿Autenticado? ✅ Sí
# 3️⃣ Estado: {
# "authenticated": true,
# "expiresAt": 1234567890
# }
#
# ✨ Test completo exitosamente
Test 4: Crear proveedor LLM
import { createProvider } from '@x/core/models/models';
import { generateText } from 'ai';
async function testLLM() {
console.log('Testing GitHub Copilot LLM...\n');
// Crear proveedor
console.log('1️⃣ Creando proveedor GitHub Copilot...');
const config = {
flavor: 'github-copilot' as const,
};
const provider = await createProvider(config);
console.log('✅ Proveedor creado\n');
// Crear modelo
console.log('2️⃣ Creando modelo gpt-4o...');
const model = provider.languageModel('gpt-4o');
console.log('✅ Modelo creado\n');
// Generar texto
console.log('3️⃣ Enviando prompt a GitHub Copilot...');
const response = await generateText({
model,
prompt: 'Say hello in Spanish',
});
console.log('✅ Respuesta recibida:\n');
console.log(response.text);
}
testLLM();
Test 5: Verificar Almacenamiento de Tokens
# Ver tokens guardados
cat ~/.rowboat/config/oauth.json | jq '.providers."github-copilot"'
# Expected output:
# {
# "tokens": {
# "access_token": "ghu_...",
# "refresh_token": null,
# "expires_at": 1234567890,
# "token_type": "Bearer",
# "scopes": ["read:user", "user:email", "gist"]
# },
# "clientId": "Iv1.b507a08c87ecfe98"
# }
Test 6: Probar Refresh de Tokens
import { getGitHubCopilotAccessToken } from '@x/core/auth/github-copilot-auth';
import * as oauthClient from '@x/core/auth/oauth-client';
async function testTokenRefresh() {
console.log('Testing token refresh...\n');
// Obtener token actual
console.log('1️⃣ Obteniendo token de acceso...');
const token = await getGitHubCopilotAccessToken();
console.log(`✅ Token: ${token.substring(0, 20)}...\n`);
// Verificar expiración
console.log('2️⃣ Verificando expiración...');
const connection = await container.resolve('oauthRepo').read('github-copilot');
if (connection.tokens) {
const expiresIn = connection.tokens.expires_at - Math.floor(Date.now() / 1000);
console.log(`✅ Token expira en: ${expiresIn} segundos`);
if (expiresIn > 3600) {
console.log(' (Aún es válido por más de 1 hora)\n');
}
}
}
testTokenRefresh();
Test 7: Listar Modelos Disponibles
import { getAvailableGitHubCopilotModels } from '@x/core/auth/github-copilot-models';
async function testModels() {
console.log('Modelos disponibles en GitHub Copilot:\n');
const models = await getAvailableGitHubCopilotModels();
models.forEach((model, i) => {
console.log(`${i + 1}. ${model}`);
});
}
testModels();
Test 8: Desconectar GitHub Copilot
import { disconnectGitHubCopilot, isGitHubCopilotAuthenticated } from '@x/core/auth/github-copilot-auth';
async function testDisconnect() {
console.log('Desconectando GitHub Copilot...\n');
console.log('1️⃣ Estado antes: ', await isGitHubCopilotAuthenticated());
await disconnectGitHubCopilot();
console.log('2️⃣ Estado después: ', await isGitHubCopilotAuthenticated());
console.log('\n✅ Desconectado correctamente');
}
testDisconnect();
Verificación de Checklist
- Compilación exitosa sin errores TypeScript
- Tests unitarios pasan (25+ casos)
- Device Flow funciona y abre el navegador
- Usuario puede completar autenticación en GitHub
- Tokens se guardan en
~/.rowboat/config/oauth.json - Proveedor LLM se crea correctamente
- Modelo responde a prompts
- Token se actualiza automáticamente si expira
- Tokens se eliminan al desconectar
- Modelos disponibles se listan correctamente
Troubleshooting
Error: "GitHub Copilot not authenticated"
- Ejecutar Device Flow nuevamente:
startGitHubCopilotAuthentication() - Verificar que tokens existen:
cat ~/.rowboat/config/oauth.json
Error: "Token expired"
- El sistema debería intentar refresh automático
- Si falla, ejecutar Device Flow nuevamente
Error: "Cannot reach API"
- Verificar conexión a internet
- Verificar que
https://models.github.com/api/openai/es accesible - Verificar que token es válido:
npm run test -- github-copilot
Error: "Model not found"
- Verificar que el modelo está disponible en tu plan
- Usar
gpt-4ocomo fallback
Recursos Adicionales
- GITHUB_COPILOT_INTEGRATION.md - Documentación técnica completa
- RFC 8628 - Device Flow OAuth spec
- GitHub Copilot Docs - Documentación oficial
Notas de Seguridad
- Nunca compartas tu código de dispositivo
- Los tokens se almacenan en
~/.rowboat/config/oauth.json- asegúrate de que los permisos son correctos - Desconecta cuando no uses GitHub Copilot
- Los tokens expiran automáticamente (generalmente en 8 horas)