๐Ÿ“… let's chat! explore the endless possibilities creating industries that don't exist. click here

openevidence-debug-bundle

Generate comprehensive debug information for OpenEvidence integration issues. Use when troubleshooting complex problems, preparing support tickets, or conducting post-incident analysis. Trigger with phrases like "openevidence debug", "openevidence troubleshoot", "openevidence support bundle", "diagnose openevidence". allowed-tools: Read, Grep, Bash(curl:*), Bash(npm:*), Bash(node:*) version: 1.0.0 license: MIT author: Jeremy Longshore <jeremy@intentsolutions.io>

Allowed Tools

No tools specified

Provided by Plugin

openevidence-pack

Claude Code skill pack for OpenEvidence medical AI (24 skills)

saas packs v1.0.0
View Plugin

Installation

This skill is included in the openevidence-pack plugin:

/plugin install openevidence-pack@claude-code-plugins-plus

Click to copy

Instructions

# OpenEvidence Debug Bundle ## Overview Generate comprehensive diagnostic information for troubleshooting OpenEvidence integration issues without exposing PHI. ## Prerequisites - OpenEvidence SDK installed - Access to application logs - Command-line access - curl installed ## Instructions ### Step 1: Environment Check Script ```bash #!/bin/bash # scripts/openevidence-debug.sh echo "=== OpenEvidence Debug Bundle ===" echo "Generated: $(date -u +%Y-%m-%dT%H:%M:%SZ)" echo "" # 1. Environment Variables (masked) echo "=== Environment Configuration ===" echo "OPENEVIDENCE_API_KEY: ${OPENEVIDENCE_API_KEY:+[SET - ${#OPENEVIDENCE_API_KEY} chars]}" echo "OPENEVIDENCE_ORG_ID: ${OPENEVIDENCE_ORG_ID:+[SET - ${#OPENEVIDENCE_ORG_ID} chars]}" echo "OPENEVIDENCE_BASE_URL: ${OPENEVIDENCE_BASE_URL:-https://api.openevidence.com}" echo "OPENEVIDENCE_TIMEOUT: ${OPENEVIDENCE_TIMEOUT:-30000}ms" echo "NODE_ENV: ${NODE_ENV:-not set}" echo "" # 2. SDK Version echo "=== SDK Version ===" npm list @openevidence/sdk 2>/dev/null || pip show openevidence 2>/dev/null || echo "SDK not found" echo "" # 3. Node/Python Version echo "=== Runtime Version ===" node --version 2>/dev/null || echo "Node.js not found" python3 --version 2>/dev/null || echo "Python not found" echo "" # 4. Connectivity Test echo "=== Connectivity Test ===" HEALTH_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \ -H "Authorization: Bearer ${OPENEVIDENCE_API_KEY}" \ "${OPENEVIDENCE_BASE_URL:-https://api.openevidence.com}/health" 2>/dev/null) echo "Health endpoint: HTTP ${HEALTH_STATUS}" DNS_CHECK=$(dig +short api.openevidence.com 2>/dev/null || echo "DNS lookup failed") echo "DNS resolution: ${DNS_CHECK}" echo "" # 5. TLS Check echo "=== TLS Configuration ===" openssl s_client -connect api.openevidence.com:443 -brief 2>/dev/null | head -5 || echo "TLS check failed" echo "" # 6. Rate Limit Status echo "=== Rate Limit Status ===" curl -s -D - \ -H "Authorization: Bearer ${OPENEVIDENCE_API_KEY}" \ "${OPENEVIDENCE_BASE_URL:-https://api.openevidence.com}/v1/rate-limit" 2>/dev/null \ | grep -i "x-ratelimit" || echo "Could not retrieve rate limit headers" echo "" echo "=== Debug Bundle Complete ===" ``` ### Step 2: Programmatic Debug Collection ```typescript // src/debug/debug-bundle.ts import { OpenEvidenceClient } from '@openevidence/sdk'; import { execSync } from 'child_process'; interface DebugBundle { timestamp: string; environment: EnvironmentInfo; connectivity: ConnectivityInfo; sdkInfo: SDKInfo; recentErrors: ErrorSummary[]; metrics: MetricsSummary; } interface EnvironmentInfo { nodeVersion: string; sdkVersion: string; apiKeySet: boolean; apiKeyLength: number; orgIdSet: boolean; baseUrl: string; timeout: number; } interface ConnectivityInfo { healthStatus: number | null; latencyMs: number | null; dnsResolution: boolean; tlsVersion: string | null; } interface SDKInfo { version: string; features: string[]; } interface ErrorSummary { code: string; count: number; lastOccurred: string; } interface MetricsSummary { totalRequests: number; successRate: number; avgLatencyMs: number; p99LatencyMs: number; } export async function generateDebugBundle(): Promise { const timestamp = new Date().toISOString(); // Gather environment info const environment = gatherEnvironmentInfo(); // Test connectivity const connectivity = await testConnectivity(); // Get SDK info const sdkInfo = getSDKInfo(); // Summarize recent errors (from in-memory store or logs) const recentErrors = await summarizeRecentErrors(); // Gather metrics const metrics = await gatherMetrics(); return { timestamp, environment, connectivity, sdkInfo, recentErrors, metrics, }; } function gatherEnvironmentInfo(): EnvironmentInfo { return { nodeVersion: process.version, sdkVersion: getPackageVersion('@openevidence/sdk'), apiKeySet: !!process.env.OPENEVIDENCE_API_KEY, apiKeyLength: process.env.OPENEVIDENCE_API_KEY?.length || 0, orgIdSet: !!process.env.OPENEVIDENCE_ORG_ID, baseUrl: process.env.OPENEVIDENCE_BASE_URL || 'https://api.openevidence.com', timeout: parseInt(process.env.OPENEVIDENCE_TIMEOUT || '30000'), }; } async function testConnectivity(): Promise { const baseUrl = process.env.OPENEVIDENCE_BASE_URL || 'https://api.openevidence.com'; const startTime = Date.now(); try { const response = await fetch(`${baseUrl}/health`, { headers: { Authorization: `Bearer ${process.env.OPENEVIDENCE_API_KEY}` }, }); return { healthStatus: response.status, latencyMs: Date.now() - startTime, dnsResolution: true, tlsVersion: 'TLS 1.2+', // Inferred from successful HTTPS }; } catch (error: any) { return { healthStatus: null, latencyMs: null, dnsResolution: error.code !== 'ENOTFOUND', tlsVersion: null, }; } } function getSDKInfo(): SDKInfo { return { version: getPackageVersion('@openevidence/sdk'), features: ['clinical-query', 'deep-consult', 'webhooks'], }; } function getPackageVersion(pkg: string): string { try { const result = execSync(`npm list ${pkg} --json 2>/dev/null`, { encoding: 'utf8' }); const json = JSON.parse(result); return json.dependencies?.[pkg]?.version || 'unknown'; } catch { return 'unknown'; } } async function summarizeRecentErrors(): Promise { // This would typically pull from your error tracking system // Placeholder implementation return []; } async function gatherMetrics(): Promise { // This would typically pull from your metrics system // Placeholder implementation return { totalRequests: 0, successRate: 0, avgLatencyMs: 0, p99LatencyMs: 0, }; } ``` ### Step 3: Sanitized Log Extraction ```typescript // src/debug/log-sanitizer.ts // IMPORTANT: Removes PHI before including in debug bundle const PHI_PATTERNS = [ /\b\d{3}-\d{2}-\d{4}\b/g, // SSN /\b[A-Z]\d{8}\b/gi, // MRN patterns /\b\d{10,}\b/g, // Long numbers (potential IDs) /patient[_\s]*(name|id|dob)/gi, // Patient fields /\b(male|female),?\s*\d{1,3}/gi, // Demographics /"name"\s*:\s*"[^"]+"/gi, // Name fields in JSON /"dob"\s*:\s*"[^"]+"/gi, // DOB fields /"mrn"\s*:\s*"[^"]+"/gi, // MRN fields ]; export function sanitizeLogs(logs: string): string { let sanitized = logs; for (const pattern of PHI_PATTERNS) { sanitized = sanitized.replace(pattern, '[REDACTED]'); } return sanitized; } export function extractSanitizedLogs( logSource: string, timeRange: { start: Date; end: Date }, maxLines: number = 1000 ): string[] { // Implementation depends on your logging infrastructure // Example with file-based logs: const logs: string[] = []; // Read logs, filter by time range, sanitize each line // ... return logs.map(sanitizeLogs).slice(0, maxLines); } ``` ### Step 4: Support Ticket Generator ```typescript // src/debug/support-ticket.ts import { generateDebugBundle, DebugBundle } from './debug-bundle'; import { sanitizeLogs, extractSanitizedLogs } from './log-sanitizer'; interface SupportTicket { subject: string; description: string; debugBundle: DebugBundle; sanitizedLogs: string[]; stepsToReproduce: string[]; expectedBehavior: string; actualBehavior: string; } export async function generateSupportTicket( issue: { summary: string; stepsToReproduce: string[]; expectedBehavior: string; actualBehavior: string; } ): Promise { const bundle = await generateDebugBundle(); const logs = extractSanitizedLogs( '/var/log/app/openevidence.log', { start: new Date(Date.now() - 3600000), end: new Date() }, 500 ); return { subject: `[OpenEvidence Integration] ${issue.summary}`, description: ` ## Issue Summary ${issue.summary} ## Environment - Node Version: ${bundle.environment.nodeVersion} - SDK Version: ${bundle.environment.sdkVersion} - Base URL: ${bundle.environment.baseUrl} - Timeout: ${bundle.environment.timeout}ms ## Connectivity - Health Status: ${bundle.connectivity.healthStatus || 'Failed'} - Latency: ${bundle.connectivity.latencyMs || 'N/A'}ms - DNS Resolution: ${bundle.connectivity.dnsResolution ? 'OK' : 'Failed'} ## Recent Errors ${bundle.recentErrors.map(e => `- ${e.code}: ${e.count} occurrences (last: ${e.lastOccurred})`).join('\n') || 'None recorded'} `, debugBundle: bundle, sanitizedLogs: logs, stepsToReproduce: issue.stepsToReproduce, expectedBehavior: issue.expectedBehavior, actualBehavior: issue.actualBehavior, }; } ``` ## Output - Environment configuration status - Connectivity test results - SDK version information - Sanitized logs (no PHI) - Formatted support ticket ## Diagnostic Checklist - [ ] API key is set and correct length - [ ] Organization ID is configured - [ ] Health endpoint returns 200 - [ ] DNS resolves api.openevidence.com - [ ] TLS handshake succeeds - [ ] Rate limits have headroom - [ ] No recent 5xx errors ## Error Handling | Issue | Check | Resolution | |-------|-------|------------| | No connectivity | DNS, firewall | Check network config | | Auth failures | API key format | Regenerate key in dashboard | | Timeouts | Latency test | Increase timeout, check network | | PHI in logs | Log sanitizer | Audit logging configuration | ## Examples ### Quick Debug Command ```bash # Run bash debug script chmod +x scripts/openevidence-debug.sh ./scripts/openevidence-debug.sh > debug-bundle.txt ``` ### Generate Support Ticket ```typescript const ticket = await generateSupportTicket({ summary: 'Clinical queries timing out after SDK upgrade', stepsToReproduce: [ '1. Upgrade @openevidence/sdk to v2.0.0', '2. Make clinical query request', '3. Request times out after 30s', ], expectedBehavior: 'Response within 10s', actualBehavior: 'Timeout after configured limit', }); console.log(JSON.stringify(ticket, null, 2)); ``` ## Resources - [OpenEvidence Support](mailto:support@openevidence.com) - [OpenEvidence Status](https://status.openevidence.com/) ## Next Steps For rate limit management, see `openevidence-rate-limits`.

Skill file: plugins/saas-packs/openevidence-pack/skills/openevidence-debug-bundle/SKILL.md