@the-magic-tower/fixhive-opencode-plugin 0.1.25 → 0.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/plugin/index.ts","../src/core/privacy-filter.ts","../src/core/error-detector.ts","../src/storage/local-store.ts","../src/core/hash.ts","../src/storage/migrations.ts","../src/cloud/embedding.ts","../src/cloud/client.ts","../src/plugin/tools.ts"],"sourcesContent":["/**\n * FixHive OpenCode Plugin\n * Community-based error knowledge sharing plugin for OpenCode\n */\n\nimport type { Plugin } from '@opencode-ai/plugin';\nimport { tool } from '@opencode-ai/plugin';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createErrorDetector } from '../core/error-detector.js';\nimport { createPrivacyFilter, createFilterContext, type PrivacyFilter } from '../core/privacy-filter.js';\nimport { createLocalStore, type LocalStore } from '../storage/local-store.js';\nimport { createCloudClient, type CloudClient } from '../cloud/client.js';\nimport { generateErrorFingerprint } from '../core/hash.js';\nimport { createTools } from './tools.js';\nimport type { FixHiveContext, Language, FixHiveConfig } from '../types/index.js';\n\n/**\n * Default configuration\n */\nconst DEFAULT_CONFIG: Partial<FixHiveConfig> = {\n cacheExpirationMs: 3600000, // 1 hour\n embeddingModel: 'text-embedding-3-small',\n embeddingDimensions: 1536,\n similarityThreshold: 0.7,\n maxSearchResults: 10,\n};\n\n/**\n * FixHive Plugin Factory\n */\nexport const FixHivePlugin: Plugin = async (ctx) => {\n // Load configuration from environment\n const config = loadConfig();\n\n // Log plugin initialization\n console.log('[FixHive] Plugin loaded');\n console.log(`[FixHive] Project: ${ctx.directory}`);\n console.log(`[FixHive] Cloud: ${config.supabaseUrl ? 'enabled' : 'disabled'}`);\n\n // Initialize components using factory functions\n const privacyFilter = createPrivacyFilter();\n const filterContext = createFilterContext(ctx.directory);\n const errorDetector = createErrorDetector(privacyFilter);\n const localStore = createLocalStore(ctx.directory);\n\n // Initialize cloud client if configured\n let cloudClient: CloudClient | null = null;\n if (config.supabaseUrl && config.supabaseAnonKey) {\n try {\n cloudClient = await createCloudClient({\n supabaseUrl: config.supabaseUrl,\n supabaseAnonKey: config.supabaseAnonKey,\n openaiApiKey: config.openaiApiKey,\n contributorId: config.contributorId,\n similarityThreshold: config.similarityThreshold,\n });\n } catch (err) {\n console.error('[FixHive] Failed to initialize cloud client:', err);\n console.error('[FixHive] Falling back to offline mode');\n // Continue with null cloudClient (offline mode)\n }\n }\n\n // Plugin context (shared state)\n const pluginContext: FixHiveContext = {\n sessionId: '',\n projectDirectory: ctx.directory,\n language: detectLanguage(ctx.directory),\n framework: detectFramework(ctx.directory),\n };\n\n // Log detected environment\n if (pluginContext.language) {\n console.log(`[FixHive] Detected: ${pluginContext.language}${pluginContext.framework ? ` / ${pluginContext.framework}` : ''}`);\n }\n console.log('[FixHive] Ready - use fixhive_stats to verify');\n\n // Error-producing tools to monitor\n const errorProducingTools = ['bash', 'edit', 'write', 'read', 'terminal'];\n\n return {\n // ============ Tool Execution Hook ============\n 'tool.execute.after': async (input, output) => {\n // Only process tools that can produce errors\n if (!errorProducingTools.includes(input.tool)) return;\n\n // Detect errors in output\n const detection = errorDetector.detect({\n tool: input.tool,\n output: output.output,\n exitCode: (output.metadata as Record<string, number>)?.exitCode,\n stderr: (output.metadata as Record<string, string>)?.stderr,\n metadata: output.metadata as Record<string, unknown>,\n });\n\n if (detection.detected && detection.confidence >= 0.5) {\n // Sanitize error data before storing locally\n const sanitizedErrorMessage = privacyFilter.sanitize(detection.errorMessage, filterContext).sanitized;\n const sanitizedErrorStack = detection.errorStack\n ? privacyFilter.sanitize(detection.errorStack, filterContext).sanitized\n : undefined;\n\n // Store error locally (with sanitized data)\n localStore.createErrorRecord({\n errorType: detection.errorType,\n errorMessage: sanitizedErrorMessage,\n errorStack: sanitizedErrorStack,\n language: pluginContext.language,\n framework: pluginContext.framework,\n toolName: input.tool,\n toolInput: {}, // Tool input is intentionally omitted to avoid storing sensitive data\n sessionId: pluginContext.sessionId || input.sessionID,\n });\n\n // Query cloud for solutions if client available\n if (cloudClient) {\n try {\n // Use already-sanitized error data for cloud query\n const solutions = await cloudClient.searchSimilar({\n errorMessage: sanitizedErrorMessage,\n errorStack: sanitizedErrorStack,\n language: pluginContext.language,\n framework: pluginContext.framework,\n limit: 3,\n });\n\n if (solutions.results.length > 0) {\n // Cache results using sanitized fingerprint\n localStore.cacheResults(\n generateErrorFingerprint(sanitizedErrorMessage, sanitizedErrorStack),\n solutions.results\n );\n\n // Append solution hints to output title\n output.title = `${output.title} [FixHive: ${solutions.results.length} solution(s) found]`;\n }\n } catch (e) {\n // Log error with context but avoid exposing sensitive details\n const errorMessage = e instanceof Error ? e.message : 'Unknown error';\n console.error(`[FixHive] Cloud query failed: ${errorMessage}`);\n // Don't throw - gracefully degrade to offline mode\n }\n }\n }\n },\n\n // ============ Session Compaction Hook ============\n 'experimental.session.compacting': async (_input, output) => {\n const unresolvedErrors = localStore.getUnresolvedErrors(pluginContext.sessionId);\n\n if (unresolvedErrors.length > 0) {\n output.context.push(`\n## FixHive: Unresolved Errors in Session\n\n${unresolvedErrors.map((e) => `- [${e.id.slice(0, 8)}] ${e.errorType}: ${e.errorMessage.slice(0, 100)}...`).join('\\n')}\n\nUse \\`fixhive_mark_resolved\\` when errors are fixed to contribute solutions.\n`);\n }\n },\n\n // ============ Chat Message Hook ============\n 'chat.message': async (input, _output) => {\n // Update session ID\n pluginContext.sessionId = input.sessionID;\n },\n\n // ============ Custom Tools ============\n tool: cloudClient\n ? createTools(localStore, cloudClient, privacyFilter, pluginContext)\n : createOfflineTools(localStore, privacyFilter, pluginContext),\n };\n};\n\n/**\n * Create offline-only tools when cloud is not configured\n */\nfunction createOfflineTools(\n localStore: LocalStore,\n _privacyFilter: PrivacyFilter,\n context: FixHiveContext\n) {\n return {\n fixhive_list: tool({\n description: 'List errors detected in the current session.',\n args: {\n status: tool.schema\n .enum(['unresolved', 'resolved', 'uploaded'])\n .optional()\n .describe('Filter by status'),\n limit: tool.schema.number().optional().describe('Maximum results (default: 10)'),\n },\n async execute(args: { status?: string; limit?: number }, ctx: { sessionID: string }) {\n context.sessionId = ctx.sessionID;\n\n const errors = localStore.getSessionErrors(ctx.sessionID, {\n status: args.status as 'unresolved' | 'resolved' | 'uploaded',\n limit: args.limit || 10,\n });\n\n if (errors.length === 0) {\n return 'No errors recorded in this session.';\n }\n\n return `## Session Errors (${errors.length})\\n\\n${errors.map((e) => `- [${e.id.slice(0, 8)}] ${e.errorType}: ${e.errorMessage.slice(0, 80)}...`).join('\\n')}\\n\\n*Cloud features disabled. Set FIXHIVE_SUPABASE_URL and FIXHIVE_SUPABASE_KEY to enable.*`;\n },\n }),\n\n fixhive_stats: tool({\n description: 'Get FixHive usage statistics.',\n args: {},\n async execute() {\n const stats = localStore.getStats();\n\n return `\n## FixHive Statistics (Offline Mode)\n\n### Local\n- Errors recorded: ${stats.totalErrors}\n- Resolved: ${stats.resolvedErrors}\n- Uploaded: ${stats.uploadedErrors}\n\n*Cloud features disabled. Set FIXHIVE_SUPABASE_URL and FIXHIVE_SUPABASE_KEY to enable community sharing.*\n`;\n },\n }),\n };\n}\n\n/**\n * Default FixHive Community Supabase (공유 지식 베이스)\n * 환경변수로 오버라이드 가능\n */\nconst COMMUNITY_SUPABASE = {\n url: 'https://flpqzkrpufrgnpxvftip.supabase.co',\n anonKey: 'sb_publishable_w3Y2uo-0vb4bFVamntChVw_Aqi0rv2y',\n};\n\n/**\n * Load configuration from environment (with community defaults)\n */\nfunction loadConfig(): FixHiveConfig {\n return {\n supabaseUrl: process.env.FIXHIVE_SUPABASE_URL || COMMUNITY_SUPABASE.url,\n supabaseAnonKey: process.env.FIXHIVE_SUPABASE_KEY || COMMUNITY_SUPABASE.anonKey,\n openaiApiKey: process.env.OPENAI_API_KEY || process.env.FIXHIVE_OPENAI_KEY || '',\n contributorId: process.env.FIXHIVE_CONTRIBUTOR_ID || '',\n cacheExpirationMs: DEFAULT_CONFIG.cacheExpirationMs!,\n embeddingModel: DEFAULT_CONFIG.embeddingModel!,\n embeddingDimensions: DEFAULT_CONFIG.embeddingDimensions!,\n similarityThreshold: DEFAULT_CONFIG.similarityThreshold!,\n maxSearchResults: DEFAULT_CONFIG.maxSearchResults!,\n };\n}\n\n/**\n * Detect programming language from project\n */\nfunction detectLanguage(directory: string): Language | undefined {\n const indicators: [string, Language][] = [\n ['package.json', 'typescript'],\n ['tsconfig.json', 'typescript'],\n ['pyproject.toml', 'python'],\n ['requirements.txt', 'python'],\n ['Cargo.toml', 'rust'],\n ['go.mod', 'go'],\n ['pom.xml', 'java'],\n ['build.gradle', 'java'],\n ['Gemfile', 'ruby'],\n ['composer.json', 'php'],\n ];\n\n for (const [file, lang] of indicators) {\n if (existsSync(join(directory, file))) {\n return lang;\n }\n }\n\n return undefined;\n}\n\n/**\n * Detect framework from project\n */\nfunction detectFramework(directory: string): string | undefined {\n // Check package.json for JS/TS projects\n const pkgPath = join(directory, 'package.json');\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n if (deps['next']) return 'nextjs';\n if (deps['react']) return 'react';\n if (deps['vue']) return 'vue';\n if (deps['@angular/core']) return 'angular';\n if (deps['express']) return 'express';\n if (deps['fastify']) return 'fastify';\n if (deps['hono']) return 'hono';\n } catch {\n // Ignore parse errors\n }\n }\n\n // Check for Python frameworks\n const reqPath = join(directory, 'requirements.txt');\n if (existsSync(reqPath)) {\n try {\n const content = readFileSync(reqPath, 'utf-8');\n if (content.includes('django')) return 'django';\n if (content.includes('flask')) return 'flask';\n if (content.includes('fastapi')) return 'fastapi';\n } catch {\n // Ignore read errors\n }\n }\n\n return undefined;\n}\n\nexport default FixHivePlugin;\n","/**\n * FixHive Privacy Filter\n * Sanitizes sensitive information from error messages before sharing\n */\n\nimport type { PrivacyFilterRule, SanitizedContent, FilterContext } from '../types/index.js';\n\n/**\n * Default privacy filtering rules sorted by priority (highest first)\n */\nconst DEFAULT_FILTER_RULES: PrivacyFilterRule[] = [\n // =====================================\n // SECRETS (Critical - Always Filter)\n // =====================================\n\n // AWS Keys\n {\n name: 'aws_access_key',\n category: 'secret',\n pattern: /\\b(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}\\b/g,\n replacement: '[AWS_KEY_REDACTED]',\n priority: 100,\n },\n\n // OpenAI API Keys\n {\n name: 'openai_key',\n category: 'secret',\n pattern: /\\b(sk-[a-zA-Z0-9]{20,})\\b/g,\n replacement: '[OPENAI_KEY_REDACTED]',\n priority: 100,\n },\n\n // GitHub Tokens\n {\n name: 'github_token',\n category: 'secret',\n pattern: /\\b(gh[pousr]_[A-Za-z0-9_]{36,}|github_pat_[A-Za-z0-9_]{22,})\\b/g,\n replacement: '[GITHUB_TOKEN_REDACTED]',\n priority: 100,\n },\n\n // Google API Keys\n {\n name: 'google_api_key',\n category: 'secret',\n pattern: /\\bAIza[0-9A-Za-z\\-_]{35}\\b/g,\n replacement: '[GOOGLE_API_KEY_REDACTED]',\n priority: 100,\n },\n\n // Stripe Keys\n {\n name: 'stripe_key',\n category: 'secret',\n pattern: /\\b(sk|pk|rk)_(live|test)_[0-9a-zA-Z]{24,}\\b/g,\n replacement: '[STRIPE_KEY_REDACTED]',\n priority: 100,\n },\n\n // JWT Tokens (limited length to prevent ReDoS)\n {\n name: 'jwt_token',\n category: 'secret',\n pattern: /\\beyJ[A-Za-z0-9_-]{10,500}\\.eyJ[A-Za-z0-9_-]{10,1000}\\.[A-Za-z0-9_-]{10,500}/g,\n replacement: '[JWT_REDACTED]',\n priority: 100,\n },\n\n // Bearer Tokens\n {\n name: 'bearer_token',\n category: 'secret',\n pattern: /\\b(Bearer|Authorization:?\\s*Bearer)\\s+[\\w\\-._~+\\/]+=*/gi,\n replacement: '$1 [TOKEN_REDACTED]',\n priority: 100,\n },\n\n // Private Keys\n {\n name: 'private_key',\n category: 'secret',\n pattern:\n /-----BEGIN\\s+(RSA|DSA|EC|OPENSSH|PGP)?\\s*PRIVATE KEY-----[\\s\\S]*?-----END\\s+(RSA|DSA|EC|OPENSSH|PGP)?\\s*PRIVATE KEY-----/g,\n replacement: '[PRIVATE_KEY_REDACTED]',\n priority: 100,\n },\n\n // Generic API Keys (context-based, limited length to prevent ReDoS)\n {\n name: 'generic_api_key',\n category: 'secret',\n pattern: /\\b(api[_-]?key|apikey|api[_-]?secret)\\s{0,5}[=:]\\s{0,5}[\"']?[\\w-]{20,200}[\"']?/gi,\n replacement: '$1=[KEY_REDACTED]',\n priority: 95,\n },\n\n // Secret/Password assignments (limited length to prevent ReDoS)\n {\n name: 'secret_assignment',\n category: 'secret',\n pattern: /\\b(password|passwd|pwd|secret|token|credential)\\s{0,5}[=:]\\s{0,5}[\"']?[^\\s\"']{8,200}[\"']?/gi,\n replacement: '$1=[REDACTED]',\n priority: 90,\n },\n\n // =====================================\n // IDENTITY (High Risk)\n // =====================================\n\n // Email Addresses\n {\n name: 'email',\n category: 'identity',\n pattern: /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b/g,\n replacement: '[EMAIL_REDACTED]',\n priority: 80,\n },\n\n // =====================================\n // INFRASTRUCTURE (Medium Risk)\n // =====================================\n\n // Database Connection Strings\n {\n name: 'db_connection',\n category: 'infrastructure',\n pattern: /\\b(mongodb|postgres|postgresql|mysql|redis|amqp):\\/\\/[^\\s]+/gi,\n replacement: '$1://[CONNECTION_REDACTED]',\n priority: 85,\n },\n\n // Internal URLs\n {\n name: 'internal_url',\n category: 'infrastructure',\n pattern:\n /\\bhttps?:\\/\\/(?:[\\w-]+\\.)*(?:internal|corp|local|intranet|private)[\\w.-]*(?::\\d+)?(?:\\/[^\\s]*)?/gi,\n replacement: '[INTERNAL_URL_REDACTED]',\n priority: 75,\n },\n\n // IP Addresses (except localhost and common dev IPs)\n {\n name: 'ipv4',\n category: 'infrastructure',\n pattern: /\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b/g,\n replacement: (match: string) => {\n // Keep localhost and common dev IPs\n if (match === '127.0.0.1' || match === '0.0.0.0' || match.startsWith('192.168.')) {\n return match;\n }\n return '[IP_REDACTED]';\n },\n priority: 70,\n },\n\n // =====================================\n // FILE PATHS (Context-dependent)\n // =====================================\n\n // Home Directory Paths (macOS)\n {\n name: 'macos_home_path',\n category: 'path',\n pattern: /\\/Users\\/[\\w.-]+/g,\n replacement: '~',\n priority: 60,\n },\n\n // Home Directory Paths (Linux)\n {\n name: 'linux_home_path',\n category: 'path',\n pattern: /\\/home\\/[\\w.-]+/g,\n replacement: '~',\n priority: 60,\n },\n\n // Home Directory Paths (Windows)\n {\n name: 'windows_home_path',\n category: 'path',\n pattern: /C:\\\\Users\\\\[\\w.-]+/gi,\n replacement: '~',\n priority: 60,\n },\n\n // =====================================\n // ENVIRONMENT (Medium Risk)\n // =====================================\n\n // Sensitive Environment Variables\n {\n name: 'env_var_value',\n category: 'environment',\n pattern: /\\b([A-Z_][A-Z0-9_]*)\\s*=\\s*[\"']?([^\\s\"']+)[\"']?/g,\n replacement: (match: string, name: string, _value: string) => {\n const sensitivePatterns = [\n 'API_KEY',\n 'SECRET',\n 'PASSWORD',\n 'TOKEN',\n 'CREDENTIAL',\n 'PRIVATE',\n 'AUTH',\n 'DATABASE_URL',\n 'REDIS_URL',\n 'OPENAI',\n 'STRIPE',\n 'AWS',\n ];\n if (sensitivePatterns.some((s) => name.toUpperCase().includes(s))) {\n return `${name}=[REDACTED]`;\n }\n return match;\n },\n priority: 65,\n },\n];\n\n/**\n * PrivacyFilter interface - defines all public methods\n */\nexport interface PrivacyFilter {\n sanitize(content: string, context?: FilterContext): SanitizedContent;\n addRule(rule: PrivacyFilterRule): void;\n removeRule(name: string): boolean;\n getRules(): ReadonlyArray<PrivacyFilterRule>;\n containsSensitiveData(content: string): boolean;\n}\n\n/**\n * Create a PrivacyFilter instance\n * Factory function pattern to avoid ES6 class issues with Bun\n */\nexport function createPrivacyFilter(customRules?: PrivacyFilterRule[]): PrivacyFilter {\n // Combine default and custom rules, sort by priority\n const rules = [...DEFAULT_FILTER_RULES, ...(customRules || [])].sort(\n (a, b) => b.priority - a.priority\n );\n\n /**\n * Generalize file paths while keeping meaningful structure\n */\n function generalizePaths(content: string, context: FilterContext): string {\n let result = content;\n\n // Replace project root with <PROJECT>\n if (context.projectRoot) {\n const escapedRoot = context.projectRoot.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n result = result.replace(new RegExp(escapedRoot, 'g'), '<PROJECT>');\n }\n\n // Replace common paths\n for (const [fullPath, alias] of context.commonPaths) {\n const escapedPath = fullPath.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n result = result.replace(new RegExp(escapedPath, 'g'), alias);\n }\n\n // Normalize node_modules paths\n result = result.replace(/node_modules\\/(?:@[\\w.-]+\\/)?[\\w.-]+\\//g, 'node_modules/<PKG>/');\n\n // Normalize site-packages paths\n result = result.replace(/site-packages\\/[\\w.-]+\\//g, 'site-packages/<PKG>/');\n\n return result;\n }\n\n return {\n /**\n * Sanitize content by applying all filter rules\n */\n sanitize(content: string, context?: FilterContext): SanitizedContent {\n let result = content;\n const appliedFilters: string[] = [];\n let totalRedacted = 0;\n\n // Apply each filter rule in priority order\n for (const rule of rules) {\n const before = result;\n\n if (typeof rule.replacement === 'function') {\n result = result.replace(rule.pattern, rule.replacement as (...args: string[]) => string);\n } else {\n result = result.replace(rule.pattern, rule.replacement);\n }\n\n if (result !== before) {\n const matches = before.match(rule.pattern);\n if (matches) {\n totalRedacted += matches.length;\n appliedFilters.push(rule.name);\n }\n }\n }\n\n // Apply path generalization if context provided\n if (context) {\n result = generalizePaths(result, context);\n }\n\n return {\n original: content,\n sanitized: result,\n redactedCount: totalRedacted,\n appliedFilters: [...new Set(appliedFilters)],\n };\n },\n\n /**\n * Add a custom filter rule\n */\n addRule(rule: PrivacyFilterRule): void {\n rules.push(rule);\n rules.sort((a, b) => b.priority - a.priority);\n },\n\n /**\n * Remove a filter rule by name\n */\n removeRule(name: string): boolean {\n const index = rules.findIndex((r) => r.name === name);\n if (index !== -1) {\n rules.splice(index, 1);\n return true;\n }\n return false;\n },\n\n /**\n * Get all current rules\n */\n getRules(): ReadonlyArray<PrivacyFilterRule> {\n return rules;\n },\n\n /**\n * Check if content contains sensitive data\n * Note: Always reset regex lastIndex BEFORE testing to prevent state pollution\n */\n containsSensitiveData(content: string): boolean {\n for (const rule of rules) {\n if (rule.category === 'secret') {\n // Reset lastIndex BEFORE testing to ensure consistent behavior with global regex\n rule.pattern.lastIndex = 0;\n const hasSensitiveData = rule.pattern.test(content);\n // Reset again after test to clean up state\n rule.pattern.lastIndex = 0;\n if (hasSensitiveData) {\n return true;\n }\n }\n }\n return false;\n },\n };\n}\n\n/**\n * Legacy class wrapper for backwards compatibility\n * @deprecated Use createPrivacyFilter() instead\n */\nexport const PrivacyFilter = {\n create: createPrivacyFilter,\n};\n\n/**\n * Create default filter context from project directory\n */\nexport function createFilterContext(projectDirectory: string): FilterContext {\n const homeDir = process.env.HOME || process.env.USERPROFILE || '~';\n\n return {\n projectRoot: projectDirectory,\n homeDir,\n commonPaths: new Map([\n ['/usr/local/lib/', '<LIB>/'],\n ['/usr/lib/', '<LIB>/'],\n ['/var/log/', '<LOG>/'],\n ['/tmp/', '<TMP>/'],\n ['/etc/', '<ETC>/'],\n ]),\n };\n}\n\n// Export default instance factory\nexport const defaultPrivacyFilter = createPrivacyFilter();\n","/**\n * FixHive Error Detector\n * Detects errors from tool outputs using multi-signal analysis\n */\n\nimport type {\n ErrorType,\n Severity,\n DetectedSignal,\n ErrorDetectionResult,\n StackTraceInfo,\n ToolOutput,\n} from '../types/index.js';\nimport { createPrivacyFilter, type PrivacyFilter } from './privacy-filter.js';\n\n/**\n * Error keyword patterns by category\n */\nconst ERROR_PATTERNS: Record<string, RegExp[]> = {\n // Universal error indicators\n universal: [\n /\\b(error|failed|failure|fatal|exception|panic)\\b/i,\n /\\b(cannot|could not|unable to|couldn't)\\b/i,\n /\\b(denied|rejected|refused|forbidden)\\b/i,\n /\\b(not found|missing|undefined|null pointer)\\b/i,\n /\\b(invalid|illegal|malformed|corrupt)\\b/i,\n /\\b(timeout|timed out|connection refused)\\b/i,\n /\\b(segmentation fault|segfault|core dumped)\\b/i,\n /\\b(out of memory|oom|memory allocation failed)\\b/i,\n ],\n\n // Error prefixes\n prefixed: [\n /^Error:/m,\n /^ERROR\\s/m,\n /^E\\s+\\d+:/m, // Rust errors\n /^\\[ERROR\\]/m,\n /^fatal:/m,\n /^FATAL:/m,\n /^panic:/m,\n /^Traceback \\(most recent call last\\):/m, // Python\n /^Exception in thread/m, // Java\n /^Uncaught \\w+Error:/m, // JavaScript\n ],\n\n // Build/compilation errors\n build: [\n /^.+:\\d+:\\d+:\\s*error:/m, // GCC/Clang format\n /error\\[E\\d+\\]:/m, // Rust compiler\n /error TS\\d+:/m, // TypeScript\n /SyntaxError:/m,\n /ParseError:/m,\n /CompileError:/m,\n ],\n\n // Package manager errors\n package: [\n /npm ERR!/m,\n /npm error/m,\n /yarn error/m,\n /pnpm error/m,\n /pip error/m,\n /cargo error/m,\n /ModuleNotFoundError:/m,\n /ImportError:/m,\n /Cannot find module/m,\n /Module not found/m,\n ],\n\n // Permission errors\n permission: [/EACCES:/m, /EPERM:/m, /Permission denied/m, /Access denied/m, /Insufficient permissions/m],\n\n // Network errors\n network: [\n /ECONNREFUSED/m,\n /ETIMEDOUT/m,\n /ENOTFOUND/m,\n /getaddrinfo ENOTFOUND/m,\n /Connection refused/m,\n /Network is unreachable/m,\n ],\n\n // Test failures\n test: [/FAIL /m, /AssertionError/m, /Expected .+ but got/m, /Test failed/i, /\\d+ failing/m],\n};\n\n/**\n * Stack trace patterns by language\n */\nconst STACK_TRACE_PATTERNS: Record<string, RegExp> = {\n javascript: /^\\s+at\\s+(?:(?:async\\s+)?[\\w.<>]+\\s+\\()?(?:[\\w/\\\\.:-]+:\\d+:\\d+|native|<anonymous>)\\)?$/m,\n python: /^\\s+File\\s+\"[^\"]+\",\\s+line\\s+\\d+/m,\n java: /^\\s+at\\s+[\\w.$]+\\([\\w.]+:\\d+\\)$/m,\n golang: /^goroutine\\s+\\d+\\s+\\[.+\\]:/m,\n rust: /^\\s+\\d+:\\s+0x[\\da-f]+\\s+-\\s+.+$/m,\n ruby: /^\\s+from\\s+[\\w/\\\\.]+:\\d+:in\\s+`.+'$/m,\n php: /^#\\d+\\s+[\\w/\\\\.]+\\(\\d+\\):\\s+[\\w\\\\]+/m,\n csharp: /^\\s+at\\s+[\\w.<>]+\\s+in\\s+[\\w/\\\\.]+:line\\s+\\d+$/m,\n};\n\n/**\n * Exit code severity mapping\n */\nconst EXIT_CODE_SEVERITY: Record<number, Severity> = {\n 1: 'error', // General errors\n 2: 'error', // Misuse of shell builtins\n 126: 'error', // Command cannot execute\n 127: 'error', // Command not found\n 128: 'critical', // Invalid exit argument\n 130: 'warning', // Script terminated by Ctrl+C\n 137: 'critical', // SIGKILL (OOM, etc.)\n 139: 'critical', // Segmentation fault\n 143: 'warning', // SIGTERM\n};\n\n/**\n * ErrorDetector interface - defines all public methods\n */\nexport interface ErrorDetector {\n detect(toolOutput: ToolOutput): ErrorDetectionResult;\n}\n\n/**\n * Create an ErrorDetector instance\n * Factory function pattern to avoid ES6 class issues with Bun\n */\nexport function createErrorDetector(privacyFilter?: PrivacyFilter): ErrorDetector {\n const filter = privacyFilter || createPrivacyFilter();\n\n /**\n * Check if content contains error keywords\n */\n function containsErrorKeywords(content: string): boolean {\n return ERROR_PATTERNS.universal.some((p) => p.test(content));\n }\n\n /**\n * Detect error patterns in content\n */\n function detectErrorPatterns(content: string): DetectedSignal[] {\n const signals: DetectedSignal[] = [];\n const weights: Record<string, number> = {\n prefixed: 0.85,\n build: 0.8,\n package: 0.75,\n permission: 0.8,\n network: 0.75,\n test: 0.7,\n };\n\n for (const [category, patterns] of Object.entries(ERROR_PATTERNS)) {\n if (category === 'universal') continue; // Already used for keyword check\n\n for (const pattern of patterns) {\n const match = content.match(pattern);\n if (match) {\n signals.push({\n type: 'pattern',\n weight: weights[category] || 0.7,\n value: match[0].substring(0, 200),\n description: `Matched ${category} pattern: ${pattern.source.substring(0, 50)}`,\n });\n break; // One match per category is enough\n }\n }\n }\n\n return signals;\n }\n\n /**\n * Detect stack traces in content\n */\n function detectStackTrace(content: string): StackTraceInfo {\n for (const [language, pattern] of Object.entries(STACK_TRACE_PATTERNS)) {\n const globalPattern = new RegExp(pattern.source, 'gm');\n const matches = content.match(globalPattern);\n if (matches && matches.length >= 2) {\n return {\n hasStackTrace: true,\n language,\n frames: matches,\n };\n }\n }\n\n return {\n hasStackTrace: false,\n language: null,\n frames: [],\n };\n }\n\n /**\n * Calculate confidence score from signals\n */\n function calculateConfidence(signals: DetectedSignal[]): number {\n if (signals.length === 0) return 0;\n\n // Weighted average with diminishing returns for multiple signals\n const totalWeight = signals.reduce((sum, s) => sum + s.weight, 0);\n const avgWeight = totalWeight / signals.length;\n\n // Boost confidence for multiple signals\n const multiplier = Math.min(1.2, 1 + signals.length * 0.05);\n\n return Math.min(1.0, avgWeight * multiplier);\n }\n\n /**\n * Classify error type based on signals and content\n */\n function classifyErrorType(signals: DetectedSignal[], content: string): ErrorType {\n // Check for specific patterns\n if (ERROR_PATTERNS.build.some((p) => p.test(content))) return 'build';\n if (ERROR_PATTERNS.package.some((p) => p.test(content))) return 'dependency';\n if (ERROR_PATTERNS.permission.some((p) => p.test(content))) return 'permission';\n if (ERROR_PATTERNS.network.some((p) => p.test(content))) return 'network';\n if (ERROR_PATTERNS.test.some((p) => p.test(content))) return 'test';\n\n // Check for type errors\n if (/TypeError:|type error|Type '[^']+' is not assignable/i.test(content)) return 'type_error';\n\n // Check for syntax errors\n if (/SyntaxError:|syntax error|unexpected token/i.test(content)) return 'syntax';\n\n // Check for runtime errors\n if (/ReferenceError:|RangeError:|runtime error/i.test(content)) return 'runtime';\n\n // Check signals\n const hasStackTrace = signals.some((s) => s.type === 'stack_trace');\n if (hasStackTrace) return 'runtime';\n\n return 'unknown';\n }\n\n /**\n * Determine severity from signals and exit code\n */\n function determineSeverity(signals: DetectedSignal[], exitCode?: number): Severity {\n // Check exit code first\n if (exitCode !== undefined && EXIT_CODE_SEVERITY[exitCode]) {\n return EXIT_CODE_SEVERITY[exitCode];\n }\n\n // High confidence signals indicate error\n const maxWeight = Math.max(...signals.map((s) => s.weight));\n if (maxWeight >= 0.9) return 'error';\n if (maxWeight >= 0.7) return 'error';\n\n return 'warning';\n }\n\n /**\n * Check if a line looks like an error message\n */\n function isErrorLine(line: string): boolean {\n const trimmed = line.trim();\n return (\n /^(Error|TypeError|ReferenceError|SyntaxError|RangeError):/i.test(trimmed) ||\n /^(error|FAIL|fatal|panic)\\b/i.test(trimmed) ||\n /^error\\[E\\d+\\]:/.test(trimmed) ||\n /^error TS\\d+:/.test(trimmed)\n );\n }\n\n /**\n * Extract error message and stack from output\n */\n function extractErrorDetails(output: string): { message: string; stack?: string } {\n const lines = output.split('\\n');\n let message = '';\n let stack = '';\n let inStack = false;\n\n for (const line of lines) {\n if (isErrorLine(line) && !message) {\n message = line.trim();\n inStack = true;\n } else if (\n inStack &&\n (line.match(/^\\s+at\\s/) || // JS stack\n line.match(/^\\s+File\\s/) || // Python stack\n line.match(/^\\s+\\d+:\\s/) || // Rust stack\n line.match(/^\\s+from\\s/)) // Ruby stack\n ) {\n stack += line + '\\n';\n }\n }\n\n // If no specific error line found, use first non-empty line\n if (!message) {\n for (const line of lines) {\n if (line.trim()) {\n message = line.trim();\n break;\n }\n }\n }\n\n return {\n message: message || output.substring(0, 500),\n stack: stack || undefined,\n };\n }\n\n return {\n /**\n * Detect if output contains an error\n */\n detect(toolOutput: ToolOutput): ErrorDetectionResult {\n const signals: DetectedSignal[] = [];\n const combinedOutput = `${toolOutput.output || ''}\\n${toolOutput.stderr || ''}`;\n\n // Signal 1: Exit code\n if (toolOutput.exitCode !== undefined && toolOutput.exitCode !== 0) {\n const severity = EXIT_CODE_SEVERITY[toolOutput.exitCode] || 'error';\n signals.push({\n type: 'exit_code',\n weight: 0.9,\n value: toolOutput.exitCode,\n description: `Non-zero exit code: ${toolOutput.exitCode} (${severity})`,\n });\n }\n\n // Signal 2: Stderr presence\n if (toolOutput.stderr && toolOutput.stderr.trim().length > 0) {\n const hasErrorKeywords = containsErrorKeywords(toolOutput.stderr);\n const stderrWeight = hasErrorKeywords ? 0.85 : 0.4;\n signals.push({\n type: 'stderr',\n weight: stderrWeight,\n value: toolOutput.stderr.substring(0, 500),\n description: hasErrorKeywords ? 'Stderr with error keywords' : 'Stderr output present',\n });\n }\n\n // Signal 3: Error patterns\n const patternMatches = detectErrorPatterns(combinedOutput);\n signals.push(...patternMatches);\n\n // Signal 4: Stack trace\n const stackTrace = detectStackTrace(combinedOutput);\n if (stackTrace.hasStackTrace) {\n signals.push({\n type: 'stack_trace',\n weight: 0.95,\n value: stackTrace.frames.slice(0, 5).join('\\n'),\n description: `${stackTrace.language} stack trace detected`,\n });\n }\n\n // Calculate confidence\n const confidence = calculateConfidence(signals);\n const detected = confidence >= 0.5;\n\n // Determine error type and severity\n const errorType = classifyErrorType(signals, combinedOutput);\n const severity = determineSeverity(signals, toolOutput.exitCode);\n\n // Extract error details\n const { message, stack } = extractErrorDetails(combinedOutput);\n\n // Sanitize output\n const sanitizedMessage = filter.sanitize(message);\n const sanitizedStack = stack ? filter.sanitize(stack) : undefined;\n const sanitizedOutput = filter.sanitize(combinedOutput.substring(0, 5000));\n\n return {\n detected,\n confidence,\n errorType,\n severity,\n signals,\n errorMessage: sanitizedMessage.sanitized,\n errorStack: sanitizedStack?.sanitized,\n rawOutput: sanitizedOutput.sanitized,\n };\n },\n };\n}\n\n/**\n * Legacy class wrapper for backwards compatibility\n * @deprecated Use createErrorDetector() instead\n */\nexport const ErrorDetector = {\n create: createErrorDetector,\n};\n\n// Export default instance factory\nexport const defaultErrorDetector = createErrorDetector();\n","/**\n * FixHive Local Store\n * SQLite-based local storage for error records and caching\n */\n\nimport Database from 'better-sqlite3';\nimport { v4 as uuidv4 } from 'uuid';\nimport { mkdirSync, existsSync } from 'fs';\nimport { dirname } from 'path';\nimport type {\n LocalErrorRecord,\n ErrorStatus,\n LocalStats,\n CloudKnowledgeEntry,\n} from '../types/index.js';\nimport { generateErrorFingerprint } from '../core/hash.js';\nimport { runMigrations } from './migrations.js';\n\n/**\n * Allowed stat column names for incrementStat (whitelist to prevent SQL injection)\n */\nconst ALLOWED_STATS = [\n 'total_errors',\n 'resolved_errors',\n 'uploaded_errors',\n 'queries_made',\n] as const;\n\n/**\n * LocalStore interface - defines all public methods\n */\nexport interface LocalStore {\n createErrorRecord(data: Omit<LocalErrorRecord, 'id' | 'errorHash' | 'status' | 'createdAt'>): LocalErrorRecord;\n getErrorById(id: string): LocalErrorRecord | null;\n getSessionErrors(sessionId: string, options?: { status?: ErrorStatus; limit?: number }): LocalErrorRecord[];\n getUnresolvedErrors(sessionId: string): LocalErrorRecord[];\n getRecentErrors(limit?: number): LocalErrorRecord[];\n markResolved(id: string, data: { resolution: string; resolutionCode?: string }): LocalErrorRecord | null;\n markUploaded(id: string, cloudKnowledgeId: string): void;\n findSimilarErrors(errorHash: string): LocalErrorRecord[];\n getCachedResults(errorHash: string): CloudKnowledgeEntry[] | null;\n cacheResults(errorHash: string, results: CloudKnowledgeEntry[], expirationMs?: number): void;\n clearExpiredCache(): number;\n getStats(): LocalStats;\n getPreference(key: string): string | null;\n setPreference(key: string, value: string): void;\n close(): void;\n getDatabase(): Database.Database;\n}\n\n/**\n * Convert database row to LocalErrorRecord\n */\nfunction rowToRecord(row: Record<string, unknown>): LocalErrorRecord {\n return {\n id: row.id as string,\n errorHash: row.error_hash as string,\n errorType: row.error_type as LocalErrorRecord['errorType'],\n errorMessage: row.error_message as string,\n errorStack: (row.error_stack as string) || undefined,\n language: (row.language as LocalErrorRecord['language']) || undefined,\n framework: (row.framework as string) || undefined,\n toolName: row.tool_name as string,\n toolInput: JSON.parse((row.tool_input as string) || '{}'),\n sessionId: row.session_id as string,\n status: row.status as ErrorStatus,\n resolution: (row.resolution as string) || undefined,\n resolutionCode: (row.resolution_code as string) || undefined,\n createdAt: row.created_at as string,\n resolvedAt: (row.resolved_at as string) || undefined,\n uploadedAt: (row.uploaded_at as string) || undefined,\n cloudKnowledgeId: (row.cloud_knowledge_id as string) || undefined,\n };\n}\n\n/**\n * Create a LocalStore instance\n * Factory function pattern to avoid ES6 class issues with Bun\n */\nexport function createLocalStore(projectDirectory: string): LocalStore {\n const dbPath = `${projectDirectory}/.fixhive/fixhive.db`;\n\n // Ensure directory exists\n const dir = dirname(dbPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Initialize database\n const db = new Database(dbPath);\n db.pragma('journal_mode = WAL');\n db.pragma('foreign_keys = ON');\n\n // Run migrations\n runMigrations(db);\n\n /**\n * Increment a stat counter\n * @throws Error if stat name is not in the allowed whitelist\n */\n function incrementStat(stat: string): void {\n // Validate stat name against whitelist to prevent SQL injection\n if (!ALLOWED_STATS.includes(stat as (typeof ALLOWED_STATS)[number])) {\n throw new Error(`Invalid stat name: ${stat}. Allowed: ${ALLOWED_STATS.join(', ')}`);\n }\n const stmt = db.prepare(`UPDATE usage_stats SET ${stat} = ${stat} + 1 WHERE id = 1`);\n stmt.run();\n }\n\n return {\n // ============ Error Records ============\n\n /**\n * Create a new error record\n */\n createErrorRecord(\n data: Omit<LocalErrorRecord, 'id' | 'errorHash' | 'status' | 'createdAt'>\n ): LocalErrorRecord {\n const id = uuidv4();\n const errorHash = generateErrorFingerprint(data.errorMessage, data.errorStack);\n\n const stmt = db.prepare(`\n INSERT INTO error_records (\n id, error_hash, error_type, error_message, error_stack,\n language, framework, tool_name, tool_input, session_id, status\n ) VALUES (\n @id, @errorHash, @errorType, @errorMessage, @errorStack,\n @language, @framework, @toolName, @toolInput, @sessionId, 'unresolved'\n )\n `);\n\n stmt.run({\n id,\n errorHash,\n errorType: data.errorType,\n errorMessage: data.errorMessage,\n errorStack: data.errorStack || null,\n language: data.language || null,\n framework: data.framework || null,\n toolName: data.toolName,\n toolInput: JSON.stringify(data.toolInput),\n sessionId: data.sessionId,\n });\n\n // Update stats\n incrementStat('total_errors');\n\n return this.getErrorById(id)!;\n },\n\n /**\n * Get error record by ID\n */\n getErrorById(id: string): LocalErrorRecord | null {\n const stmt = db.prepare('SELECT * FROM error_records WHERE id = ?');\n const row = stmt.get(id) as Record<string, unknown> | undefined;\n return row ? rowToRecord(row) : null;\n },\n\n /**\n * Get errors by session\n */\n getSessionErrors(\n sessionId: string,\n options?: { status?: ErrorStatus; limit?: number }\n ): LocalErrorRecord[] {\n let query = 'SELECT * FROM error_records WHERE session_id = ?';\n const params: (string | number)[] = [sessionId];\n\n if (options?.status) {\n query += ' AND status = ?';\n params.push(options.status);\n }\n\n query += ' ORDER BY created_at DESC';\n\n if (options?.limit) {\n query += ' LIMIT ?';\n params.push(options.limit);\n }\n\n const stmt = db.prepare(query);\n return (stmt.all(...params) as Record<string, unknown>[]).map((row) => rowToRecord(row));\n },\n\n /**\n * Get unresolved errors for a session\n */\n getUnresolvedErrors(sessionId: string): LocalErrorRecord[] {\n return this.getSessionErrors(sessionId, { status: 'unresolved' });\n },\n\n /**\n * Get recent errors across all sessions\n */\n getRecentErrors(limit: number = 10): LocalErrorRecord[] {\n const stmt = db.prepare(\n 'SELECT * FROM error_records ORDER BY created_at DESC LIMIT ?'\n );\n return (stmt.all(limit) as Record<string, unknown>[]).map((row) => rowToRecord(row));\n },\n\n /**\n * Mark error as resolved\n */\n markResolved(\n id: string,\n data: { resolution: string; resolutionCode?: string }\n ): LocalErrorRecord | null {\n const stmt = db.prepare(`\n UPDATE error_records\n SET status = 'resolved',\n resolution = ?,\n resolution_code = ?,\n resolved_at = datetime('now')\n WHERE id = ?\n `);\n\n const result = stmt.run(data.resolution, data.resolutionCode || null, id);\n\n if (result.changes > 0) {\n incrementStat('resolved_errors');\n return this.getErrorById(id);\n }\n\n return null;\n },\n\n /**\n * Mark error as uploaded to cloud\n */\n markUploaded(id: string, cloudKnowledgeId: string): void {\n const stmt = db.prepare(`\n UPDATE error_records\n SET status = 'uploaded',\n cloud_knowledge_id = ?,\n uploaded_at = datetime('now')\n WHERE id = ?\n `);\n\n const result = stmt.run(cloudKnowledgeId, id);\n\n if (result.changes > 0) {\n incrementStat('uploaded_errors');\n }\n },\n\n /**\n * Find similar errors by hash\n */\n findSimilarErrors(errorHash: string): LocalErrorRecord[] {\n const stmt = db.prepare(\n 'SELECT * FROM error_records WHERE error_hash = ? ORDER BY created_at DESC'\n );\n return (stmt.all(errorHash) as Record<string, unknown>[]).map((row) => rowToRecord(row));\n },\n\n // ============ Query Cache ============\n\n /**\n * Get cached query results\n */\n getCachedResults(errorHash: string): CloudKnowledgeEntry[] | null {\n const stmt = db.prepare(`\n SELECT results FROM query_cache\n WHERE error_hash = ? AND expires_at > datetime('now')\n ORDER BY created_at DESC LIMIT 1\n `);\n\n const row = stmt.get(errorHash) as { results: string } | undefined;\n if (row) {\n return JSON.parse(row.results);\n }\n return null;\n },\n\n /**\n * Cache query results\n */\n cacheResults(\n errorHash: string,\n results: CloudKnowledgeEntry[],\n expirationMs: number = 3600000 // 1 hour default\n ): void {\n const id = uuidv4();\n const expiresAt = new Date(Date.now() + expirationMs).toISOString();\n\n const stmt = db.prepare(`\n INSERT INTO query_cache (id, error_hash, results, expires_at)\n VALUES (?, ?, ?, ?)\n `);\n\n stmt.run(id, errorHash, JSON.stringify(results), expiresAt);\n\n // Update stats\n incrementStat('queries_made');\n },\n\n /**\n * Clear expired cache entries\n */\n clearExpiredCache(): number {\n const stmt = db.prepare(\"DELETE FROM query_cache WHERE expires_at <= datetime('now')\");\n const result = stmt.run();\n return result.changes;\n },\n\n // ============ Statistics ============\n\n /**\n * Get usage statistics\n */\n getStats(): LocalStats {\n const stmt = db.prepare(\n 'SELECT total_errors, resolved_errors, uploaded_errors FROM usage_stats WHERE id = 1'\n );\n const row = stmt.get() as {\n total_errors: number;\n resolved_errors: number;\n uploaded_errors: number;\n };\n\n return {\n totalErrors: row.total_errors,\n resolvedErrors: row.resolved_errors,\n uploadedErrors: row.uploaded_errors,\n };\n },\n\n // ============ Preferences ============\n\n /**\n * Get preference value\n */\n getPreference(key: string): string | null {\n const stmt = db.prepare('SELECT value FROM user_preferences WHERE key = ?');\n const row = stmt.get(key) as { value: string } | undefined;\n return row?.value || null;\n },\n\n /**\n * Set preference value\n */\n setPreference(key: string, value: string): void {\n const stmt = db.prepare(`\n INSERT OR REPLACE INTO user_preferences (key, value) VALUES (?, ?)\n `);\n stmt.run(key, value);\n },\n\n // ============ Utilities ============\n\n /**\n * Close database connection\n */\n close(): void {\n db.close();\n },\n\n /**\n * Get database for advanced queries\n */\n getDatabase(): Database.Database {\n return db;\n },\n };\n}\n\n/**\n * Legacy class wrapper for backwards compatibility\n * @deprecated Use createLocalStore() instead\n */\nexport const LocalStore = {\n create: createLocalStore,\n};\n","/**\n * FixHive Hash Utilities\n * Generates fingerprints and hashes for error deduplication\n */\n\nimport { createHash } from 'crypto';\n\n/**\n * Generate SHA-256 hash of content\n */\nexport function sha256(content: string): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\n/**\n * Generate a shortened hash (first 16 characters)\n */\nexport function shortHash(content: string): string {\n return sha256(content).substring(0, 16);\n}\n\n/**\n * Generate error fingerprint for matching similar errors\n * Normalizes variable parts (paths, numbers, hashes) before hashing\n */\nexport function generateErrorFingerprint(\n errorMessage: string,\n errorStack?: string\n): string {\n // Combine message and stack\n const combined = `${errorMessage}\\n${errorStack || ''}`;\n\n // Normalize the content\n const normalized = normalizeErrorContent(combined);\n\n // Generate hash\n return shortHash(normalized);\n}\n\n/**\n * Normalize error content by replacing variable parts\n */\nexport function normalizeErrorContent(content: string): string {\n return (\n content\n // String literals\n .replace(/['\"`][^'\"`\\n]{0,100}['\"`]/g, '<STR>')\n // File paths\n .replace(/(?:\\/[\\w.-]+)+/g, '<PATH>')\n // Windows paths\n .replace(/(?:[A-Z]:\\\\[\\w.-]+)+/gi, '<PATH>')\n // Line:column references\n .replace(/:\\d+:\\d+/g, ':<LINE>:<COL>')\n // Line numbers only\n .replace(/line\\s+\\d+/gi, 'line <LINE>')\n // Memory addresses\n .replace(/0x[a-f0-9]+/gi, '<ADDR>')\n // UUIDs\n .replace(/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/gi, '<UUID>')\n // Long hex strings (hashes, IDs)\n .replace(/\\b[a-f0-9]{8,}\\b/gi, '<HASH>')\n // Numbers (but keep small numbers like error codes)\n .replace(/\\b\\d{5,}\\b/g, '<NUM>')\n // Timestamps\n .replace(/\\d{4}-\\d{2}-\\d{2}[T\\s]\\d{2}:\\d{2}:\\d{2}/g, '<TIMESTAMP>')\n // Multiple whitespace\n .replace(/\\s+/g, ' ')\n .trim()\n );\n}\n\n/**\n * Generate contributor ID (anonymous hash)\n * Uses machine-specific information to create a stable anonymous ID\n */\nexport function generateContributorId(): string {\n const machineInfo = [\n process.env.USER || process.env.USERNAME || '',\n process.env.HOME || process.env.USERPROFILE || '',\n process.platform,\n process.arch,\n ].join(':');\n\n return `anon_${shortHash(machineInfo)}`;\n}\n\n/**\n * Generate session-specific hash\n */\nexport function generateSessionHash(sessionId: string): string {\n return shortHash(`session:${sessionId}:${Date.now()}`);\n}\n\n/**\n * Compare two fingerprints for similarity\n * Returns true if they're identical (exact match)\n */\nexport function fingerprintsMatch(fp1: string, fp2: string): boolean {\n return fp1 === fp2;\n}\n\n/**\n * Calculate simple string similarity (Jaccard index)\n * Used as a fallback when embeddings aren't available\n */\nexport function calculateStringSimilarity(str1: string, str2: string): number {\n const words1 = new Set(str1.toLowerCase().split(/\\s+/));\n const words2 = new Set(str2.toLowerCase().split(/\\s+/));\n\n const intersection = new Set([...words1].filter((x) => words2.has(x)));\n const union = new Set([...words1, ...words2]);\n\n if (union.size === 0) return 0;\n\n return intersection.size / union.size;\n}\n","/**\n * FixHive Database Migrations\n * SQLite schema setup and migrations\n */\n\nimport type Database from 'better-sqlite3';\n\n/**\n * Run all migrations on the database\n */\nexport function runMigrations(db: Database.Database): void {\n // Create migrations table\n db.exec(`\n CREATE TABLE IF NOT EXISTS migrations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL UNIQUE,\n applied_at TEXT DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Get applied migrations\n const appliedMigrations = new Set(\n (db.prepare('SELECT name FROM migrations').all() as { name: string }[]).map((r) => r.name)\n );\n\n // Run pending migrations\n for (const migration of MIGRATIONS) {\n if (!appliedMigrations.has(migration.name)) {\n db.exec(migration.sql);\n db.prepare('INSERT INTO migrations (name) VALUES (?)').run(migration.name);\n }\n }\n}\n\n/**\n * Migration definitions\n */\nconst MIGRATIONS = [\n {\n name: '001_initial_schema',\n sql: `\n -- Error records table\n CREATE TABLE IF NOT EXISTS error_records (\n id TEXT PRIMARY KEY,\n error_hash TEXT NOT NULL,\n error_type TEXT NOT NULL,\n error_message TEXT NOT NULL,\n error_stack TEXT,\n language TEXT,\n framework TEXT,\n tool_name TEXT NOT NULL,\n tool_input TEXT NOT NULL DEFAULT '{}',\n session_id TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'unresolved',\n resolution TEXT,\n resolution_code TEXT,\n created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,\n resolved_at TEXT,\n uploaded_at TEXT,\n cloud_knowledge_id TEXT\n );\n\n -- Indexes for error_records\n CREATE INDEX IF NOT EXISTS idx_error_records_hash ON error_records(error_hash);\n CREATE INDEX IF NOT EXISTS idx_error_records_status ON error_records(status);\n CREATE INDEX IF NOT EXISTS idx_error_records_session ON error_records(session_id);\n CREATE INDEX IF NOT EXISTS idx_error_records_created ON error_records(created_at);\n\n -- Query cache table\n CREATE TABLE IF NOT EXISTS query_cache (\n id TEXT PRIMARY KEY,\n error_hash TEXT NOT NULL,\n results TEXT NOT NULL DEFAULT '[]',\n created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,\n expires_at TEXT NOT NULL\n );\n\n -- Indexes for query_cache\n CREATE INDEX IF NOT EXISTS idx_query_cache_hash ON query_cache(error_hash);\n CREATE INDEX IF NOT EXISTS idx_query_cache_expires ON query_cache(expires_at);\n\n -- User preferences table\n CREATE TABLE IF NOT EXISTS user_preferences (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n\n -- Usage statistics table\n CREATE TABLE IF NOT EXISTS usage_stats (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n total_errors INTEGER NOT NULL DEFAULT 0,\n resolved_errors INTEGER NOT NULL DEFAULT 0,\n uploaded_errors INTEGER NOT NULL DEFAULT 0,\n queries_made INTEGER NOT NULL DEFAULT 0,\n last_sync TEXT\n );\n\n -- Initialize usage stats\n INSERT OR IGNORE INTO usage_stats (id) VALUES (1);\n `,\n },\n {\n name: '002_add_confidence_score',\n sql: `\n ALTER TABLE error_records ADD COLUMN confidence REAL DEFAULT 0;\n ALTER TABLE error_records ADD COLUMN severity TEXT DEFAULT 'error';\n `,\n },\n];\n","/**\n * FixHive Embedding Service\n * Generates text embeddings for semantic search using OpenAI\n */\n\nconst DEFAULT_MODEL = 'text-embedding-3-small';\nconst DEFAULT_DIMENSIONS = 1536;\nconst MAX_INPUT_LENGTH = 30000; // ~8000 tokens\n\n/**\n * Dynamic import helper for OpenAI (Bun ESM/CJS interop)\n */\nasync function getOpenAIClass(): Promise<typeof import('openai').OpenAI> {\n const mod = await import('openai');\n // Handle various export patterns\n return mod.OpenAI || (mod as unknown as { default: typeof mod.OpenAI }).default;\n}\n\n/**\n * EmbeddingService interface - defines all public methods\n */\nexport interface EmbeddingService {\n generate(text: string): Promise<number[]>;\n generateBatch(texts: string[]): Promise<number[][]>;\n generateErrorEmbedding(\n errorMessage: string,\n errorStack?: string,\n context?: { language?: string; framework?: string }\n ): Promise<number[]>;\n getDimensions(): number;\n getModel(): string;\n}\n\n/**\n * EmbeddingService configuration\n */\nexport interface EmbeddingServiceConfig {\n apiKey: string;\n model?: string;\n dimensions?: number;\n}\n\n/**\n * Calculate cosine similarity between two embeddings\n */\nexport function cosineSimilarity(a: number[], b: number[]): number {\n if (a.length !== b.length) {\n throw new Error('Embeddings must have same dimensions');\n }\n\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n\n const magnitude = Math.sqrt(normA) * Math.sqrt(normB);\n if (magnitude === 0) return 0;\n\n return dotProduct / magnitude;\n}\n\n/**\n * Create an EmbeddingService instance\n * Factory function pattern to avoid ES6 class issues with Bun\n */\nexport async function createEmbeddingService(config: EmbeddingServiceConfig): Promise<EmbeddingService> {\n // Dynamic import for Bun ESM/CJS interop\n const OpenAI = await getOpenAIClass();\n const client = new OpenAI({ apiKey: config.apiKey });\n const model = config.model || DEFAULT_MODEL;\n const dimensions = config.dimensions || DEFAULT_DIMENSIONS;\n\n /**\n * Truncate text to fit within model limits\n */\n function truncateText(text: string): string {\n if (text.length <= MAX_INPUT_LENGTH) {\n return text;\n }\n\n // Try to truncate at a sensible boundary\n const truncated = text.substring(0, MAX_INPUT_LENGTH);\n const lastNewline = truncated.lastIndexOf('\\n');\n\n if (lastNewline > MAX_INPUT_LENGTH * 0.8) {\n return truncated.substring(0, lastNewline);\n }\n\n return truncated;\n }\n\n return {\n /**\n * Generate embedding for a single text\n */\n async generate(text: string): Promise<number[]> {\n const truncated = truncateText(text);\n\n const response = await client.embeddings.create({\n model,\n input: truncated,\n dimensions,\n });\n\n return response.data[0].embedding;\n },\n\n /**\n * Generate embeddings for multiple texts\n */\n async generateBatch(texts: string[]): Promise<number[][]> {\n const truncated = texts.map((t) => truncateText(t));\n\n const response = await client.embeddings.create({\n model,\n input: truncated,\n dimensions,\n });\n\n return response.data.map((d) => d.embedding);\n },\n\n /**\n * Generate embedding for error context\n * Combines error message, stack trace, and context\n */\n async generateErrorEmbedding(\n errorMessage: string,\n errorStack?: string,\n context?: { language?: string; framework?: string }\n ): Promise<number[]> {\n // Build context string\n const parts: string[] = [];\n\n if (context?.language) {\n parts.push(`Language: ${context.language}`);\n }\n if (context?.framework) {\n parts.push(`Framework: ${context.framework}`);\n }\n\n parts.push(`Error: ${errorMessage}`);\n\n if (errorStack) {\n parts.push(`Stack Trace:\\n${errorStack}`);\n }\n\n const text = parts.join('\\n');\n // Generate embedding directly (avoid this reference issues)\n const truncated = truncateText(text);\n const response = await client.embeddings.create({\n model,\n input: truncated,\n dimensions,\n });\n return response.data[0].embedding;\n },\n\n /**\n * Get embedding dimensions\n */\n getDimensions(): number {\n return dimensions;\n },\n\n /**\n * Get model name\n */\n getModel(): string {\n return model;\n },\n };\n}\n\n/**\n * Legacy class wrapper for backwards compatibility\n * @deprecated Use createEmbeddingService() instead\n */\nexport const EmbeddingService = {\n create: createEmbeddingService,\n cosineSimilarity,\n};\n","/**\n * FixHive Cloud Client\n * Supabase client for cloud knowledge base operations\n */\n\nimport type { SupabaseClient } from '@supabase/supabase-js';\nimport type {\n CloudKnowledgeEntry,\n SearchRequest,\n SearchResponse,\n UploadRequest,\n UploadResponse,\n DuplicateCheckResult,\n ContributorStats,\n} from '../types/index.js';\nimport { createEmbeddingService, type EmbeddingService } from './embedding.js';\nimport { generateContributorId } from '../core/hash.js';\n\n/**\n * Dynamic import helper for Supabase (Bun ESM/CJS interop)\n */\nasync function getSupabaseCreateClient(): Promise<typeof import('@supabase/supabase-js').createClient> {\n const mod = await import('@supabase/supabase-js');\n // Handle various export patterns\n return mod.createClient || (mod as unknown as { default: { createClient: typeof mod.createClient } }).default?.createClient;\n}\n\n/**\n * Cloud Client Configuration\n */\nexport interface CloudClientConfig {\n supabaseUrl: string;\n supabaseAnonKey: string;\n openaiApiKey?: string;\n contributorId?: string;\n similarityThreshold?: number;\n}\n\n/**\n * CloudClient interface - defines all public methods\n */\nexport interface CloudClient {\n searchSimilar(request: SearchRequest): Promise<SearchResponse>;\n uploadResolution(request: UploadRequest): Promise<UploadResponse>;\n checkDuplicate(errorHash: string, embedding: number[]): Promise<DuplicateCheckResult>;\n vote(knowledgeId: string, helpful: boolean): Promise<{ success: boolean; error?: string }>;\n reportEntry(knowledgeId: string, reason?: string): Promise<{ success: boolean }>;\n reportHelpful(knowledgeId: string): Promise<void>;\n getContributorStats(): Promise<ContributorStats>;\n getEntry(id: string): Promise<CloudKnowledgeEntry | null>;\n getContributorId(): string;\n hasEmbeddingService(): boolean;\n}\n\n/**\n * Map database row to CloudKnowledgeEntry\n */\nfunction mapToKnowledgeEntry(row: Record<string, unknown>): CloudKnowledgeEntry {\n return {\n id: row.id as string,\n errorHash: row.error_hash as string,\n errorType: row.error_type as CloudKnowledgeEntry['errorType'],\n errorMessage: row.error_message as string,\n errorStack: (row.error_stack as string) || undefined,\n language: row.language as CloudKnowledgeEntry['language'],\n framework: (row.framework as string) || undefined,\n dependencies: (row.dependencies as Record<string, string>) || undefined,\n resolutionDescription: row.resolution_description as string,\n resolutionCode: (row.resolution_code as string) || undefined,\n resolutionSteps: (row.resolution_steps as string[]) || undefined,\n contributorId: row.contributor_id as string,\n upvotes: (row.upvotes as number) || 0,\n downvotes: (row.downvotes as number) || 0,\n usageCount: (row.usage_count as number) || 0,\n createdAt: row.created_at as string,\n updatedAt: row.updated_at as string,\n isVerified: (row.is_verified as boolean) || false,\n similarity: (row.similarity as number) || undefined,\n };\n}\n\n/**\n * Create a CloudClient instance\n * Factory function pattern to avoid ES6 class issues with Bun\n */\nexport async function createCloudClient(config: CloudClientConfig): Promise<CloudClient> {\n // Create Supabase client using dynamic import for Bun compatibility\n const createClient = await getSupabaseCreateClient();\n const supabase: SupabaseClient = createClient(config.supabaseUrl, config.supabaseAnonKey);\n\n // Initialize embedding service (optional)\n let embedding: EmbeddingService | null = null;\n if (config.openaiApiKey) {\n try {\n embedding = await createEmbeddingService({ apiKey: config.openaiApiKey });\n } catch (err) {\n console.warn('[FixHive] Failed to initialize embedding service:', err);\n }\n }\n\n const contributorId = config.contributorId || generateContributorId();\n const similarityThreshold = config.similarityThreshold || 0.7;\n\n // Private helper for duplicate check\n async function checkDuplicateInternal(errorHash: string, embeddingData: number[]): Promise<DuplicateCheckResult> {\n // First check by exact hash\n const { data: hashMatch } = await supabase\n .from('knowledge_entries')\n .select('id')\n .eq('error_hash', errorHash)\n .limit(1)\n .single();\n\n if (hashMatch) {\n return {\n isDuplicate: true,\n existingId: hashMatch.id,\n similarityScore: 1.0,\n };\n }\n\n // Then check by embedding similarity\n const { data, error } = await supabase.rpc('check_duplicate_entry', {\n new_hash: errorHash,\n new_embedding: embeddingData,\n similarity_threshold: 0.95,\n });\n\n if (error || !data || data.length === 0) {\n return { isDuplicate: false, similarityScore: 0 };\n }\n\n const result = data[0];\n return {\n isDuplicate: result.is_duplicate,\n existingId: result.existing_id,\n similarityScore: result.similarity_score,\n };\n }\n\n // Private helper for text-based search\n async function searchByText(request: SearchRequest): Promise<SearchResponse> {\n const startTime = Date.now();\n\n let query = supabase\n .from('knowledge_entries')\n .select('*')\n .ilike('error_message', `%${request.errorMessage.substring(0, 100)}%`)\n .order('upvotes', { ascending: false })\n .limit(request.limit || 10);\n\n if (request.language) {\n query = query.eq('language', request.language);\n }\n\n if (request.framework) {\n query = query.eq('framework', request.framework);\n }\n\n const { data, error } = await query;\n\n if (error) {\n console.error('Text search error:', error);\n return { results: [], queryTime: Date.now() - startTime, cached: false };\n }\n\n return {\n results: (data || []).map(mapToKnowledgeEntry),\n queryTime: Date.now() - startTime,\n cached: false,\n };\n }\n\n // Return object with all methods (closure pattern)\n return {\n async searchSimilar(request: SearchRequest): Promise<SearchResponse> {\n const startTime = Date.now();\n\n // If no embedding service, fall back to text search\n if (!embedding) {\n return searchByText(request);\n }\n\n // Generate embedding for search query\n const queryText = `${request.errorMessage}\\n${request.errorStack || ''}`;\n const queryEmbedding = await embedding.generate(queryText);\n\n // Call Supabase RPC function\n const { data, error } = await supabase.rpc('search_similar_errors', {\n query_embedding: queryEmbedding,\n match_threshold: request.threshold || similarityThreshold,\n match_count: request.limit || 10,\n filter_language: request.language || null,\n filter_framework: request.framework || null,\n });\n\n if (error) {\n console.error('Search error:', error);\n return { results: [], queryTime: Date.now() - startTime, cached: false };\n }\n\n return {\n results: (data || []).map(mapToKnowledgeEntry),\n queryTime: Date.now() - startTime,\n cached: false,\n };\n },\n\n async uploadResolution(request: UploadRequest): Promise<UploadResponse> {\n const { errorRecord, resolution, resolutionCode, resolutionSteps } = request;\n\n // Generate embedding if available\n let embeddingData: number[] | null = null;\n if (embedding) {\n const embeddingText = `${errorRecord.errorMessage}\\n${errorRecord.errorStack || ''}`;\n embeddingData = await embedding.generate(embeddingText);\n }\n\n // Check for duplicates\n if (embeddingData) {\n const duplicateCheck = await checkDuplicateInternal(errorRecord.errorHash, embeddingData);\n\n if (duplicateCheck.isDuplicate && duplicateCheck.similarityScore > 0.95) {\n // Increment usage count on existing entry\n await supabase.rpc('increment_usage_count', {\n entry_id: duplicateCheck.existingId,\n });\n\n return {\n success: true,\n isDuplicate: true,\n existingId: duplicateCheck.existingId,\n message: 'Similar solution already exists. Usage count incremented.',\n };\n }\n }\n\n // Insert new entry\n const { data, error } = await supabase\n .from('knowledge_entries')\n .insert({\n error_hash: errorRecord.errorHash,\n error_type: errorRecord.errorType,\n error_message: errorRecord.errorMessage,\n error_stack: errorRecord.errorStack,\n language: errorRecord.language || 'other',\n framework: errorRecord.framework,\n embedding: embeddingData,\n resolution_description: resolution,\n resolution_code: resolutionCode,\n resolution_steps: resolutionSteps,\n contributor_id: contributorId,\n })\n .select('id')\n .single();\n\n if (error) {\n return {\n success: false,\n isDuplicate: false,\n message: `Upload failed: ${error.message}`,\n };\n }\n\n return {\n success: true,\n knowledgeId: data.id,\n isDuplicate: false,\n message: 'Solution uploaded successfully!',\n };\n },\n\n async checkDuplicate(errorHash: string, embeddingData: number[]): Promise<DuplicateCheckResult> {\n return checkDuplicateInternal(errorHash, embeddingData);\n },\n\n async vote(knowledgeId: string, helpful: boolean): Promise<{ success: boolean; error?: string }> {\n const voteType = helpful ? 'up' : 'down';\n\n const { data, error } = await supabase.rpc('safe_vote', {\n p_entry_id: knowledgeId,\n p_user_hash: contributorId,\n p_vote_type: voteType,\n });\n\n if (error) {\n return { success: false, error: error.message };\n }\n\n const result = data as { success: boolean; error?: string; action?: string };\n\n // Log usage only on successful new vote\n if (result.success) {\n await supabase.from('usage_logs').insert({\n knowledge_id: knowledgeId,\n action: helpful ? 'upvote' : 'downvote',\n user_hash: contributorId,\n });\n }\n\n return result;\n },\n\n async reportEntry(knowledgeId: string, reason?: string): Promise<{ success: boolean }> {\n const { data, error } = await supabase.rpc('report_entry', {\n p_entry_id: knowledgeId,\n p_user_hash: contributorId,\n p_reason: reason || null,\n });\n\n if (error) {\n return { success: false };\n }\n\n return data as { success: boolean };\n },\n\n async reportHelpful(knowledgeId: string): Promise<void> {\n await supabase.rpc('increment_usage_count', {\n entry_id: knowledgeId,\n });\n\n await supabase.from('usage_logs').insert({\n knowledge_id: knowledgeId,\n action: 'apply',\n user_hash: contributorId,\n });\n },\n\n async getContributorStats(): Promise<ContributorStats> {\n const { data } = await supabase\n .from('knowledge_entries')\n .select('upvotes, usage_count')\n .eq('contributor_id', contributorId);\n\n if (!data || data.length === 0) {\n return { contributionCount: 0, helpedCount: 0, totalUpvotes: 0 };\n }\n\n return {\n contributionCount: data.length,\n helpedCount: data.reduce((sum, e) => sum + (e.usage_count || 0), 0),\n totalUpvotes: data.reduce((sum, e) => sum + (e.upvotes || 0), 0),\n };\n },\n\n async getEntry(id: string): Promise<CloudKnowledgeEntry | null> {\n const { data, error } = await supabase\n .from('knowledge_entries')\n .select('*')\n .eq('id', id)\n .single();\n\n if (error || !data) {\n return null;\n }\n\n return mapToKnowledgeEntry(data);\n },\n\n getContributorId(): string {\n return contributorId;\n },\n\n hasEmbeddingService(): boolean {\n return embedding !== null;\n },\n };\n}\n\n// Legacy export for backwards compatibility\n// CloudClient is now an interface, use createCloudClient() instead\nexport const CloudClient = {\n create: createCloudClient,\n};\n","/**\n * FixHive Custom Tools\n * OpenCode plugin tools for error knowledge management\n */\n\nimport { tool } from '@opencode-ai/plugin';\nimport type { LocalStore } from '../storage/local-store.js';\nimport type { CloudClient } from '../cloud/client.js';\nimport type { PrivacyFilter } from '../core/privacy-filter.js';\nimport type { FixHiveContext, CloudKnowledgeEntry, LocalErrorRecord } from '../types/index.js';\n\n/**\n * Create FixHive tools for OpenCode plugin\n * @returns Record of tool definitions\n */\nexport function createTools(\n localStore: LocalStore,\n cloudClient: CloudClient,\n privacyFilter: PrivacyFilter,\n context: FixHiveContext\n): Record<string, ReturnType<typeof tool>> {\n return {\n /**\n * Search cloud knowledge base for error solutions\n */\n fixhive_search: tool({\n description:\n 'Search FixHive knowledge base for error solutions. Use when encountering errors to find community solutions.',\n args: {\n errorMessage: tool.schema.string().describe('The error message to search for'),\n language: tool.schema\n .string()\n .optional()\n .describe('Programming language (typescript, python, etc.)'),\n framework: tool.schema\n .string()\n .optional()\n .describe('Framework (react, nextjs, express, etc.)'),\n limit: tool.schema.number().optional().describe('Maximum results (default: 5)'),\n },\n async execute(args, ctx) {\n context.sessionId = ctx.sessionID;\n\n // Check local cache first\n const sanitized = privacyFilter.sanitize(args.errorMessage);\n const cachedResults = localStore.getCachedResults(sanitized.sanitized);\n\n if (cachedResults && cachedResults.length > 0) {\n return formatSearchResults(cachedResults, true);\n }\n\n // Search cloud\n const results = await cloudClient.searchSimilar({\n errorMessage: sanitized.sanitized,\n language: args.language as LocalErrorRecord['language'],\n framework: args.framework,\n limit: args.limit || 5,\n });\n\n if (results.results.length === 0) {\n return 'No matching solutions found in FixHive knowledge base.';\n }\n\n // Cache results\n localStore.cacheResults(sanitized.sanitized, results.results);\n\n return formatSearchResults(results.results, false);\n },\n }),\n\n /**\n * Mark error as resolved and optionally upload solution\n */\n fixhive_resolve: tool({\n description:\n 'Mark an error as resolved and optionally share the solution with the community.',\n args: {\n errorId: tool.schema.string().describe('Error ID from fixhive_list'),\n resolution: tool.schema\n .string()\n .describe('Description of how the error was resolved'),\n resolutionCode: tool.schema\n .string()\n .optional()\n .describe('Code fix or diff that resolved the error'),\n upload: tool.schema\n .boolean()\n .optional()\n .describe('Upload solution to community (default: true)'),\n },\n async execute(args, ctx) {\n context.sessionId = ctx.sessionID;\n\n // Update local record\n const record = localStore.markResolved(args.errorId, {\n resolution: args.resolution,\n resolutionCode: args.resolutionCode,\n });\n\n if (!record) {\n return `Error with ID ${args.errorId} not found.`;\n }\n\n // Upload to cloud if requested\n if (args.upload !== false) {\n const uploadResult = await cloudClient.uploadResolution({\n errorRecord: record,\n resolution: args.resolution,\n resolutionCode: args.resolutionCode,\n });\n\n if (uploadResult.isDuplicate) {\n return `Error resolved locally. Similar solution already exists in FixHive (ID: ${uploadResult.existingId}).`;\n }\n\n if (uploadResult.success && uploadResult.knowledgeId) {\n localStore.markUploaded(args.errorId, uploadResult.knowledgeId);\n return `Error resolved and shared with FixHive community! Knowledge ID: ${uploadResult.knowledgeId}`;\n }\n\n return `Error resolved locally. Upload failed: ${uploadResult.message}`;\n }\n\n return 'Error marked as resolved locally.';\n },\n }),\n\n /**\n * List errors in current session\n */\n fixhive_list: tool({\n description: 'List errors detected in the current session.',\n args: {\n status: tool.schema\n .enum(['unresolved', 'resolved', 'uploaded'])\n .optional()\n .describe('Filter by status'),\n limit: tool.schema.number().optional().describe('Maximum results (default: 10)'),\n },\n async execute(args, ctx) {\n context.sessionId = ctx.sessionID;\n\n const errors = localStore.getSessionErrors(ctx.sessionID, {\n status: args.status as LocalErrorRecord['status'],\n limit: args.limit || 10,\n });\n\n if (errors.length === 0) {\n return 'No errors recorded in this session.';\n }\n\n return formatErrorList(errors);\n },\n }),\n\n /**\n * Vote on a solution\n */\n fixhive_vote: tool({\n description:\n 'Upvote or downvote a FixHive solution based on whether it helped.',\n args: {\n knowledgeId: tool.schema.string().describe('Knowledge entry ID'),\n helpful: tool.schema\n .boolean()\n .describe('True for upvote, false for downvote'),\n },\n async execute(args) {\n const result = await cloudClient.vote(args.knowledgeId, args.helpful);\n\n if (!result.success) {\n if (result.error === 'Already voted') {\n return 'You have already voted on this solution.';\n }\n return `Vote failed: ${result.error}`;\n }\n\n return args.helpful\n ? 'Thanks for the feedback! Solution upvoted.'\n : 'Thanks for the feedback! Solution downvoted.';\n },\n }),\n\n /**\n * Report inappropriate content\n */\n fixhive_report: tool({\n description:\n 'Report a FixHive solution for inappropriate content, spam, or incorrect information.',\n args: {\n knowledgeId: tool.schema.string().describe('Knowledge entry ID to report'),\n reason: tool.schema\n .string()\n .optional()\n .describe('Reason for reporting (spam, incorrect, inappropriate, etc.)'),\n },\n async execute(args) {\n const result = await cloudClient.reportEntry(args.knowledgeId, args.reason);\n\n if (!result.success) {\n return 'Failed to submit report. Please try again later.';\n }\n\n return 'Report submitted. Thank you for helping keep FixHive clean!';\n },\n }),\n\n /**\n * Get usage statistics\n */\n fixhive_stats: tool({\n description: 'Get FixHive usage statistics.',\n args: {},\n async execute() {\n const localStats = localStore.getStats();\n const cloudStats = await cloudClient.getContributorStats();\n\n return `\n## FixHive Statistics\n\n### Local\n- Errors recorded: ${localStats.totalErrors}\n- Resolved: ${localStats.resolvedErrors}\n- Uploaded: ${localStats.uploadedErrors}\n\n### Community Contributions\n- Solutions shared: ${cloudStats.contributionCount}\n- Times your solutions helped: ${cloudStats.helpedCount}\n- Total upvotes received: ${cloudStats.totalUpvotes}\n`;\n },\n }),\n\n /**\n * Report that a solution was helpful\n */\n fixhive_helpful: tool({\n description:\n 'Report that a FixHive solution was helpful and resolved your issue.',\n args: {\n knowledgeId: tool.schema.string().describe('Knowledge entry ID that helped'),\n },\n async execute(args) {\n await cloudClient.reportHelpful(args.knowledgeId);\n return 'Thanks! Your feedback helps improve solution rankings.';\n },\n }),\n };\n}\n\n/**\n * Format search results for display\n */\nfunction formatSearchResults(\n results: CloudKnowledgeEntry[],\n cached: boolean\n): string {\n const header = cached\n ? `## FixHive Solutions Found (${results.length}) [Cached]`\n : `## FixHive Solutions Found (${results.length})`;\n\n const entries = results\n .map((r, i) => {\n const similarity = r.similarity\n ? ` (${Math.round(r.similarity * 100)}% match)`\n : '';\n\n let entry = `\n### ${i + 1}. ${r.errorMessage.slice(0, 80)}...${similarity}\n**Language:** ${r.language} | **Framework:** ${r.framework || 'N/A'} | **Upvotes:** ${r.upvotes}\n\n**Resolution:**\n${r.resolutionDescription}\n`;\n\n if (r.resolutionCode) {\n entry += `\n**Code Fix:**\n\\`\\`\\`\n${r.resolutionCode}\n\\`\\`\\`\n`;\n }\n\n if (r.resolutionSteps?.length) {\n entry += `\n**Steps:**\n${r.resolutionSteps.map((s, j) => `${j + 1}. ${s}`).join('\\n')}\n`;\n }\n\n entry += `\n*ID: ${r.id}*\n\n---`;\n\n return entry;\n })\n .join('\\n');\n\n return `${header}\\n${entries}\\n\\nUse \\`fixhive_vote\\` to rate solutions or \\`fixhive_helpful\\` if a solution resolved your issue.`;\n}\n\n/**\n * Format error list for display\n */\nfunction formatErrorList(errors: LocalErrorRecord[]): string {\n const header = `## Session Errors (${errors.length})`;\n\n const table = `\n| ID | Type | Status | Message |\n|----|------|--------|---------|\n${errors\n .map(\n (e) =>\n `| ${e.id.slice(0, 8)} | ${e.errorType} | ${e.status} | ${e.errorMessage.slice(0, 50)}... |`\n )\n .join('\\n')}\n`;\n\n return `${header}\\n${table}\\n\\nUse \\`fixhive_resolve <id>\\` to mark as resolved and share solutions.`;\n}\n"],"mappings":"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","names":["tool","existsSync","severity","tool","existsSync"]}