diff --git a/gitnexus/src/App.tsx b/gitnexus/src/App.tsx index 2b8c22de2..c305a18a4 100644 --- a/gitnexus/src/App.tsx +++ b/gitnexus/src/App.tsx @@ -41,12 +41,12 @@ const AppContent = () => { const projectName = file.name.replace('.zip', ''); setProjectName(projectName); setViewMode('loading'); - + try { const result = await runPipeline(file, (progress) => { setProgress(progress); }); - + setGraph(result.graph); setFileContents(result.fileContents); setViewMode('exploring'); @@ -54,9 +54,9 @@ const AppContent = () => { // Initialize (or re-initialize) the agent AFTER a repo loads so it captures // the current codebase context (file contents + graph tools) in the worker. if (getActiveProviderConfig()) { - initializeAgent(); + initializeAgent(projectName); } - + // Auto-start embeddings pipeline in background // Uses WebGPU if available, falls back to WASM startEmbeddings().catch((err) => { @@ -86,15 +86,15 @@ const AppContent = () => { // Extract project name from first file path (e.g., "owner-repo-123/src/..." -> "owner-repo") const firstPath = files[0]?.path || 'repository'; const projectName = firstPath.split('/')[0].replace(/-\d+$/, '') || 'repository'; - + setProjectName(projectName); setViewMode('loading'); - + try { const result = await runPipelineFromFiles(files, (progress) => { setProgress(progress); }); - + setGraph(result.graph); setFileContents(result.fileContents); setViewMode('exploring'); @@ -102,9 +102,9 @@ const AppContent = () => { // Initialize (or re-initialize) the agent AFTER a repo loads so it captures // the current codebase context (file contents + graph tools) in the worker. if (getActiveProviderConfig()) { - initializeAgent(); + initializeAgent(projectName); } - + // Auto-start embeddings pipeline in background // Uses WebGPU if available, falls back to WASM startEmbeddings().catch((err) => { @@ -154,11 +154,11 @@ const AppContent = () => { return (
- +
{/* Left Panel - File Tree */} - + {/* Graph area - takes remaining space */}
@@ -170,13 +170,13 @@ const AppContent = () => {
)}
- + {/* Right Panel - Code & Chat (tabbed) */} {isRightPanelOpen && } - + - + {/* Settings Panel (modal) */} ('disconnected'); const [copied, setCopied] = useState(false); const [showSetup, setShowSetup] = useState(false); + const [hasConnectionError, setHasConnectionError] = useState(false); + const setupPopupRef = useRef(null); const [showTip, setShowTip] = useState(false); const isConnected = status === 'connected'; @@ -62,6 +64,21 @@ export function MCPToggle({ } }, [showOnboardingTip]); + // Close setup popup when clicking outside + useEffect(() => { + if (!showSetup) return; + + const handleClickOutside = (event: MouseEvent) => { + if (!setupPopupRef.current) return; + if (!setupPopupRef.current.contains(event.target as Node)) { + setShowSetup(false); + } + }; + + document.addEventListener('mousedown', handleClickOutside); + return () => document.removeEventListener('mousedown', handleClickOutside); + }, [showSetup]); + const dismissTip = () => { setShowTip(false); localStorage.setItem(MCP_TIP_DISMISSED_KEY, 'true'); @@ -71,6 +88,7 @@ export function MCPToggle({ const client = getMCPClient(); setStatus('connecting'); setShowTip(false); + setHasConnectionError(false); try { await client.connect(); @@ -125,6 +143,7 @@ export function MCPToggle({ setStatus('connected'); setShowSetup(false); + setHasConnectionError(false); localStorage.setItem(MCP_TIP_DISMISSED_KEY, 'true'); // Send codebase context after connecting @@ -141,6 +160,7 @@ export function MCPToggle({ } catch { setStatus('error'); setShowSetup(true); + setHasConnectionError(true); } }, [onSearch, onCypher, onBlastRadius, onHighlight, onGrep, onRead, getContext]); @@ -148,6 +168,7 @@ export function MCPToggle({ const client = getMCPClient(); client.disconnect(); setStatus('disconnected'); + setHasConnectionError(false); }, []); const toggle = useCallback(() => { @@ -158,8 +179,8 @@ export function MCPToggle({ } }, [isConnected, isConnecting, connect, disconnect]); - const copyCommand = () => { - navigator.clipboard.writeText('npx gitnexus-mcp setup'); + const copyCommand = (command: string) => { + navigator.clipboard.writeText(command); setCopied(true); setTimeout(() => setCopied(false), 2000); }; @@ -168,13 +189,19 @@ export function MCPToggle({ useEffect(() => { const client = getMCPClient(); const unsubscribe = client.onConnectionChange((connected) => { - setStatus(connected ? 'connected' : 'disconnected'); + if (connected) { + setStatus('connected'); + setShowSetup(false); + setHasConnectionError(false); + } else { + setStatus('disconnected'); + } }); return () => { unsubscribe(); }; }, []); // Error state - show setup popup - if (status === 'error' && showSetup) { + if (hasConnectionError && showSetup) { return (
MCP @@ -183,30 +210,74 @@ export function MCPToggle({ className="flex items-center gap-1.5 px-2 py-1 text-xs text-amber-400 hover:bg-amber-400/10 rounded transition-colors" > - Setup + Daemon -
-

- Run this command to enable external AI agents: +

+

+ MCP daemon isn't running. Follow the steps below:

-
- npx gitnexus-mcp setup - + +
+

1) Install/configure your IDE:

+
+ npx gitnexus-mcp setup + +
+ +
+

2) Start the daemon (recommended):

+
+ npx gitnexus-mcp daemon + +
+
+ +
+

Dev mode (from `gitnexus-mcp` dir):

+
+ npm run build && node dist/cli.js daemon + +
+
+ @@ -282,7 +353,7 @@ export function MCPToggle({
npx gitnexus-mcp setup