@uncaughtdev/core 0.1.1 → 0.2.0

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.
Files changed (52) hide show
  1. package/README.md +44 -3
  2. package/dist/chunk-2YXXFGBV.js +2 -0
  3. package/dist/chunk-2YXXFGBV.js.map +1 -0
  4. package/dist/chunk-3FCDO7OR.mjs +23 -0
  5. package/dist/chunk-3FCDO7OR.mjs.map +1 -0
  6. package/dist/chunk-A6GKDPT3.mjs +2 -0
  7. package/dist/chunk-A6GKDPT3.mjs.map +1 -0
  8. package/dist/chunk-BXMN7NW4.mjs +2 -0
  9. package/dist/chunk-BXMN7NW4.mjs.map +1 -0
  10. package/dist/chunk-HANXURHX.mjs +59 -0
  11. package/dist/chunk-HANXURHX.mjs.map +1 -0
  12. package/dist/chunk-MSUAXLMV.js +2 -0
  13. package/dist/chunk-MSUAXLMV.js.map +1 -0
  14. package/dist/chunk-VQXSHR3C.js +59 -0
  15. package/dist/chunk-VQXSHR3C.js.map +1 -0
  16. package/dist/chunk-WZBG5VLB.js +23 -0
  17. package/dist/chunk-WZBG5VLB.js.map +1 -0
  18. package/dist/index.d.mts +64 -3
  19. package/dist/index.d.ts +64 -3
  20. package/dist/index.js +7 -26
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +7 -26
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/local-api-handler-pages.js +1 -1
  25. package/dist/local-api-handler-pages.js.map +1 -1
  26. package/dist/local-api-handler-pages.mjs +1 -1
  27. package/dist/local-api-handler-pages.mjs.map +1 -1
  28. package/dist/local-api-handler.d.mts +1 -1
  29. package/dist/local-api-handler.d.ts +1 -1
  30. package/dist/local-api-handler.js +1 -1
  31. package/dist/local-api-handler.mjs +1 -1
  32. package/dist/local-viewer.js +432 -46
  33. package/dist/local-viewer.js.map +1 -1
  34. package/dist/local-viewer.mjs +432 -46
  35. package/dist/local-viewer.mjs.map +1 -1
  36. package/dist/mcp-server.d.mts +1 -0
  37. package/dist/mcp-server.d.ts +1 -0
  38. package/dist/mcp-server.js +22 -0
  39. package/dist/mcp-server.js.map +1 -0
  40. package/dist/mcp-server.mjs +22 -0
  41. package/dist/mcp-server.mjs.map +1 -0
  42. package/dist/sqlite-store-4FTNST7O.js +2 -0
  43. package/dist/sqlite-store-4FTNST7O.js.map +1 -0
  44. package/dist/sqlite-store-TEXDAAOM.mjs +2 -0
  45. package/dist/sqlite-store-TEXDAAOM.mjs.map +1 -0
  46. package/dist/{types-CjgYXVc_.d.mts → types-D1Fw4k-D.d.mts} +12 -1
  47. package/dist/{types-CjgYXVc_.d.ts → types-D1Fw4k-D.d.ts} +12 -1
  48. package/package.json +9 -2
  49. package/dist/chunk-FFHQ452Q.js +0 -2
  50. package/dist/chunk-FFHQ452Q.js.map +0 -1
  51. package/dist/chunk-JALIO2BZ.mjs +0 -2
  52. package/dist/chunk-JALIO2BZ.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp-server.ts"],"names":["getBaseDir","getDbPath","withStore","fn","store","openStore","TOOLS","handleSetup","baseDir","execSync","error","handleListErrors","args","filter","issues","lines","issue","i","status","count","title","env","rel","handleGetError","fingerprint","event","parts","stack","crumb","handleGetFixPrompt","buildFixPrompt","handleGetStats","stats","handleResolveError","handleSearchErrors","query","matches","main","server","Server","ListToolsRequestSchema","CallToolRequestSchema","request","name","transport","StdioServerTransport"],"mappings":"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","file":"mcp-server.mjs","sourcesContent":["#!/usr/bin/env node\n// ---------------------------------------------------------------------------\n// @uncaughtdev/core — MCP server for AI coding assistants\n// ---------------------------------------------------------------------------\n\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { execSync } from 'child_process';\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { openStore, type SqliteStore } from './sqlite-store';\nimport { buildFixPrompt } from './prompt-builder';\nimport type { IssueStatus } from './types';\n\n// ---------------------------------------------------------------------------\n// Paths (same pattern as local-viewer.ts)\n// ---------------------------------------------------------------------------\n\nfunction getBaseDir(): string {\n return path.resolve(process.cwd(), '.uncaught');\n}\n\nfunction getDbPath(): string {\n return path.join(getBaseDir(), 'uncaught.db');\n}\n\nfunction withStore<T>(fn: (store: SqliteStore) => T): T {\n const store = openStore(getDbPath());\n store.importFromFiles(getBaseDir());\n try {\n return fn(store);\n } finally {\n store.close();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Tool definitions\n// ---------------------------------------------------------------------------\n\nconst TOOLS = [\n {\n name: 'setup_uncaught',\n description:\n 'Install and configure Uncaught error monitoring in the current project. ' +\n 'Auto-detects your framework (React, Next.js, Vite, etc.), installs packages, ' +\n 'and patches entry files. Run this first before any other tool.',\n inputSchema: {\n type: 'object' as const,\n properties: {},\n },\n },\n {\n name: 'list_errors',\n description:\n 'List all captured error issues. Returns fingerprint, title, error type, ' +\n 'count, status, and timestamps. Use this to see what bugs exist.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n status: {\n type: 'string',\n enum: ['open', 'resolved', 'ignored'],\n description: 'Filter by status. Omit for all issues.',\n },\n environment: {\n type: 'string',\n description: 'Filter by deploy environment (e.g. \"production\", \"staging\").',\n },\n },\n },\n },\n {\n name: 'get_error',\n description:\n 'Get full details of a specific error: stack trace, breadcrumbs (user actions ' +\n 'leading to the error), environment info, request context, and user info.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n fingerprint: {\n type: 'string',\n description: 'Error fingerprint ID. Use list_errors to find fingerprints.',\n },\n },\n required: ['fingerprint'],\n },\n },\n {\n name: 'get_fix_prompt',\n description:\n 'Get an AI-ready fix prompt for a specific error. Returns a structured ' +\n 'diagnosis with error details, stack trace, breadcrumbs, environment, and ' +\n 'what to investigate. Use this to understand and fix the bug.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n fingerprint: {\n type: 'string',\n description: 'Error fingerprint ID.',\n },\n },\n required: ['fingerprint'],\n },\n },\n {\n name: 'get_stats',\n description:\n 'Get error statistics: total issues, open, resolved, ignored, and total events.',\n inputSchema: {\n type: 'object' as const,\n properties: {},\n },\n },\n {\n name: 'resolve_error',\n description:\n 'Update an error\\'s status. Use after fixing a bug to mark it resolved.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n fingerprint: {\n type: 'string',\n description: 'Error fingerprint ID.',\n },\n status: {\n type: 'string',\n enum: ['resolved', 'ignored', 'open'],\n description: 'New status. Defaults to \"resolved\".',\n },\n },\n required: ['fingerprint'],\n },\n },\n {\n name: 'search_errors',\n description:\n 'Search errors by message text. Returns issues whose title matches the query.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n query: {\n type: 'string',\n description: 'Text to search for in error messages.',\n },\n },\n required: ['query'],\n },\n },\n];\n\n// ---------------------------------------------------------------------------\n// Tool handlers\n// ---------------------------------------------------------------------------\n\nfunction handleSetup(): { content: Array<{ type: string; text: string }>; isError?: boolean } {\n const baseDir = getBaseDir();\n\n // Check if already set up\n if (fs.existsSync(baseDir) && fs.existsSync(getDbPath())) {\n return {\n content: [{\n type: 'text',\n text: 'Uncaught is already set up in this project. The .uncaught/ directory and database exist.\\n\\nYou can use list_errors to check for captured errors.',\n }],\n };\n }\n\n try {\n const output = execSync('npx uncaughtdev init', {\n cwd: process.cwd(),\n encoding: 'utf-8',\n timeout: 60_000,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n return {\n content: [{\n type: 'text',\n text: `Uncaught has been set up successfully!\\n\\n${output}\\n\\nErrors will now be captured automatically. Use list_errors to check for captured errors.`,\n }],\n };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: 'text', text: `Setup failed: ${msg}` }],\n isError: true,\n };\n }\n}\n\nfunction handleListErrors(args: Record<string, unknown>): { content: Array<{ type: string; text: string }>; isError?: boolean } {\n if (!fs.existsSync(getDbPath())) {\n return {\n content: [{\n type: 'text',\n text: 'No error database found. Run setup_uncaught first to install error monitoring, or trigger some errors in your app.',\n }],\n };\n }\n\n const filter: { status?: IssueStatus; environment?: string } = {};\n if (args.status) filter.status = args.status as IssueStatus;\n if (args.environment) filter.environment = args.environment as string;\n\n const issues = withStore((store) => store.getIssues(filter));\n\n if (issues.length === 0) {\n const filterDesc = filter.status || filter.environment\n ? ` matching filters (status: ${filter.status ?? 'any'}, environment: ${filter.environment ?? 'any'})`\n : '';\n return {\n content: [{ type: 'text', text: `No errors found${filterDesc}. Your app is running clean!` }],\n };\n }\n\n const lines = issues.map((issue, i) => {\n const status = issue.status.toUpperCase().padEnd(8);\n const count = `x${issue.count}`.padEnd(5);\n const fp = issue.fingerprint.slice(0, 8);\n const title = issue.title.length > 80 ? issue.title.slice(0, 77) + '...' : issue.title;\n const env = issue.environment ? ` [${issue.environment}]` : '';\n const rel = issue.release ? ` (${issue.release})` : '';\n return `${i + 1}. [${status}] ${count} ${issue.errorType}: ${title}${env}${rel}\\n fingerprint: ${issue.fingerprint}\\n last seen: ${issue.lastSeen}`;\n });\n\n return {\n content: [{\n type: 'text',\n text: `Found ${issues.length} error(s):\\n\\n${lines.join('\\n\\n')}`,\n }],\n };\n}\n\nfunction handleGetError(args: Record<string, unknown>): { content: Array<{ type: string; text: string }>; isError?: boolean } {\n const fingerprint = args.fingerprint as string;\n\n return withStore((store) => {\n const issue = store.getIssue(fingerprint);\n if (!issue) {\n return {\n content: [{ type: 'text', text: `No error found with fingerprint: ${fingerprint}` }],\n isError: true,\n };\n }\n\n const event = store.getLatestEvent(fingerprint);\n const parts: string[] = [];\n\n parts.push(`# ${issue.errorType}: ${issue.title}`);\n parts.push('');\n parts.push(`**Status:** ${issue.status} | **Count:** ${issue.count} | **Affected users:** ${issue.affectedUsers.length}`);\n parts.push(`**First seen:** ${issue.firstSeen} | **Last seen:** ${issue.lastSeen}`);\n if (issue.release) parts.push(`**Release:** ${issue.release}`);\n if (issue.environment) parts.push(`**Environment:** ${issue.environment}`);\n parts.push(`**Fingerprint:** ${issue.fingerprint}`);\n\n if (event) {\n // Stack trace\n const stack = event.error.resolvedStack || event.error.stack;\n if (stack) {\n parts.push('');\n parts.push('## Stack Trace');\n parts.push('```');\n parts.push(stack);\n parts.push('```');\n }\n\n // Component stack (React)\n if (event.error.componentStack) {\n parts.push('');\n parts.push('## Component Stack');\n parts.push('```');\n parts.push(event.error.componentStack);\n parts.push('```');\n }\n\n // Breadcrumbs\n if (event.breadcrumbs && event.breadcrumbs.length > 0) {\n parts.push('');\n parts.push('## Breadcrumbs (user actions before error)');\n for (const crumb of event.breadcrumbs.slice(-10)) {\n parts.push(`- [${crumb.timestamp}] ${crumb.type}/${crumb.category}: ${crumb.message}`);\n }\n }\n\n // Environment\n if (event.environment) {\n parts.push('');\n parts.push('## Environment');\n const env = event.environment;\n if (env.framework) parts.push(`- Framework: ${env.framework} ${env.frameworkVersion ?? ''}`);\n if (env.runtime) parts.push(`- Runtime: ${env.runtime} ${env.runtimeVersion ?? ''}`);\n if (env.browser) parts.push(`- Browser: ${env.browser} ${env.browserVersion ?? ''}`);\n if (env.os) parts.push(`- OS: ${env.os}`);\n if (env.url) parts.push(`- URL: ${env.url}`);\n if (env.deploy) parts.push(`- Deploy: ${env.deploy}`);\n }\n\n // Request context\n if (event.request) {\n parts.push('');\n parts.push('## Request');\n parts.push(`- ${event.request.method ?? 'GET'} ${event.request.url ?? 'unknown'}`);\n }\n\n // User feedback\n if (event.userFeedback) {\n parts.push('');\n parts.push('## User Feedback');\n parts.push(event.userFeedback);\n }\n }\n\n return {\n content: [{ type: 'text', text: parts.join('\\n') }],\n };\n });\n}\n\nfunction handleGetFixPrompt(args: Record<string, unknown>): { content: Array<{ type: string; text: string }>; isError?: boolean } {\n const fingerprint = args.fingerprint as string;\n\n return withStore((store) => {\n const event = store.getLatestEvent(fingerprint);\n if (!event) {\n return {\n content: [{ type: 'text', text: `No error found with fingerprint: ${fingerprint}` }],\n isError: true,\n };\n }\n\n // Use the stored fix prompt, or generate one\n const prompt = event.fixPrompt || buildFixPrompt(event);\n\n return {\n content: [{ type: 'text', text: prompt }],\n };\n });\n}\n\nfunction handleGetStats(): { content: Array<{ type: string; text: string }>; isError?: boolean } {\n if (!fs.existsSync(getDbPath())) {\n return {\n content: [{\n type: 'text',\n text: 'No error database found. Run setup_uncaught first.',\n }],\n };\n }\n\n const stats = withStore((store) => store.getStats());\n\n return {\n content: [{\n type: 'text',\n text: [\n `Error Statistics:`,\n ` Total issues: ${stats.total}`,\n ` Open: ${stats.open}`,\n ` Resolved: ${stats.resolved}`,\n ` Ignored: ${stats.ignored}`,\n ` Total events: ${stats.totalEvents}`,\n ].join('\\n'),\n }],\n };\n}\n\nfunction handleResolveError(args: Record<string, unknown>): { content: Array<{ type: string; text: string }>; isError?: boolean } {\n const fingerprint = args.fingerprint as string;\n const status = (args.status as IssueStatus) ?? 'resolved';\n\n return withStore((store) => {\n const issue = store.getIssue(fingerprint);\n if (!issue) {\n return {\n content: [{ type: 'text', text: `No error found with fingerprint: ${fingerprint}` }],\n isError: true,\n };\n }\n\n store.updateIssueStatus(fingerprint, status);\n\n return {\n content: [{\n type: 'text',\n text: `Marked \"${issue.title}\" as ${status}.`,\n }],\n };\n });\n}\n\nfunction handleSearchErrors(args: Record<string, unknown>): { content: Array<{ type: string; text: string }>; isError?: boolean } {\n const query = (args.query as string).toLowerCase();\n\n if (!fs.existsSync(getDbPath())) {\n return {\n content: [{ type: 'text', text: 'No error database found. Run setup_uncaught first.' }],\n };\n }\n\n const allIssues = withStore((store) => store.getIssues());\n const matches = allIssues.filter(\n (issue) =>\n issue.title.toLowerCase().includes(query) ||\n issue.errorType.toLowerCase().includes(query)\n );\n\n if (matches.length === 0) {\n return {\n content: [{ type: 'text', text: `No errors matching \"${args.query}\".` }],\n };\n }\n\n const lines = matches.map((issue, i) => {\n const status = issue.status.toUpperCase().padEnd(8);\n const title = issue.title.length > 80 ? issue.title.slice(0, 77) + '...' : issue.title;\n return `${i + 1}. [${status}] ${issue.errorType}: ${title}\\n fingerprint: ${issue.fingerprint}`;\n });\n\n return {\n content: [{\n type: 'text',\n text: `Found ${matches.length} error(s) matching \"${args.query}\":\\n\\n${lines.join('\\n\\n')}`,\n }],\n };\n}\n\n// ---------------------------------------------------------------------------\n// Server\n// ---------------------------------------------------------------------------\n\nasync function main(): Promise<void> {\n const server = new Server(\n { name: 'uncaught-mcp', version: '0.2.0' },\n { capabilities: { tools: {} } }\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return { tools: TOOLS };\n });\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n switch (name) {\n case 'setup_uncaught':\n return handleSetup();\n case 'list_errors':\n return handleListErrors(args ?? {});\n case 'get_error':\n return handleGetError(args ?? {});\n case 'get_fix_prompt':\n return handleGetFixPrompt(args ?? {});\n case 'get_stats':\n return handleGetStats();\n case 'resolve_error':\n return handleResolveError(args ?? {});\n case 'search_errors':\n return handleSearchErrors(args ?? {});\n default:\n return {\n content: [{ type: 'text', text: `Unknown tool: ${name}` }],\n isError: true,\n };\n }\n } catch (error) {\n return {\n content: [{\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n }],\n isError: true,\n };\n }\n });\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((error) => {\n console.error('Uncaught MCP server failed to start:', error);\n process.exit(1);\n});\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkVQXSHR3C_js=require('./chunk-VQXSHR3C.js');require('./chunk-2YXXFGBV.js');Object.defineProperty(exports,"openStore",{enumerable:true,get:function(){return chunkVQXSHR3C_js.a}});//# sourceMappingURL=sqlite-store-4FTNST7O.js.map
