From 4c63261e3c54d09d0b59cf2e06ac8ac317548db7 Mon Sep 17 00:00:00 2001 From: aviram fireberger Date: Thu, 12 Feb 2026 01:00:35 +1100 Subject: [PATCH 1/2] fix: add missing parseAgentFrontmatter import and ErrorBoundary - Add parseAgentFrontmatter to the import from ./agents in main.ts (was used at 5 locations but never imported, causing ReferenceError at runtime that flooded logs and led to black screen) - Remove duplicate getAllAgents import on line 168 - Add React ErrorBoundary component wrapping the app to prevent future uncaught render errors from causing blank screens --- src/main/main.ts | 4 +- src/renderer/components/ErrorBoundary.tsx | 69 +++++++++++++++++++++++ src/renderer/main.tsx | 9 ++- 3 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 src/renderer/components/ErrorBoundary.tsx diff --git a/src/main/main.ts b/src/main/main.ts index cfd89e5..9c59c6b 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -160,13 +160,11 @@ async function writeMcpConfig(config: MCPConfigFile): Promise { import { getAllSkills } from './skills'; // Agent discovery - imported from agents module -import { getAllAgents } from './agents'; +import { getAllAgents, parseAgentFrontmatter } from './agents'; // Copilot Instructions - imported from instructions module import { getAllInstructions, getGitRoot } from './instructions'; -import { getAllAgents } from './agents'; - // Set up file logging only - no IPC to renderer (causes errors) log.transports.file.level = 'info'; log.transports.console.level = 'info'; diff --git a/src/renderer/components/ErrorBoundary.tsx b/src/renderer/components/ErrorBoundary.tsx new file mode 100644 index 0000000..c1ef033 --- /dev/null +++ b/src/renderer/components/ErrorBoundary.tsx @@ -0,0 +1,69 @@ +import React from 'react'; + +interface ErrorBoundaryProps { + children: React.ReactNode; +} + +interface ErrorBoundaryState { + hasError: boolean; + error: Error | null; +} + +export class ErrorBoundary extends React.Component { + constructor(props: ErrorBoundaryProps) { + super(props); + this.state = { hasError: false, error: null }; + } + + static getDerivedStateFromError(error: Error): ErrorBoundaryState { + return { hasError: true, error }; + } + + componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void { + console.error('[ErrorBoundary] Uncaught render error:', error, errorInfo.componentStack); + } + + handleReload = (): void => { + window.location.reload(); + }; + + handleDismiss = (): void => { + this.setState({ hasError: false, error: null }); + }; + + render(): React.ReactNode { + if (this.state.hasError) { + return ( +
+
+

Something went wrong

+

+ An unexpected error occurred. You can try dismissing this or reloading the app. +

+ {this.state.error && ( +
+                {this.state.error.message}
+              
+ )} +
+ + +
+
+
+ ); + } + + return this.props.children; + } +} diff --git a/src/renderer/main.tsx b/src/renderer/main.tsx index 6f1913f..0ffe513 100644 --- a/src/renderer/main.tsx +++ b/src/renderer/main.tsx @@ -2,12 +2,15 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import { ThemeProvider } from './context/ThemeContext'; +import { ErrorBoundary } from './components/ErrorBoundary'; import './styles/global.css'; ReactDOM.createRoot(document.getElementById('root')!).render( - - - + + + + + ); From eb3582c7ad2fdf2b67317d46bc1dad6b579b3a13 Mon Sep 17 00:00:00 2001 From: aviram fireberger Date: Thu, 12 Feb 2026 01:13:57 +1100 Subject: [PATCH 2/2] fix: guard against undefined server.tools in MCP panel server.tools can be undefined at runtime even though the type declares string[]. Add optional chaining and fallback defaults at both locations (lines 3360 and 4570) to prevent TypeError when clicking MCP servers panel. --- src/renderer/App.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index 6991990..59f6580 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -3357,7 +3357,7 @@ Only when ALL the above are verified complete, output exactly: ${RALPH_COMPLETIO command: isLocal ? (server as MCPLocalServerConfig).command : '', args: isLocal ? (server as MCPLocalServerConfig).args.join(' ') : '', url: !isLocal ? (server as MCPRemoteServerConfig).url : '', - tools: server.tools[0] === '*' ? '*' : server.tools.join(', '), + tools: server.tools?.[0] === '*' ? '*' : (server.tools || []).join(', '), }); setShowMcpModal(true); }; @@ -4567,7 +4567,7 @@ Only when ALL the above are verified complete, output exactly: ${RALPH_COMPLETIO const isLocal = !server.type || server.type === 'local' || server.type === 'stdio'; const toolCount = - server.tools[0] === '*' ? 'all' : `${server.tools.length}`; + server.tools?.[0] === '*' ? 'all' : `${server.tools?.length ?? 0}`; return (
{isLocal ? (