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