2
+ //# sourceMappingURL=sqlite-store-4FTNST7O.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"sqlite-store-4FTNST7O.js"}
@@ -0,0 +1,2 @@
1
+ export{a as openStore}from'./chunk-HANXURHX.mjs';import'./chunk-A6GKDPT3.mjs';//# sourceMappingURL=sqlite-store-TEXDAAOM.mjs.map
2
+ //# sourceMappingURL=sqlite-store-TEXDAAOM.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"sqlite-store-TEXDAAOM.mjs"}
@@ -41,12 +41,18 @@ interface UncaughtConfig {
41
41
  * Defaults to `process.cwd() + '/.uncaught'`.
42
42
  */
43
43
  localOutputDir?: string;
44
+ /**
45
+ * Webhook URL to POST notifications when a new error fingerprint is first seen.
46
+ * Payload: `{ title, errorType, fingerprint, level, timestamp, release, environment, fixPrompt }`.
47
+ */
48
+ webhookUrl?: string;
44
49
  }
45
50
  /** Structured representation of a captured error. */
46
51
  interface ErrorInfo {
47
52
  message: string;
48
53
  type: string;
49
54
  stack?: string;
55
+ resolvedStack?: string;
50
56
  componentStack?: string;
51
57
  raw?: unknown;
52
58
  }
@@ -88,17 +94,19 @@ interface UncaughtEvent {
88
94
  projectKey?: string;
89
95
  level: SeverityLevel;
90
96
  fingerprint: string;
97
+ release?: string;
91
98
  error: ErrorInfo;
92
99
  breadcrumbs: Breadcrumb[];
93
100
  request?: RequestInfo;
94
101
  operation?: OperationInfo;
95
102
  environment?: EnvironmentInfo;
96
103
  user?: UserInfo;
104
+ userFeedback?: string;
97
105
  fixPrompt: string;
98
106
  sdk: SdkInfo;
99
107
  }
100
108
  /** Breadcrumb categories. */
101
- type BreadcrumbType = 'click' | 'navigation' | 'api_call' | 'db_query' | 'auth' | 'console' | 'custom';
109
+ type BreadcrumbType = 'click' | 'navigation' | 'api_call' | 'db_query' | 'auth' | 'console' | 'web_vital' | 'custom';
102
110
  /** A single breadcrumb entry. */
103
111
  interface Breadcrumb {
104
112
  type: BreadcrumbType;
@@ -133,6 +141,7 @@ interface EnvironmentInfo {
133
141
  locale?: string;
134
142
  timezone?: string;
135
143
  url?: string;
144
+ deploy?: string;
136
145
  }
137
146
  /** Options used to configure a remote transport. */
138
147
  interface TransportOptions {
@@ -159,6 +168,8 @@ interface IssueEntry {
159
168
  status: IssueStatus;
160
169
  fixPromptFile: string;
161
170
  latestEventFile: string;
171
+ release?: string;
172
+ environment?: string;
162
173
  }
163
174
 
164
175
  export type { Breadcrumb as B, EnvironmentInfo as E, IssueEntry as I, OperationInfo as O, RequestInfo as R, SeverityLevel as S, Transport as T, UncaughtEvent as U, UncaughtConfig as a, UserInfo as b, BreadcrumbStore as c, BreadcrumbType as d, ErrorInfo as e, IssueStatus as f, SdkInfo as g, TransportMode as h, TransportOptions as i };
@@ -41,12 +41,18 @@ interface UncaughtConfig {
41
41
  * Defaults to `process.cwd() + '/.uncaught'`.
42
42
  */
43
43
  localOutputDir?: string;
44
+ /**
45
+ * Webhook URL to POST notifications when a new error fingerprint is first seen.
46
+ * Payload: `{ title, errorType, fingerprint, level, timestamp, release, environment, fixPrompt }`.
47
+ */
48
+ webhookUrl?: string;
44
49
  }
45
50
  /** Structured representation of a captured error. */
46
51
  interface ErrorInfo {
47
52
  message: string;
48
53
  type: string;
49
54
  stack?: string;
55
+ resolvedStack?: string;
50
56
  componentStack?: string;
51
57
  raw?: unknown;
52
58
  }
@@ -88,17 +94,19 @@ interface UncaughtEvent {
88
94
  projectKey?: string;
89
95
  level: SeverityLevel;
90
96
  fingerprint: string;
97
+ release?: string;
91
98
  error: ErrorInfo;
92
99
  breadcrumbs: Breadcrumb[];
93
100
  request?: RequestInfo;
94
101
  operation?: OperationInfo;
95
102
  environment?: EnvironmentInfo;
96
103
  user?: UserInfo;
104
+ userFeedback?: string;
97
105
  fixPrompt: string;
98
106
  sdk: SdkInfo;
99
107
  }
100
108
  /** Breadcrumb categories. */
101
- type BreadcrumbType = 'click' | 'navigation' | 'api_call' | 'db_query' | 'auth' | 'console' | 'custom';
109
+ type BreadcrumbType = 'click' | 'navigation' | 'api_call' | 'db_query' | 'auth' | 'console' | 'web_vital' | 'custom';
102
110
  /** A single breadcrumb entry. */
103
111
  interface Breadcrumb {
104
112
  type: BreadcrumbType;
@@ -133,6 +141,7 @@ interface EnvironmentInfo {
133
141
  locale?: string;
134
142
  timezone?: string;
135
143
  url?: string;
144
+ deploy?: string;
136
145
  }
137
146
  /** Options used to configure a remote transport. */
138
147
  interface TransportOptions {
@@ -159,6 +168,8 @@ interface IssueEntry {
159
168
  status: IssueStatus;
160
169
  fixPromptFile: string;
161
170
  latestEventFile: string;
171
+ release?: string;
172
+ environment?: string;
162
173
  }
163
174
 
164
175
  export type { Breadcrumb as B, EnvironmentInfo as E, IssueEntry as I, OperationInfo as O, RequestInfo as R, SeverityLevel as S, Transport as T, UncaughtEvent as U, UncaughtConfig as a, UserInfo as b, BreadcrumbStore as c, BreadcrumbType as d, ErrorInfo as e, IssueStatus as f, SdkInfo as g, TransportMode as h, TransportOptions as i };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uncaughtdev/core",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Core engine for Uncaught error monitoring — transport, breadcrumbs, and fix prompt generation",
5
5
  "license": "MIT",
6
6
  "author": "Uncaught",
@@ -40,13 +40,20 @@
40
40
  }
41
41
  },
42
42
  "bin": {
43
- "uncaught": "./dist/local-viewer.js"
43
+ "uncaught": "./dist/local-viewer.js",
44
+ "uncaught-mcp": "./dist/mcp-server.js"
44
45
  },
45
46
  "sideEffects": false,
46
47
  "files": [
47
48
  "dist"
48
49
  ],
50
+ "dependencies": {
51
+ "@modelcontextprotocol/sdk": "^1.0.0",
52
+ "better-sqlite3": "^11.0.0",
53
+ "source-map": "^0.7.6"
54
+ },
49
55
  "devDependencies": {
56
+ "@types/better-sqlite3": "^7.6.0",
50
57
  "@types/node": "^25.3.3",
51
58
  "tsup": "^8.0.0",
52
59
  "typescript": "^5.4.0",
@@ -1,2 +0,0 @@
1
- 'use strict';var chunkE76GW6KF_js=require('./chunk-E76GW6KF.js');async function P(a){try{if(typeof process<"u"&&process.env.NODE_ENV==="production"&&process.env.UNCAUGHT_LOCAL_IN_PROD!=="true")return new Response(JSON.stringify({error:"Local handler is disabled in production"}),{status:403,headers:{"Content-Type":"application/json"}});let e;try{e=await a.json();}catch{return new Response(JSON.stringify({error:"Invalid JSON body"}),{status:400,headers:{"Content-Type":"application/json"}})}if(!e||typeof e!="object"||!Array.isArray(e.events))return new Response(JSON.stringify({error:'Payload must contain an "events" array'}),{status:400,headers:{"Content-Type":"application/json"}});let t=e.events;return t.length===0?new Response(JSON.stringify({accepted:0}),{status:202,headers:{"Content-Type":"application/json"}}):(await E(t),new Response(JSON.stringify({accepted:t.length}),{status:202,headers:{"Content-Type":"application/json"}}))}catch(e){let t=e instanceof Error?e.message:"Internal server error";return new Response(JSON.stringify({error:t}),{status:500,headers:{"Content-Type":"application/json"}})}}async function E(a){let e=await import('fs/promises'),t=await import('path'),r=t.resolve(process.cwd(),".uncaught");await e.mkdir(t.join(r,"events"),{recursive:true}),await e.mkdir(t.join(r,"fix-prompts"),{recursive:true});let p=t.join(r,"issues.json"),o=[];try{let n=await e.readFile(p,"utf-8");o=JSON.parse(n);}catch{}for(let n of a){let i=n.fingerprint;if(!i)continue;let c=t.join(r,"events",i);await e.mkdir(c,{recursive:true});let u=`event-${(n.timestamp??new Date().toISOString()).replace(/[:.]/g,"-")}.json`,w=t.join(c,u),y=w+".tmp";await e.writeFile(y,chunkE76GW6KF_js.b(n),"utf-8"),await e.rename(y,w);let g=t.join(c,"latest.json"),v=g+".tmp";await e.writeFile(v,chunkE76GW6KF_js.b(n),"utf-8"),await e.rename(v,g);let f=`${i}.md`,h=t.join(r,"fix-prompts",f),S=h+".tmp";await e.writeFile(S,n.fixPrompt??"","utf-8"),await e.rename(S,h);let m=n.user?.id??n.user?.email??"anonymous",s=o.find(j=>j.fingerprint===i);s?(s.count+=1,s.lastSeen=n.timestamp,s.latestEventFile=u,s.fixPromptFile=f,s.affectedUsers.includes(String(m))||s.affectedUsers.push(String(m)),s.status==="resolved"&&(s.status="open")):o.push({fingerprint:i,title:n.error?.message??"Unknown error",errorType:n.error?.type??"Error",count:1,affectedUsers:[String(m)],firstSeen:n.timestamp,lastSeen:n.timestamp,status:"open",fixPromptFile:f,latestEventFile:u});}let l=p+".tmp";await e.writeFile(l,JSON.stringify(o,null,2),"utf-8"),await e.rename(l,p);}exports.a=P;exports.b=E;//# sourceMappingURL=chunk-FFHQ452Q.js.map
2
- //# sourceMappingURL=chunk-FFHQ452Q.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/local-api-handler.ts"],"names":["POST","request","body","events","writeEvents","err","message","fs","path","baseDir","indexPath","issues","raw","event","fp","eventDir","eventFile","eventPath","tmpEvent","safeStringify","latestPath","tmpLatest","promptFile","promptPath","tmpPrompt","userId","existing","i","tmpIndex"],"mappings":"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","file":"chunk-FFHQ452Q.js","sourcesContent":["// ---------------------------------------------------------------------------\n// @uncaughtdev/core — Next.js App Router local API handler\n// ---------------------------------------------------------------------------\n//\n// Usage:\n// // app/api/uncaught/local/route.ts\n// export { POST } from '@uncaughtdev/core/local-api-handler';\n//\n// ---------------------------------------------------------------------------\n\nimport type { UncaughtEvent, IssueEntry } from './types';\nimport { safeStringify } from './utils';\n\n/**\n * Next.js App Router POST handler.\n * Accepts `{ events: UncaughtEvent[] }` and writes them to `.uncaught/`.\n *\n * Blocked in production unless `UNCAUGHT_LOCAL_IN_PROD=true` is set.\n */\nexport async function POST(request: Request): Promise<Response> {\n try {\n // --- Production guard --------------------------------------------------\n if (\n typeof process !== 'undefined' &&\n process.env.NODE_ENV === 'production' &&\n process.env.UNCAUGHT_LOCAL_IN_PROD !== 'true'\n ) {\n return new Response(\n JSON.stringify({ error: 'Local handler is disabled in production' }),\n { status: 403, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // --- Parse body --------------------------------------------------------\n let body: unknown;\n try {\n body = await request.json();\n } catch {\n return new Response(\n JSON.stringify({ error: 'Invalid JSON body' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n if (\n !body ||\n typeof body !== 'object' ||\n !Array.isArray((body as Record<string, unknown>).events)\n ) {\n return new Response(\n JSON.stringify({ error: 'Payload must contain an \"events\" array' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const events = (body as { events: UncaughtEvent[] }).events;\n\n if (events.length === 0) {\n return new Response(\n JSON.stringify({ accepted: 0 }),\n { status: 202, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // --- Write events to disk ----------------------------------------------\n await writeEvents(events);\n\n return new Response(\n JSON.stringify({ accepted: events.length }),\n { status: 202, headers: { 'Content-Type': 'application/json' } }\n );\n } catch (err) {\n const message =\n err instanceof Error ? err.message : 'Internal server error';\n return new Response(\n JSON.stringify({ error: message }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// Shared disk-writing logic\n// ---------------------------------------------------------------------------\n\nexport async function writeEvents(events: UncaughtEvent[]): Promise<void> {\n const fs = await import('fs/promises');\n const path = await import('path');\n\n const baseDir = path.resolve(process.cwd(), '.uncaught');\n await fs.mkdir(path.join(baseDir, 'events'), { recursive: true });\n await fs.mkdir(path.join(baseDir, 'fix-prompts'), { recursive: true });\n\n // Load existing issues index\n const indexPath = path.join(baseDir, 'issues.json');\n let issues: IssueEntry[] = [];\n try {\n const raw = await fs.readFile(indexPath, 'utf-8');\n issues = JSON.parse(raw) as IssueEntry[];\n } catch {\n // Start fresh.\n }\n\n for (const event of events) {\n const fp = event.fingerprint;\n if (!fp) continue;\n\n const eventDir = path.join(baseDir, 'events', fp);\n await fs.mkdir(eventDir, { recursive: true });\n\n // Timestamped event file\n const ts = (event.timestamp ?? new Date().toISOString()).replace(\n /[:.]/g,\n '-'\n );\n const eventFile = `event-${ts}.json`;\n const eventPath = path.join(eventDir, eventFile);\n const tmpEvent = eventPath + '.tmp';\n await fs.writeFile(tmpEvent, safeStringify(event), 'utf-8');\n await fs.rename(tmpEvent, eventPath);\n\n // latest.json\n const latestPath = path.join(eventDir, 'latest.json');\n const tmpLatest = latestPath + '.tmp';\n await fs.writeFile(tmpLatest, safeStringify(event), 'utf-8');\n await fs.rename(tmpLatest, latestPath);\n\n // Fix-prompt markdown\n const promptFile = `${fp}.md`;\n const promptPath = path.join(baseDir, 'fix-prompts', promptFile);\n const tmpPrompt = promptPath + '.tmp';\n await fs.writeFile(tmpPrompt, event.fixPrompt ?? '', 'utf-8');\n await fs.rename(tmpPrompt, promptPath);\n\n // Update issues index\n const userId =\n (event.user as Record<string, unknown> | undefined)?.id ??\n (event.user as Record<string, unknown> | undefined)?.email ??\n 'anonymous';\n\n const existing = issues.find((i) => i.fingerprint === fp);\n if (existing) {\n existing.count += 1;\n existing.lastSeen = event.timestamp;\n existing.latestEventFile = eventFile;\n existing.fixPromptFile = promptFile;\n if (!existing.affectedUsers.includes(String(userId))) {\n existing.affectedUsers.push(String(userId));\n }\n if (existing.status === 'resolved') {\n existing.status = 'open';\n }\n } else {\n issues.push({\n fingerprint: fp,\n title: event.error?.message ?? 'Unknown error',\n errorType: event.error?.type ?? 'Error',\n count: 1,\n affectedUsers: [String(userId)],\n firstSeen: event.timestamp,\n lastSeen: event.timestamp,\n status: 'open',\n fixPromptFile: promptFile,\n latestEventFile: eventFile,\n });\n }\n }\n\n // Write updated index atomically\n const tmpIndex = indexPath + '.tmp';\n await fs.writeFile(tmpIndex, JSON.stringify(issues, null, 2), 'utf-8');\n await fs.rename(tmpIndex, indexPath);\n}\n"]}
@@ -1,2 +0,0 @@
1
- import {b}from'./chunk-P6JRN5CN.mjs';async function P(a){try{if(typeof process<"u"&&process.env.NODE_ENV==="production"&&process.env.UNCAUGHT_LOCAL_IN_PROD!=="true")return new Response(JSON.stringify({error:"Local handler is disabled in production"}),{status:403,headers:{"Content-Type":"application/json"}});let e;try{e=await a.json();}catch{return new Response(JSON.stringify({error:"Invalid JSON body"}),{status:400,headers:{"Content-Type":"application/json"}})}if(!e||typeof e!="object"||!Array.isArray(e.events))return new Response(JSON.stringify({error:'Payload must contain an "events" array'}),{status:400,headers:{"Content-Type":"application/json"}});let t=e.events;return t.length===0?new Response(JSON.stringify({accepted:0}),{status:202,headers:{"Content-Type":"application/json"}}):(await E(t),new Response(JSON.stringify({accepted:t.length}),{status:202,headers:{"Content-Type":"application/json"}}))}catch(e){let t=e instanceof Error?e.message:"Internal server error";return new Response(JSON.stringify({error:t}),{status:500,headers:{"Content-Type":"application/json"}})}}async function E(a){let e=await import('fs/promises'),t=await import('path'),r=t.resolve(process.cwd(),".uncaught");await e.mkdir(t.join(r,"events"),{recursive:true}),await e.mkdir(t.join(r,"fix-prompts"),{recursive:true});let p=t.join(r,"issues.json"),o=[];try{let n=await e.readFile(p,"utf-8");o=JSON.parse(n);}catch{}for(let n of a){let i=n.fingerprint;if(!i)continue;let c=t.join(r,"events",i);await e.mkdir(c,{recursive:true});let u=`event-${(n.timestamp??new Date().toISOString()).replace(/[:.]/g,"-")}.json`,w=t.join(c,u),y=w+".tmp";await e.writeFile(y,b(n),"utf-8"),await e.rename(y,w);let g=t.join(c,"latest.json"),v=g+".tmp";await e.writeFile(v,b(n),"utf-8"),await e.rename(v,g);let f=`${i}.md`,h=t.join(r,"fix-prompts",f),S=h+".tmp";await e.writeFile(S,n.fixPrompt??"","utf-8"),await e.rename(S,h);let m=n.user?.id??n.user?.email??"anonymous",s=o.find(j=>j.fingerprint===i);s?(s.count+=1,s.lastSeen=n.timestamp,s.latestEventFile=u,s.fixPromptFile=f,s.affectedUsers.includes(String(m))||s.affectedUsers.push(String(m)),s.status==="resolved"&&(s.status="open")):o.push({fingerprint:i,title:n.error?.message??"Unknown error",errorType:n.error?.type??"Error",count:1,affectedUsers:[String(m)],firstSeen:n.timestamp,lastSeen:n.timestamp,status:"open",fixPromptFile:f,latestEventFile:u});}let l=p+".tmp";await e.writeFile(l,JSON.stringify(o,null,2),"utf-8"),await e.rename(l,p);}export{P as a,E as b};//# sourceMappingURL=chunk-JALIO2BZ.mjs.map
2
- //# sourceMappingURL=chunk-JALIO2BZ.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/local-api-handler.ts"],"names":["POST","request","body","events","writeEvents","err","message","fs","path","baseDir","indexPath","issues","raw","event","fp","eventDir","eventFile","eventPath","tmpEvent","safeStringify","latestPath","tmpLatest","promptFile","promptPath","tmpPrompt","userId","existing","i","tmpIndex"],"mappings":"qCAmBA,eAAsBA,CAAAA,CAAKC,CAAAA,CAAqC,CAC9D,GAAI,CAEF,GACE,OAAO,OAAA,CAAY,GAAA,EACnB,OAAA,CAAQ,GAAA,CAAI,QAAA,GAAa,YAAA,EACzB,OAAA,CAAQ,GAAA,CAAI,sBAAA,GAA2B,MAAA,CAEvC,OAAO,IAAI,QAAA,CACT,IAAA,CAAK,SAAA,CAAU,CAAE,KAAA,CAAO,yCAA0C,CAAC,CAAA,CACnE,CAAE,MAAA,CAAQ,IAAK,OAAA,CAAS,CAAE,cAAA,CAAgB,kBAAmB,CAAE,CACjE,CAAA,CAIF,IAAIC,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAAO,MAAMD,CAAAA,CAAQ,IAAA,GACvB,CAAA,KAAQ,CACN,OAAO,IAAI,QAAA,CACT,IAAA,CAAK,SAAA,CAAU,CAAE,KAAA,CAAO,mBAAoB,CAAC,CAAA,CAC7C,CAAE,MAAA,CAAQ,IAAK,OAAA,CAAS,CAAE,cAAA,CAAgB,kBAAmB,CAAE,CACjE,CACF,CAEA,GACE,CAACC,CAAAA,EACD,OAAOA,CAAAA,EAAS,QAAA,EAChB,CAAC,KAAA,CAAM,OAAA,CAASA,CAAAA,CAAiC,MAAM,CAAA,CAEvD,OAAO,IAAI,QAAA,CACT,IAAA,CAAK,SAAA,CAAU,CAAE,KAAA,CAAO,wCAAyC,CAAC,CAAA,CAClE,CAAE,MAAA,CAAQ,GAAA,CAAK,OAAA,CAAS,CAAE,cAAA,CAAgB,kBAAmB,CAAE,CACjE,CAAA,CAGF,IAAMC,CAAAA,CAAUD,CAAAA,CAAqC,MAAA,CAErD,OAAIC,CAAAA,CAAO,MAAA,GAAW,CAAA,CACb,IAAI,QAAA,CACT,IAAA,CAAK,SAAA,CAAU,CAAE,QAAA,CAAU,CAAE,CAAC,CAAA,CAC9B,CAAE,MAAA,CAAQ,GAAA,CAAK,OAAA,CAAS,CAAE,cAAA,CAAgB,kBAAmB,CAAE,CACjE,CAAA,EAIF,MAAMC,CAAAA,CAAYD,CAAM,CAAA,CAEjB,IAAI,QAAA,CACT,IAAA,CAAK,SAAA,CAAU,CAAE,QAAA,CAAUA,CAAAA,CAAO,MAAO,CAAC,CAAA,CAC1C,CAAE,MAAA,CAAQ,GAAA,CAAK,OAAA,CAAS,CAAE,cAAA,CAAgB,kBAAmB,CAAE,CACjE,CAAA,CACF,CAAA,MAASE,EAAK,CACZ,IAAMC,CAAAA,CACJD,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,uBAAA,CACvC,OAAO,IAAI,QAAA,CACT,IAAA,CAAK,SAAA,CAAU,CAAE,KAAA,CAAOC,CAAQ,CAAC,CAAA,CACjC,CAAE,MAAA,CAAQ,GAAA,CAAK,OAAA,CAAS,CAAE,cAAA,CAAgB,kBAAmB,CAAE,CACjE,CACF,CACF,CAMA,eAAsBF,CAAAA,CAAYD,CAAAA,CAAwC,CACxE,IAAMI,CAAAA,CAAK,MAAM,OAAO,aAAa,CAAA,CAC/BC,CAAAA,CAAO,MAAM,OAAO,MAAM,CAAA,CAE1BC,CAAAA,CAAUD,CAAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,GAAA,EAAI,CAAG,WAAW,CAAA,CACvD,MAAMD,CAAAA,CAAG,KAAA,CAAMC,CAAAA,CAAK,IAAA,CAAKC,CAAAA,CAAS,QAAQ,CAAA,CAAG,CAAE,SAAA,CAAW,IAAK,CAAC,CAAA,CAChE,MAAMF,CAAAA,CAAG,KAAA,CAAMC,CAAAA,CAAK,IAAA,CAAKC,CAAAA,CAAS,aAAa,CAAA,CAAG,CAAE,SAAA,CAAW,IAAK,CAAC,CAAA,CAGrE,IAAMC,CAAAA,CAAYF,CAAAA,CAAK,IAAA,CAAKC,CAAAA,CAAS,aAAa,CAAA,CAC9CE,CAAAA,CAAuB,EAAC,CAC5B,GAAI,CACF,IAAMC,CAAAA,CAAM,MAAML,CAAAA,CAAG,QAAA,CAASG,CAAAA,CAAW,OAAO,CAAA,CAChDC,CAAAA,CAAS,IAAA,CAAK,KAAA,CAAMC,CAAG,EACzB,CAAA,KAAQ,CAER,CAEA,IAAA,IAAWC,CAAAA,IAASV,CAAAA,CAAQ,CAC1B,IAAMW,CAAAA,CAAKD,CAAAA,CAAM,WAAA,CACjB,GAAI,CAACC,CAAAA,CAAI,SAET,IAAMC,CAAAA,CAAWP,CAAAA,CAAK,IAAA,CAAKC,CAAAA,CAAS,SAAUK,CAAE,CAAA,CAChD,MAAMP,CAAAA,CAAG,KAAA,CAAMQ,CAAAA,CAAU,CAAE,SAAA,CAAW,IAAK,CAAC,CAAA,CAO5C,IAAMC,CAAAA,CAAY,CAAA,MAAA,EAAA,CAJNH,CAAAA,CAAM,SAAA,EAAa,IAAI,IAAA,EAAK,CAAE,WAAA,EAAY,EAAG,OAAA,CACvD,OAAA,CACA,GACF,CAC6B,CAAA,KAAA,CAAA,CACvBI,CAAAA,CAAYT,CAAAA,CAAK,IAAA,CAAKO,CAAAA,CAAUC,CAAS,CAAA,CACzCE,CAAAA,CAAWD,CAAAA,CAAY,MAAA,CAC7B,MAAMV,CAAAA,CAAG,SAAA,CAAUW,CAAAA,CAAUC,CAAAA,CAAcN,CAAK,CAAA,CAAG,OAAO,CAAA,CAC1D,MAAMN,CAAAA,CAAG,MAAA,CAAOW,CAAAA,CAAUD,CAAS,CAAA,CAGnC,IAAMG,CAAAA,CAAaZ,CAAAA,CAAK,IAAA,CAAKO,CAAAA,CAAU,aAAa,CAAA,CAC9CM,CAAAA,CAAYD,CAAAA,CAAa,MAAA,CAC/B,MAAMb,EAAG,SAAA,CAAUc,CAAAA,CAAWF,CAAAA,CAAcN,CAAK,CAAA,CAAG,OAAO,CAAA,CAC3D,MAAMN,CAAAA,CAAG,MAAA,CAAOc,CAAAA,CAAWD,CAAU,CAAA,CAGrC,IAAME,CAAAA,CAAa,CAAA,EAAGR,CAAE,CAAA,GAAA,CAAA,CAClBS,CAAAA,CAAaf,CAAAA,CAAK,IAAA,CAAKC,CAAAA,CAAS,aAAA,CAAea,CAAU,CAAA,CACzDE,CAAAA,CAAYD,CAAAA,CAAa,MAAA,CAC/B,MAAMhB,CAAAA,CAAG,UAAUiB,CAAAA,CAAWX,CAAAA,CAAM,SAAA,EAAa,EAAA,CAAI,OAAO,CAAA,CAC5D,MAAMN,CAAAA,CAAG,MAAA,CAAOiB,CAAAA,CAAWD,CAAU,CAAA,CAGrC,IAAME,CAAAA,CACHZ,CAAAA,CAAM,IAAA,EAA8C,EAAA,EACpDA,CAAAA,CAAM,IAAA,EAA8C,KAAA,EACrD,WAAA,CAEIa,CAAAA,CAAWf,CAAAA,CAAO,IAAA,CAAMgB,CAAAA,EAAMA,CAAAA,CAAE,WAAA,GAAgBb,CAAE,CAAA,CACpDY,CAAAA,EACFA,EAAS,KAAA,EAAS,CAAA,CAClBA,CAAAA,CAAS,QAAA,CAAWb,CAAAA,CAAM,SAAA,CAC1Ba,CAAAA,CAAS,eAAA,CAAkBV,CAAAA,CAC3BU,CAAAA,CAAS,aAAA,CAAgBJ,CAAAA,CACpBI,CAAAA,CAAS,aAAA,CAAc,QAAA,CAAS,MAAA,CAAOD,CAAM,CAAC,CAAA,EACjDC,CAAAA,CAAS,aAAA,CAAc,IAAA,CAAK,MAAA,CAAOD,CAAM,CAAC,CAAA,CAExCC,CAAAA,CAAS,MAAA,GAAW,UAAA,GACtBA,CAAAA,CAAS,OAAS,MAAA,CAAA,EAGpBf,CAAAA,CAAO,IAAA,CAAK,CACV,WAAA,CAAaG,CAAAA,CACb,KAAA,CAAOD,CAAAA,CAAM,KAAA,EAAO,OAAA,EAAW,eAAA,CAC/B,SAAA,CAAWA,CAAAA,CAAM,KAAA,EAAO,IAAA,EAAQ,OAAA,CAChC,KAAA,CAAO,CAAA,CACP,aAAA,CAAe,CAAC,MAAA,CAAOY,CAAM,CAAC,CAAA,CAC9B,SAAA,CAAWZ,CAAAA,CAAM,SAAA,CACjB,QAAA,CAAUA,CAAAA,CAAM,SAAA,CAChB,MAAA,CAAQ,MAAA,CACR,aAAA,CAAeS,CAAAA,CACf,eAAA,CAAiBN,CACnB,CAAC,EAEL,CAGA,IAAMY,CAAAA,CAAWlB,CAAAA,CAAY,MAAA,CAC7B,MAAMH,CAAAA,CAAG,SAAA,CAAUqB,CAAAA,CAAU,IAAA,CAAK,SAAA,CAAUjB,CAAAA,CAAQ,IAAA,CAAM,CAAC,CAAA,CAAG,OAAO,CAAA,CACrE,MAAMJ,CAAAA,CAAG,MAAA,CAAOqB,CAAAA,CAAUlB,CAAS,EACrC","file":"chunk-JALIO2BZ.mjs","sourcesContent":["// ---------------------------------------------------------------------------\n// @uncaughtdev/core — Next.js App Router local API handler\n// ---------------------------------------------------------------------------\n//\n// Usage:\n// // app/api/uncaught/local/route.ts\n// export { POST } from '@uncaughtdev/core/local-api-handler';\n//\n// ---------------------------------------------------------------------------\n\nimport type { UncaughtEvent, IssueEntry } from './types';\nimport { safeStringify } from './utils';\n\n/**\n * Next.js App Router POST handler.\n * Accepts `{ events: UncaughtEvent[] }` and writes them to `.uncaught/`.\n *\n * Blocked in production unless `UNCAUGHT_LOCAL_IN_PROD=true` is set.\n */\nexport async function POST(request: Request): Promise<Response> {\n try {\n // --- Production guard --------------------------------------------------\n if (\n typeof process !== 'undefined' &&\n process.env.NODE_ENV === 'production' &&\n process.env.UNCAUGHT_LOCAL_IN_PROD !== 'true'\n ) {\n return new Response(\n JSON.stringify({ error: 'Local handler is disabled in production' }),\n { status: 403, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // --- Parse body --------------------------------------------------------\n let body: unknown;\n try {\n body = await request.json();\n } catch {\n return new Response(\n JSON.stringify({ error: 'Invalid JSON body' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n if (\n !body ||\n typeof body !== 'object' ||\n !Array.isArray((body as Record<string, unknown>).events)\n ) {\n return new Response(\n JSON.stringify({ error: 'Payload must contain an \"events\" array' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const events = (body as { events: UncaughtEvent[] }).events;\n\n if (events.length === 0) {\n return new Response(\n JSON.stringify({ accepted: 0 }),\n { status: 202, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // --- Write events to disk ----------------------------------------------\n await writeEvents(events);\n\n return new Response(\n JSON.stringify({ accepted: events.length }),\n { status: 202, headers: { 'Content-Type': 'application/json' } }\n );\n } catch (err) {\n const message =\n err instanceof Error ? err.message : 'Internal server error';\n return new Response(\n JSON.stringify({ error: message }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// Shared disk-writing logic\n// ---------------------------------------------------------------------------\n\nexport async function writeEvents(events: UncaughtEvent[]): Promise<void> {\n const fs = await import('fs/promises');\n const path = await import('path');\n\n const baseDir = path.resolve(process.cwd(), '.uncaught');\n await fs.mkdir(path.join(baseDir, 'events'), { recursive: true });\n await fs.mkdir(path.join(baseDir, 'fix-prompts'), { recursive: true });\n\n // Load existing issues index\n const indexPath = path.join(baseDir, 'issues.json');\n let issues: IssueEntry[] = [];\n try {\n const raw = await fs.readFile(indexPath, 'utf-8');\n issues = JSON.parse(raw) as IssueEntry[];\n } catch {\n // Start fresh.\n }\n\n for (const event of events) {\n const fp = event.fingerprint;\n if (!fp) continue;\n\n const eventDir = path.join(baseDir, 'events', fp);\n await fs.mkdir(eventDir, { recursive: true });\n\n // Timestamped event file\n const ts = (event.timestamp ?? new Date().toISOString()).replace(\n /[:.]/g,\n '-'\n );\n const eventFile = `event-${ts}.json`;\n const eventPath = path.join(eventDir, eventFile);\n const tmpEvent = eventPath + '.tmp';\n await fs.writeFile(tmpEvent, safeStringify(event), 'utf-8');\n await fs.rename(tmpEvent, eventPath);\n\n // latest.json\n const latestPath = path.join(eventDir, 'latest.json');\n const tmpLatest = latestPath + '.tmp';\n await fs.writeFile(tmpLatest, safeStringify(event), 'utf-8');\n await fs.rename(tmpLatest, latestPath);\n\n // Fix-prompt markdown\n const promptFile = `${fp}.md`;\n const promptPath = path.join(baseDir, 'fix-prompts', promptFile);\n const tmpPrompt = promptPath + '.tmp';\n await fs.writeFile(tmpPrompt, event.fixPrompt ?? '', 'utf-8');\n await fs.rename(tmpPrompt, promptPath);\n\n // Update issues index\n const userId =\n (event.user as Record<string, unknown> | undefined)?.id ??\n (event.user as Record<string, unknown> | undefined)?.email ??\n 'anonymous';\n\n const existing = issues.find((i) => i.fingerprint === fp);\n if (existing) {\n existing.count += 1;\n existing.lastSeen = event.timestamp;\n existing.latestEventFile = eventFile;\n existing.fixPromptFile = promptFile;\n if (!existing.affectedUsers.includes(String(userId))) {\n existing.affectedUsers.push(String(userId));\n }\n if (existing.status === 'resolved') {\n existing.status = 'open';\n }\n } else {\n issues.push({\n fingerprint: fp,\n title: event.error?.message ?? 'Unknown error',\n errorType: event.error?.type ?? 'Error',\n count: 1,\n affectedUsers: [String(userId)],\n firstSeen: event.timestamp,\n lastSeen: event.timestamp,\n status: 'open',\n fixPromptFile: promptFile,\n latestEventFile: eventFile,\n });\n }\n }\n\n // Write updated index atomically\n const tmpIndex = indexPath + '.tmp';\n await fs.writeFile(tmpIndex, JSON.stringify(issues, null, 2), 'utf-8');\n await fs.rename(tmpIndex, indexPath);\n}\n"]}