The file C:\Users\MikeSwanson\AutoBuilder\My-Auto-Builder\frontend\src\pages\MemoryManager.tsx has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
   294→  const filteredProjectMemory = filterItems(projectMemory)
   295→  const filteredGlobalMemory = filterItems(globalMemory)
   296→  const filteredInfrastructure = filterItems(infrastructure)
   297→
   298→  const handleExportMemory = async () => {
   299→    setIsExporting(true)
   300→    try {
   301→      const url = currentProject
   302→        ? `${API_BASE}/export?project_id=${currentProject.id}`
   303→        : `${API_BASE}/export`
   304→      const response = await fetch(url)
   305→      if (!response.ok) {
   306→        throw new Error('Failed to export memory')
   307→      }
   308→      const data = await response.json()
   309→      const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' })
   310→      const downloadUrl = window.URL.createObjectURL(blob)
   311→      const a = document.createElement('a')
   312→      a.href = downloadUrl
   313→      a.download = `memory_export_${new Date().toISOString().split('T')[0]}.json`
   314→      document.body.appendChild(a)
   315→      a.click()
   316→      document.body.removeChild(a)
   317→      window.URL.revokeObjectURL(downloadUrl)
   318→      addToast('success', 'Export Complete', 'Memory items exported successfully.')
   319→    } catch (error) {
   320→      console.error('Failed to export memory:', error)
   321→      addToast('error', 'Export Failed', 'Failed to export memory items.')
   322→    } finally {
   323→      setIsExporting(false)
   324→    }
   325→  }
   326→
   327→  const handleOpenImportDialog = () => {
   328→    setImportFile(null)
   329→    setImportError(null)
   330→    setShowImportDialog(true)
   331→  }
   332→
   333→  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
   334→    const file = e.target.files?.[0]
   335→    setImportError(null)
   336→    if (file) {
   337→      if (!file.name.endsWith('.json')) {
   338→        setImportError('Please select a JSON file.')
   339→        setImportFile(null)
   340→        return
   341→      }
   342→      setImportFile(file)
   343→    }
   344→  }
   345→
   346→  const handleImportMemory = async () => {
   347→    if (!importFile) return
   348→
   349→    setIsImporting(true)
   350→    setImportError(null)
   351→
   352→    try {
   353→      // Read the file contents
   354→      const text = await importFile.text()
   355→
   356→      // Try to parse the JSON
   357→      let data: Record<string, unknown>
   358→      try {
   359→        data = JSON.parse(text)
   360→      } catch {
   361→        setImportError('Invalid JSON file: The file could not be parsed. Please check the file format.')
   362→        setIsImporting(false)
   363→        return
   364→      }
   365→
   366→      // Validate structure
   367→      if (typeof data !== 'object' || data === null) {
   368→        setImportError('Invalid file structure: Expected a JSON object.')
   369→        setIsImporting(false)
   370→        return
   371→      }
   372→
   373→      // Check for required arrays
   374→      const hasProjectMemory = Array.isArray(data.project_memory)
   375→      const hasGlobalMemory = Array.isArray(data.global_memory)
   376→      const hasInfrastructure = Array.isArray(data.infrastructure)
   377→
   378→      if (!hasProjectMemory && !hasGlobalMemory && !hasInfrastructure) {
   379→        setImportError("Invalid import file: No memory data found. Expected 'project_memory', 'global_memory', or 'infrastructure' arrays.")
   380→        setIsImporting(false)
   381→        return
   382→      }
   383→
   384→      // Send to backend
   385→      const url = currentProject
   386→        ? `${API_BASE}/import?project_id=${currentProject.id}`
   387→        : `${API_BASE}/import`
   388→
   389→      const response = await fetch(url, {
   390→        method: 'POST',
   391→        headers: { 'Content-Type': 'application/json' },
   392→        body: JSON.stringify(data),
   393→      })
   394→
   395→      if (!response.ok) {
   396→        const errorData = await response.json().catch(() => ({ detail: 'Unknown error' }))
   397→        setImportError(errorData.detail || 'Import failed. Please check the file format.')
   398→        setIsImporting(false)
   399→        return
   400→      }
   401→
   402→      const result = await response.json()
   403→
   404→      // Refresh the data
   405→      if (activeTab === 'project' && currentProject) {
   406→        const refreshResponse = await fetch(`${API_BASE}/project/${currentProject.id}`)
   407→        if (refreshResponse.ok) {
   408→          const refreshedData = await refreshResponse.json()
   409→          setProjectMemory(refreshedData)
   410→        }
   411→      } else if (activeTab === 'global') {
   412→        const refreshResponse = await fetch(`${API_BASE}/global`)
   413→        if (refreshResponse.ok) {
   414→          const refreshedData = await refreshResponse.json()
   415→          setGlobalMemory(refreshedData)
   416→        }
   417→      } else if (activeTab === 'infrastructure') {
   418→        const refreshResponse = await fetch(`${API_BASE}/infrastructure`)
   419→        if (refreshResponse.ok) {
   420→          const refreshedData = await refreshResponse.json()
   421→          setInfrastructure(refreshedData)
   422→        }
   423→      }
   424→
   425→      setShowImportDialog(false)
   426→      const totalImported = (result.imported_count?.project_memory || 0) +
   427→                           (result.imported_count?.global_memory || 0) +
   428→                           (result.imported_count?.infrastructure || 0)
   429→
   430→      if (result.errors && result.errors.length > 0) {
   431→        addToast('warning', 'Import Complete with Warnings', `Imported ${totalImported} items. ${result.errors.length} items had errors.`)
   432→      } else {
   433→        addToast('success', 'Import Complete', `Successfully imported ${totalImported} memory items.`)
   434→      }
   435→    } catch (error) {
   436→      console.error('Failed to import memory:', error)
   437→      setImportError('Failed to import memory items. Please try again.')
   438→    } finally {
   439→      setIsImporting(false)
   440→    }
   441→  }
   442→
   443→  return (
   444→    <div className="h-full flex flex-col">
   445→      {/* Header */}

const handleExportMemory = async () => {
    setIsExporting(true)
    try {
      const url = currentProject
        ? `${API_BASE}/export?project_id=${currentProject.id}`
        : `${API_BASE}/export`
      const response = await fetch(url)
      if (!response.ok) {
        throw new Error('Failed to export memory')
      }
      const data = await response.json()
      const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' })
      const downloadUrl = window.URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = downloadUrl
      a.download = `memory_export_${new Date().toISOString().split('T')[0]}.json`
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
      window.URL.revokeObjectURL(downloadUrl)
      addToast('success', 'Export Complete', 'Memory items exported successfully.')
    } catch (error) {
      console.error('Failed to export memory:', error)
      addToast('error', 'Export Failed', 'Failed to export memory items.')
    } finally {
      setIsExporting(false)
    }
  }

  const handleOpenImportDialog = () => {
    setImportFile(null)
    setImportError(null)
    setShowImportDialog(true)
  }

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    setImportError(null)
    if (file) {
      if (!file.name.endsWith('.json')) {
        setImportError('Please select a JSON file.')
        setImportFile(null)
        return
      }
      setImportFile(file)
    }
  }

  const handleImportMemory = async () => {
    if (!importFile) return

    setIsImporting(true)
    setImportError(null)

    try {
      // Read the file contents
      const text = await importFile.text()

      // Try to parse the JSON
      let data: Record<string, unknown>
      try {
        data = JSON.parse(text)
      } catch {
        setImportError('Invalid JSON file: The file could not be parsed. Please check the file format.')
        setIsImporting(false)
        return
      }

      // Validate structure
      if (typeof data !== 'object' || data === null) {
        setImportError('Invalid file structure: Expected a JSON object.')
        setIsImporting(false)
        return
      }

      // Check for required arrays
      const hasProjectMemory = Array.isArray(data.project_memory)
      const hasGlobalMemory = Array.isArray(data.global_memory)
      const hasInfrastructure = Array.isArray(data.infrastructure)

      if (!hasProjectMemory && !hasGlobalMemory && !hasInfrastructure) {
        setImportError("Invalid import file: No memory data found. Expected 'project_memory', 'global_memory', or 'infrastructure' arrays.")
        setIsImporting(false)
        return
      }

      // Send to backend
      const url = currentProject
        ? `${API_BASE}/import?project_id=${currentProject.id}`
        : `${API_BASE}/import`

      const response = await fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data),
      })

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({ detail: 'Unknown error' }))
        setImportError(errorData.detail || 'Import failed. Please check the file format.')
        setIsImporting(false)
        return
      }

      const result = await response.json()

      // Refresh the data
      if (activeTab === 'project' && currentProject) {
        const refreshResponse = await fetch(`${API_BASE}/project/${currentProject.id}`)
        if (refreshResponse.ok) {
          const refreshedData = await refreshResponse.json()
          setProjectMemory(refreshedData)
        }
      } else if (activeTab === 'global') {
        const refreshResponse = await fetch(`${API_BASE}/global`)
        if (refreshResponse.ok) {
          const refreshedData = await refreshResponse.json()
          setGlobalMemory(refreshedData)
        }
      } else if (activeTab === 'infrastructure') {
        const refreshResponse = await fetch(`${API_BASE}/infrastructure`)
        if (refreshResponse.ok) {
          const refreshedData = await refreshResponse.json()
          setInfrastructure(refreshedData)
        }
      }

      setShowImportDialog(false)
      const totalImported = (result.imported_count?.project_memory || 0) +
                           (result.imported_count?.global_memory || 0) +
                           (result.imported_count?.infrastructure || 0)

      if (result.errors && result.errors.length > 0) {
        addToast('warning', 'Import Complete with Warnings', `Imported ${totalImported} items. ${result.errors.length} items had errors.`)
      } else {
        addToast('success', 'Import Complete', `Successfully imported ${totalImported} memory items.`)
      }
    } catch (error) {
      console.error('Failed to import memory:', error)
      setImportError('Failed to import memory items. Please try again.')
    } finally {
      setIsImporting(false)
    }
  }

import { useState, useEffect } from 'react'
import { Brain, Globe, Server, Plus, Search, Trash2, X, Pencil, Download, Upload } from 'lucide-react'
import * as Dialog from '@radix-ui/react-dialog'
import * as AlertDialog from '@radix-ui/react-alert-dialog'
import { useProjectStore } from '../stores/projectStore'
import { useToastStore } from '../components/Toast'

type MemoryTab = 'project' | 'global' | 'infrastructure'

interface ProjectMemoryItem {
  id: number
  project_id: number
  type: string
  content: string
  metadata: Record<string, unknown> | null
  created_at: string
}

interface GlobalMemoryItem {
  id: number
  type: string
  content: string
  metadata: Record<string, unknown> | null
  usage_count: number
  created_at: string
}

interface InfrastructureItem {
  id: number
  name: string
  type: string
  config: Record<string, unknown>
  projects: number[] | null
  created_at: string
  updated_at: string
}

const API_BASE = 'http://localhost:8000/api/memory'

export default function MemoryManager() {
  const { currentProject } = useProjectStore()
  const { addToast } = useToastStore()
  const [activeTab, setActiveTab] = useState<MemoryTab>('project')
  const [searchQuery, setSearchQuery] = useState('')

  // Data states
  const [projectMemory, setProjectMemory] = useState<ProjectMemoryItem[]>([])
  const [globalMemory, setGlobalMemory] = useState<GlobalMemoryItem[]>([])
  const [infrastructure, setInfrastructure] = useState<InfrastructureItem[]>([])
  const [isLoading, setIsLoading] = useState(false)

  // Dialog states
  const [showAddDialog, setShowAddDialog] = useState(false)
  const [newItemType, setNewItemType] = useState('')
  const [newItemContent, setNewItemContent] = useState('')
  const [newItemName, setNewItemName] = useState('')
  const [isSaving, setIsSaving] = useState(false)

  // Delete dialog states
  const [showDeleteDialog, setShowDeleteDialog] = useState(false)
  const [itemToDelete, setItemToDelete] = useState<{ id: number; type: MemoryTab } | null>(null)
  const [isDeleting, setIsDeleting] = useState(false)

  // Edit dialog states
  const [showEditDialog, setShowEditDialog] = useState(false)
  const [editItem, setEditItem] = useState<{ id: number; type: string; content: string; memoryType: MemoryTab } | null>(null)
  const [editItemType, setEditItemType] = useState('')
  const [editItemContent, setEditItemContent] = useState('')
  const [isEditing, setIsEditing] = useState(false)
  const [isExporting, setIsExporting] = useState(false)
  const [isImporting, setIsImporting] = useState(false)
  const [showImportDialog, setShowImportDialog] = useState(false)
  const [importFile, setImportFile] = useState<File | null>(null)
  const [importError, setImportError] = useState<string | null>(null)

  const tabs = [
    { id: 'project' as const, label: 'Project Memory', icon: Brain },
    { id: 'global' as const, label: 'Global Memory', icon: Globe },
    { id: 'infrastructure' as const, label: 'Infrastructure', icon: Server },
  ]

  // Fetch data based on active tab
  useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true)
      try {
        if (activeTab === 'project' && currentProject) {
          const response = await fetch(`${API_BASE}/project/${currentProject.id}`)
          if (response.ok) {
            const data = await response.json()
            setProjectMemory(data)
          }
        } else if (activeTab === 'global') {
          const response = await fetch(`${API_BASE}/global`)
          if (response.ok) {
            const data = await response.json()
            setGlobalMemory(data)
          }
        } else if (activeTab === 'infrastructure') {
          const response = await fetch(`${API_BASE}/infrastructure`)
          if (response.ok) {
            const data = await response.json()
            setInfrastructure(data)
          }
        }
      } catch (error) {
        console.error('Failed to fetch memory items:', error)
      } finally {
        setIsLoading(false)
      }
    }
    fetchData()
  }, [activeTab, currentProject])

  const getTypeOptions = () => {
    switch (activeTab) {
      case 'project':
        return ['insight', 'pattern', 'gotcha', 'codebase_map']
      case 'global':
        return ['preference', 'pattern', 'solution']
      case 'infrastructure':
        return ['server', 'docker', 'database', 'deployment']
      default:
        return []
    }
  }

  const handleOpenAddDialog = () => {
    setNewItemType(getTypeOptions()[0] || '')
    setNewItemContent('')
    setNewItemName('')
    setShowAddDialog(true)
  }

  const handleAddItem = async () => {
    if (!newItemType || (!newItemContent.trim() && activeTab !== 'infrastructure')) return
    if (activeTab === 'infrastructure' && !newItemName.trim()) return

    setIsSaving(true)
    try {
      let response: Response

      if (activeTab === 'project' && currentProject) {
        response = await fetch(`${API_BASE}/project/${currentProject.id}`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ type: newItemType, content: newItemContent.trim() }),
        })
        if (response.ok) {
          const newItem = await response.json()
          setProjectMemory([...projectMemory, newItem])
        }
      } else if (activeTab === 'global') {
        response = await fetch(`${API_BASE}/global`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ type: newItemType, content: newItemContent.trim() }),
        })
        if (response.ok) {
          const newItem = await response.json()
          setGlobalMemory([...globalMemory, newItem])
        }
      } else if (activeTab === 'infrastructure') {
        response = await fetch(`${API_BASE}/infrastructure`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            name: newItemName.trim(),
            type: newItemType,
            config: { content: newItemContent.trim() }
          }),
        })
        if (response.ok) {
          const newItem = await response.json()
          setInfrastructure([...infrastructure, newItem])
        }
      }

      setShowAddDialog(false)
    } catch (error) {
      console.error('Failed to add memory item:', error)
    } finally {
      setIsSaving(false)
    }
  }

  const handleDeleteClick = (id: number, type: MemoryTab) => {
    setItemToDelete({ id, type })
    setShowDeleteDialog(true)
  }

  const handleDeleteConfirm = async () => {
    if (!itemToDelete) return

    setIsDeleting(true)
    try {
      let endpoint: string

      if (itemToDelete.type === 'project' && currentProject) {
        endpoint = `${API_BASE}/project/${currentProject.id}/${itemToDelete.id}`
      } else if (itemToDelete.type === 'global') {
        endpoint = `${API_BASE}/global/${itemToDelete.id}`
      } else {
        endpoint = `${API_BASE}/infrastructure/${itemToDelete.id}`
      }

      const response = await fetch(endpoint, { method: 'DELETE' })

      if (response.ok || response.status === 204) {
        if (itemToDelete.type === 'project') {
          setProjectMemory(projectMemory.filter(item => item.id !== itemToDelete.id))
        } else if (itemToDelete.type === 'global') {
          setGlobalMemory(globalMemory.filter(item => item.id !== itemToDelete.id))
        } else {
          setInfrastructure(infrastructure.filter(item => item.id !== itemToDelete.id))
        }
      }

      setShowDeleteDialog(false)
      setItemToDelete(null)
    } catch (error) {
      console.error('Failed to delete memory item:', error)
    } finally {
      setIsDeleting(false)
    }
  }

  const handleEditClick = (id: number, type: string, content: string, memoryType: MemoryTab) => {
    setEditItem({ id, type, content, memoryType })
    setEditItemType(type)
    setEditItemContent(content)
    setShowEditDialog(true)
  }

  const handleEditSave = async () => {
    if (!editItem || !editItemContent.trim()) return

    setIsEditing(true)
    try {
      let endpoint: string
      let body: Record<string, unknown>

      if (editItem.memoryType === 'project' && currentProject) {
        endpoint = `${API_BASE}/project/${currentProject.id}/${editItem.id}`
        body = { type: editItemType, content: editItemContent.trim() }
      } else if (editItem.memoryType === 'global') {
        endpoint = `${API_BASE}/global/${editItem.id}`
        body = { type: editItemType, content: editItemContent.trim() }
      } else {
        // Infrastructure uses different update endpoint
        setShowEditDialog(false)
        setEditItem(null)
        return
      }

      const response = await fetch(endpoint, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      })

      if (response.ok) {
        const updatedItem = await response.json()
        if (editItem.memoryType === 'project') {
          setProjectMemory(projectMemory.map(item =>
            item.id === editItem.id ? updatedItem : item
          ))
        } else if (editItem.memoryType === 'global') {
          setGlobalMemory(globalMemory.map(item =>
            item.id === editItem.id ? updatedItem : item
          ))
        }
      }

      setShowEditDialog(false)
      setEditItem(null)
    } catch (error) {
      console.error('Failed to update memory item:', error)
    } finally {
      setIsEditing(false)
    }
  }

  const filterItems = <T extends { content?: string; name?: string; type: string }>(items: T[]) => {
    if (!searchQuery) return items
    const query = searchQuery.toLowerCase()
    return items.filter(item =>
      item.content?.toLowerCase().includes(query) ||
      item.name?.toLowerCase().includes(query) ||
      item.type.toLowerCase().includes(query)
    )
  }

  const filteredProjectMemory = filterItems(projectMemory)
  const filteredGlobalMemory = filterItems(globalMemory)
  const filteredInfrastructure = filterItems(infrastructure)

  const handleExportMemory = async () => {
    setIsExporting(true)
    try {
      const url = currentProject
        ? `${API_BASE}/export?project_id=${currentProject.id}`
        : `${API_BASE}/export`
      const response = await fetch(url)
      if (!response.ok) {
        throw new Error('Failed to export memory')
      }
      const data = await response.json()
      const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' })
      const downloadUrl = window.URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = downloadUrl
      a.download = `memory_export_${new Date().toISOString().split('T')[0]}.json`
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
      window.URL.revokeObjectURL(downloadUrl)
      addToast('success', 'Export Complete', 'Memory items exported successfully.')
    } catch (error) {
      console.error('Failed to export memory:', error)
      addToast('error', 'Export Failed', 'Failed to export memory items.')
    } finally {
      setIsExporting(false)
    }
  }

  return (

      {/* Header */}

Memory Manager

          <button
            onClick={handleExportMemory}
            disabled={isExporting}
            className="flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors disabled:opacity-50"
            title="Export Memory Items"
          >
            <Download size={16} />
            {isExporting ? 'Exporting...' : 'Export'}
          </button>
          <button
            onClick={handleOpenAddDialog}
            className="btn-accent flex items-center gap-2"
          >
            <Plus size={18} />
            Add Memory Item
          </button>

      {/* Tabs */}

        {tabs.map((tab) => {
          const Icon = tab.icon
          return (
            <button
              key={tab.id}
              onClick={() => setActiveTab(tab.id)}
              className={`flex items-center gap-2 px-4 py-2 rounded-md transition-colors ${
                activeTab === tab.id
                  ? 'bg-primary text-primary-foreground'
                  : 'text-muted-foreground hover:text-foreground'
              }`}
            >
              <Icon size={16} />
              {tab.label}
            </button>
          )
        })}

      {/* Search */}

        <Search
          size={18}
          className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground"
        />
        <input
          type="text"
          value={searchQuery}
          onChange={(e) => setSearchQuery(e.target.value)}
          placeholder="Search memory items..."
          className="w-full pl-10 pr-4 py-2 bg-card border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-accent"
        />

      {/* Content */}

        {isLoading ? (

Loading...

        ) : (
          <>
            {activeTab === 'project' && (

                {filteredProjectMemory.length === 0 ? (
                  <EmptyState
                    title="No Project Memory"
                    description="Memory items from your current project will appear here."
                  />
                ) : (
                  filteredProjectMemory.map(item => (
                    <MemoryCard
                      key={item.id}
                      id={item.id}
                      type={item.type}
                      content={item.content}
                      createdAt={item.created_at}
                      onDelete={() => handleDeleteClick(item.id, 'project')}
                      onEdit={() => handleEditClick(item.id, item.type, item.content, 'project')}
                    />
                  ))
                )}

            )}

            {activeTab === 'global' && (

                {filteredGlobalMemory.length === 0 ? (
                  <EmptyState
                    title="No Global Memory"
                    description="Cross-project patterns and preferences will appear here."
                  />
                ) : (
                  filteredGlobalMemory.map(item => (
                    <MemoryCard
                      key={item.id}
                      id={item.id}
                      type={item.type}
                      content={item.content}
                      createdAt={item.created_at}
                      usageCount={item.usage_count}
                      onDelete={() => handleDeleteClick(item.id, 'global')}
                      onEdit={() => handleEditClick(item.id, item.type, item.content, 'global')}
                    />
                  ))
                )}

            )}

            {activeTab === 'infrastructure' && (

                {filteredInfrastructure.length === 0 ? (
                  <EmptyState
                    title="No Infrastructure Config"
                    description="Server and deployment configurations will appear here."
                  />
                ) : (
                  filteredInfrastructure.map(item => (
                    <InfrastructureCard
                      key={item.id}
                      id={item.id}
                      name={item.name}
                      type={item.type}
                      config={item.config}
                      createdAt={item.created_at}
                      onDelete={() => handleDeleteClick(item.id, 'infrastructure')}
                    />
                  ))
                )}

            )}
          </>
        )}

      {/* Add Memory Dialog */}
      <Dialog.Root open={showAddDialog} onOpenChange={setShowAddDialog}>
        <Dialog.Portal>
          <Dialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
          <Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-card border border-border rounded-lg p-4 md:p-6 w-[calc(100%-2rem)] max-w-md max-h-[calc(100vh-2rem)] overflow-y-auto z-50 shadow-xl">

              <Dialog.Title className="text-xl font-semibold text-foreground">
                Add {activeTab === 'project' ? 'Project' : activeTab === 'global' ? 'Global' : 'Infrastructure'} Memory
              </Dialog.Title>
              <Dialog.Close asChild>
                <button className="p-1 text-muted-foreground hover:text-foreground hover:bg-secondary rounded transition-colors" aria-label="Close">
                  <X size={20} />
                </button>
              </Dialog.Close>

              {activeTab === 'infrastructure' && (

                  Name *
                  <input
                    type="text"
                    value={newItemName}
                    onChange={(e) => setNewItemName(e.target.value)}
                    className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-accent"
                    placeholder="Enter config name"
                  />

              )}

                Type *
                <select
                  value={newItemType}
                  onChange={(e) => setNewItemType(e.target.value)}
                  className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground focus:outline-none focus:ring-2 focus:ring-accent"
                >
                  {getTypeOptions().map(type => (
                    <option key={type} value={type}>{type}</option>
                  ))}
                </select>

                Content *
                <textarea
                  value={newItemContent}
                  onChange={(e) => setNewItemContent(e.target.value)}
                  rows={4}
                  className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-accent resize-none"
                  placeholder="Enter memory content..."
                />

              <Dialog.Close asChild>
                <button className="px-4 py-2 text-sm text-secondary-foreground hover:bg-secondary rounded-lg transition-colors">
                  Cancel
                </button>
              </Dialog.Close>
              <button
                onClick={handleAddItem}
                disabled={isSaving || !newItemContent.trim() || (activeTab === 'infrastructure' && !newItemName.trim())}
                className="px-4 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
              >
                {isSaving ? 'Saving...' : 'Add Item'}
              </button>

          </Dialog.Content>
        </Dialog.Portal>
      </Dialog.Root>

      {/* Delete Confirmation Dialog */}
      <AlertDialog.Root open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
        <AlertDialog.Portal>
          <AlertDialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
          <AlertDialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-card border border-border rounded-lg p-4 md:p-6 w-[calc(100%-2rem)] max-w-md max-h-[calc(100vh-2rem)] overflow-y-auto z-50 shadow-xl">
            <AlertDialog.Title className="text-xl font-semibold text-foreground">
              Delete Memory Item
            </AlertDialog.Title>
            <AlertDialog.Description className="mt-3 text-muted-foreground">
              Are you sure you want to delete this memory item? This action cannot be undone.
            </AlertDialog.Description>

              <AlertDialog.Cancel asChild>
                <button className="px-4 py-2 text-sm text-secondary-foreground hover:bg-secondary rounded-lg transition-colors">
                  Cancel
                </button>
              </AlertDialog.Cancel>
              <AlertDialog.Action asChild>
                <button
                  onClick={handleDeleteConfirm}
                  disabled={isDeleting}
                  className="px-4 py-2 text-sm bg-destructive hover:bg-destructive/80 text-white rounded-lg transition-colors disabled:opacity-50"
                >
                  {isDeleting ? 'Deleting...' : 'Delete'}
                </button>
              </AlertDialog.Action>

          </AlertDialog.Content>
        </AlertDialog.Portal>
      </AlertDialog.Root>

      {/* Edit Memory Dialog */}
      <Dialog.Root open={showEditDialog} onOpenChange={setShowEditDialog}>
        <Dialog.Portal>
          <Dialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
          <Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-card border border-border rounded-lg p-4 md:p-6 w-[calc(100%-2rem)] max-w-md max-h-[calc(100vh-2rem)] overflow-y-auto z-50 shadow-xl">

              <Dialog.Title className="text-xl font-semibold text-foreground">
                Edit Memory Item
              </Dialog.Title>
              <Dialog.Close asChild>
                <button className="p-1 text-muted-foreground hover:text-foreground hover:bg-secondary rounded transition-colors" aria-label="Close">
                  <X size={20} />
                </button>
              </Dialog.Close>

                Type *
                <select
                  value={editItemType}
                  onChange={(e) => setEditItemType(e.target.value)}
                  className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground focus:outline-none focus:ring-2 focus:ring-accent"
                >
                  {(editItem?.memoryType === 'project'
                    ? ['insight', 'pattern', 'gotcha', 'codebase_map']
                    : ['preference', 'pattern', 'solution']
                  ).map(type => (
                    <option key={type} value={type}>{type}</option>
                  ))}
                </select>

                Content *
                <textarea
                  value={editItemContent}
                  onChange={(e) => setEditItemContent(e.target.value)}
                  rows={4}
                  className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-accent resize-none"
                  placeholder="Enter memory content..."
                />

              <Dialog.Close asChild>
                <button className="px-4 py-2 text-sm text-secondary-foreground hover:bg-secondary rounded-lg transition-colors">
                  Cancel
                </button>
              </Dialog.Close>
              <button
                onClick={handleEditSave}
                disabled={isEditing || !editItemContent.trim()}
                className="px-4 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
              >
                {isEditing ? 'Saving...' : 'Save Changes'}
              </button>

          </Dialog.Content>
        </Dialog.Portal>
      </Dialog.Root>

  )
}

function MemoryCard({
  id: _id,
  type,
  content,
  createdAt,
  usageCount,
  onDelete,
  onEdit,
}: {
  id: number
  type: string
  content: string
  createdAt: string
  usageCount?: number
  onDelete: () => void
  onEdit?: () => void
}) {
  return (

              {type}

            {usageCount !== undefined && (
              Used {usageCount} times
            )}

{content}

            Created: {new Date(createdAt).toLocaleString()}

          {onEdit && (
            <button
              onClick={onEdit}
              className="p-2 text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors"
              title="Edit"
              aria-label="Edit memory item"
            >
              <Pencil size={16} />
            </button>
          )}
          <button
            onClick={onDelete}
            className="p-2 text-muted-foreground hover:text-destructive hover:bg-destructive/10 rounded-lg transition-colors"
            title="Delete"
            aria-label="Delete memory item"
          >
            <Trash2 size={16} />
          </button>

  )
}

function InfrastructureCard({
  id: _id,
  name,
  type,
  config,
  createdAt,
  onDelete,
}: {
  id: number
  name: string
  type: string
  config: Record<string, unknown>
  createdAt: string
  onDelete: () => void
}) {
  return (

{name}

              {type}

            {JSON.stringify(config, null, 2)}

            Created: {new Date(createdAt).toLocaleString()}

        <button
          onClick={onDelete}
          className="p-2 text-muted-foreground hover:text-destructive hover:bg-destructive/10 rounded-lg transition-colors"
          title="Delete"
        >
          <Trash2 size={16} />
        </button>

  )
}

function EmptyState({
  title,
  description,
}: {
  title: string
  description: string
}) {
  return (

      <Brain size={48} className="text-muted-foreground mx-auto mb-4" />

{title}

{description}

  )
}

+  const handleOpenImportDialog = () => {

+  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {

+      if (!file.name.endsWith('.json')) {

+        setImportError('Please select a JSON file.')

+  const handleImportMemory = async () => {

+      const text = await importFile.text()

+      let data: Record<string, unknown>

+        setImportError('Invalid JSON file: The file could not be parsed. Please check the file format.')

+      if (typeof data !== 'object' || data === null) {

+        setImportError('Invalid file structure: Expected a JSON object.')

+      const hasProjectMemory = Array.isArray(data.project_memory)

+      const hasGlobalMemory = Array.isArray(data.global_memory)

+      const hasInfrastructure = Array.isArray(data.infrastructure)

+      if (!hasProjectMemory && !hasGlobalMemory && !hasInfrastructure) {

+        setImportError("Invalid import file: No memory data found. Expected 'project_memory', 'global_memory', or 'infrastructure' arrays.")

+        ? `${API_BASE}/import?project_id=${currentProject.id}`

+      const response = await fetch(url, {

+        headers: { 'Content-Type': 'application/json' },

+        const errorData = await response.json().catch(() => ({ detail: 'Unknown error' }))

+        setImportError(errorData.detail || 'Import failed. Please check the file format.')

+      const result = await response.json()

+      if (activeTab === 'project' && currentProject) {

+        const refreshResponse = await fetch(`${API_BASE}/project/${currentProject.id}`)

+          const refreshedData = await refreshResponse.json()

+          setProjectMemory(refreshedData)

+      } else if (activeTab === 'global') {

+        const refreshResponse = await fetch(`${API_BASE}/global`)

+          setGlobalMemory(refreshedData)

+      } else if (activeTab === 'infrastructure') {

+        const refreshResponse = await fetch(`${API_BASE}/infrastructure`)

+          setInfrastructure(refreshedData)

+      const totalImported = (result.imported_count?.project_memory || 0) +

+      if (result.errors && result.errors.length > 0) {

+        addToast('warning', 'Import Complete with Warnings', `Imported ${totalImported} items. ${result.errors.length} items had errors.`)

+        addToast('success', 'Import Complete', `Successfully imported ${totalImported} memory items.`)

+      console.error('Failed to import memory:', error)

+      setImportError('Failed to import memory items. Please try again.')


Now let me add the Import button to the header and add the import dialog:


Edit

          <button
            onClick={handleExportMemory}
            disabled={isExporting}
            className="flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors disabled:opacity-50"
            title="Export Memory Items"
          >
            <Download size={16} />
            {isExporting ? 'Exporting...' : 'Export'}
          </button>
          <button
            onClick={handleOpenAddDialog}
            className="btn-accent flex items-center gap-2"
          >
            <Plus size={18} />
            Add Memory Item
          </button>

          <button
            onClick={handleOpenImportDialog}
            disabled={isImporting}
            className="flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors disabled:opacity-50"
            title="Import Memory Items"
          >
            <Upload size={16} />
            {isImporting ? 'Importing...' : 'Import'}
          </button>
          <button
            onClick={handleExportMemory}
            disabled={isExporting}
            className="flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors disabled:opacity-50"
            title="Export Memory Items"
          >
            <Download size={16} />
            {isExporting ? 'Exporting...' : 'Export'}
          </button>
          <button
            onClick={handleOpenAddDialog}
            className="btn-accent flex items-center gap-2"
          >
            <Plus size={18} />
            Add Memory Item
          </button>


The file C:\Users\MikeSwanson\AutoBuilder\My-Auto-Builder\frontend\src\pages\MemoryManager.tsx has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
   444→

   445→      {/* Header */}
   446→

   447→
Memory Manager

   448→

   449→          <button
   450→            onClick={handleOpenImportDialog}
   451→            disabled={isImporting}
   452→            className="flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors disabled:opacity-50"
   453→            title="Import Memory Items"
   454→          >
   455→            <Upload size={16} />
   456→            {isImporting ? 'Importing...' : 'Import'}
   457→          </button>
   458→          <button
   459→            onClick={handleExportMemory}
   460→            disabled={isExporting}
   461→            className="flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors disabled:opacity-50"
   462→            title="Export Memory Items"
   463→          >
   464→            <Download size={16} />
   465→            {isExporting ? 'Exporting...' : 'Export'}
   466→          </button>
   467→          <button
   468→            onClick={handleOpenAddDialog}
   469→            className="btn-accent flex items-center gap-2"
   470→          >
   471→            <Plus size={18} />
   472→            Add Memory Item
   473→          </button>
   474→

   475→

   476→
   477→      {/* Tabs */}
   478→

          <button
            onClick={handleOpenImportDialog}
            disabled={isImporting}
            className="flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors disabled:opacity-50"
            title="Import Memory Items"
          >
            <Upload size={16} />
            {isImporting ? 'Importing...' : 'Import'}
          </button>
          <button
            onClick={handleExportMemory}
            disabled={isExporting}
            className="flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors disabled:opacity-50"
            title="Export Memory Items"
          >
            <Download size={16} />
            {isExporting ? 'Exporting...' : 'Export'}
          </button>
          <button
            onClick={handleOpenAddDialog}
            className="btn-accent flex items-center gap-2"
          >
            <Plus size={18} />
            Add Memory Item
          </button>

import { useState, useEffect } from 'react'
import { Brain, Globe, Server, Plus, Search, Trash2, X, Pencil, Download, Upload } from 'lucide-react'
import * as Dialog from '@radix-ui/react-dialog'
import * as AlertDialog from '@radix-ui/react-alert-dialog'
import { useProjectStore } from '../stores/projectStore'
import { useToastStore } from '../components/Toast'

type MemoryTab = 'project' | 'global' | 'infrastructure'

interface ProjectMemoryItem {
  id: number
  project_id: number
  type: string
  content: string
  metadata: Record<string, unknown> | null
  created_at: string
}

interface GlobalMemoryItem {
  id: number
  type: string
  content: string
  metadata: Record<string, unknown> | null
  usage_count: number
  created_at: string
}

interface InfrastructureItem {
  id: number
  name: string
  type: string
  config: Record<string, unknown>
  projects: number[] | null
  created_at: string
  updated_at: string
}

const API_BASE = 'http://localhost:8000/api/memory'

export default function MemoryManager() {
  const { currentProject } = useProjectStore()
  const { addToast } = useToastStore()
  const [activeTab, setActiveTab] = useState<MemoryTab>('project')
  const [searchQuery, setSearchQuery] = useState('')

  // Data states
  const [projectMemory, setProjectMemory] = useState<ProjectMemoryItem[]>([])
  const [globalMemory, setGlobalMemory] = useState<GlobalMemoryItem[]>([])
  const [infrastructure, setInfrastructure] = useState<InfrastructureItem[]>([])
  const [isLoading, setIsLoading] = useState(false)

  // Dialog states
  const [showAddDialog, setShowAddDialog] = useState(false)
  const [newItemType, setNewItemType] = useState('')
  const [newItemContent, setNewItemContent] = useState('')
  const [newItemName, setNewItemName] = useState('')
  const [isSaving, setIsSaving] = useState(false)

  // Delete dialog states
  const [showDeleteDialog, setShowDeleteDialog] = useState(false)
  const [itemToDelete, setItemToDelete] = useState<{ id: number; type: MemoryTab } | null>(null)
  const [isDeleting, setIsDeleting] = useState(false)

  // Edit dialog states
  const [showEditDialog, setShowEditDialog] = useState(false)
  const [editItem, setEditItem] = useState<{ id: number; type: string; content: string; memoryType: MemoryTab } | null>(null)
  const [editItemType, setEditItemType] = useState('')
  const [editItemContent, setEditItemContent] = useState('')
  const [isEditing, setIsEditing] = useState(false)
  const [isExporting, setIsExporting] = useState(false)
  const [isImporting, setIsImporting] = useState(false)
  const [showImportDialog, setShowImportDialog] = useState(false)
  const [importFile, setImportFile] = useState<File | null>(null)
  const [importError, setImportError] = useState<string | null>(null)

  const tabs = [
    { id: 'project' as const, label: 'Project Memory', icon: Brain },
    { id: 'global' as const, label: 'Global Memory', icon: Globe },
    { id: 'infrastructure' as const, label: 'Infrastructure', icon: Server },
  ]

  // Fetch data based on active tab
  useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true)
      try {
        if (activeTab === 'project' && currentProject) {
          const response = await fetch(`${API_BASE}/project/${currentProject.id}`)
          if (response.ok) {
            const data = await response.json()
            setProjectMemory(data)
          }
        } else if (activeTab === 'global') {
          const response = await fetch(`${API_BASE}/global`)
          if (response.ok) {
            const data = await response.json()
            setGlobalMemory(data)
          }
        } else if (activeTab === 'infrastructure') {
          const response = await fetch(`${API_BASE}/infrastructure`)
          if (response.ok) {
            const data = await response.json()
            setInfrastructure(data)
          }
        }
      } catch (error) {
        console.error('Failed to fetch memory items:', error)
      } finally {
        setIsLoading(false)
      }
    }
    fetchData()
  }, [activeTab, currentProject])

  const getTypeOptions = () => {
    switch (activeTab) {
      case 'project':
        return ['insight', 'pattern', 'gotcha', 'codebase_map']
      case 'global':
        return ['preference', 'pattern', 'solution']
      case 'infrastructure':
        return ['server', 'docker', 'database', 'deployment']
      default:
        return []
    }
  }

  const handleOpenAddDialog = () => {
    setNewItemType(getTypeOptions()[0] || '')
    setNewItemContent('')
    setNewItemName('')
    setShowAddDialog(true)
  }

  const handleAddItem = async () => {
    if (!newItemType || (!newItemContent.trim() && activeTab !== 'infrastructure')) return
    if (activeTab === 'infrastructure' && !newItemName.trim()) return

    setIsSaving(true)
    try {
      let response: Response

      if (activeTab === 'project' && currentProject) {
        response = await fetch(`${API_BASE}/project/${currentProject.id}`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ type: newItemType, content: newItemContent.trim() }),
        })
        if (response.ok) {
          const newItem = await response.json()
          setProjectMemory([...projectMemory, newItem])
        }
      } else if (activeTab === 'global') {
        response = await fetch(`${API_BASE}/global`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ type: newItemType, content: newItemContent.trim() }),
        })
        if (response.ok) {
          const newItem = await response.json()
          setGlobalMemory([...globalMemory, newItem])
        }
      } else if (activeTab === 'infrastructure') {
        response = await fetch(`${API_BASE}/infrastructure`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            name: newItemName.trim(),
            type: newItemType,
            config: { content: newItemContent.trim() }
          }),
        })
        if (response.ok) {
          const newItem = await response.json()
          setInfrastructure([...infrastructure, newItem])
        }
      }

      setShowAddDialog(false)
    } catch (error) {
      console.error('Failed to add memory item:', error)
    } finally {
      setIsSaving(false)
    }
  }

  const handleDeleteClick = (id: number, type: MemoryTab) => {
    setItemToDelete({ id, type })
    setShowDeleteDialog(true)
  }

  const handleDeleteConfirm = async () => {
    if (!itemToDelete) return

    setIsDeleting(true)
    try {
      let endpoint: string

      if (itemToDelete.type === 'project' && currentProject) {
        endpoint = `${API_BASE}/project/${currentProject.id}/${itemToDelete.id}`
      } else if (itemToDelete.type === 'global') {
        endpoint = `${API_BASE}/global/${itemToDelete.id}`
      } else {
        endpoint = `${API_BASE}/infrastructure/${itemToDelete.id}`
      }

      const response = await fetch(endpoint, { method: 'DELETE' })

      if (response.ok || response.status === 204) {
        if (itemToDelete.type === 'project') {
          setProjectMemory(projectMemory.filter(item => item.id !== itemToDelete.id))
        } else if (itemToDelete.type === 'global') {
          setGlobalMemory(globalMemory.filter(item => item.id !== itemToDelete.id))
        } else {
          setInfrastructure(infrastructure.filter(item => item.id !== itemToDelete.id))
        }
      }

      setShowDeleteDialog(false)
      setItemToDelete(null)
    } catch (error) {
      console.error('Failed to delete memory item:', error)
    } finally {
      setIsDeleting(false)
    }
  }

  const handleEditClick = (id: number, type: string, content: string, memoryType: MemoryTab) => {
    setEditItem({ id, type, content, memoryType })
    setEditItemType(type)
    setEditItemContent(content)
    setShowEditDialog(true)
  }

  const handleEditSave = async () => {
    if (!editItem || !editItemContent.trim()) return

    setIsEditing(true)
    try {
      let endpoint: string
      let body: Record<string, unknown>

      if (editItem.memoryType === 'project' && currentProject) {
        endpoint = `${API_BASE}/project/${currentProject.id}/${editItem.id}`
        body = { type: editItemType, content: editItemContent.trim() }
      } else if (editItem.memoryType === 'global') {
        endpoint = `${API_BASE}/global/${editItem.id}`
        body = { type: editItemType, content: editItemContent.trim() }
      } else {
        // Infrastructure uses different update endpoint
        setShowEditDialog(false)
        setEditItem(null)
        return
      }

      const response = await fetch(endpoint, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      })

      if (response.ok) {
        const updatedItem = await response.json()
        if (editItem.memoryType === 'project') {
          setProjectMemory(projectMemory.map(item =>
            item.id === editItem.id ? updatedItem : item
          ))
        } else if (editItem.memoryType === 'global') {
          setGlobalMemory(globalMemory.map(item =>
            item.id === editItem.id ? updatedItem : item
          ))
        }
      }

      setShowEditDialog(false)
      setEditItem(null)
    } catch (error) {
      console.error('Failed to update memory item:', error)
    } finally {
      setIsEditing(false)
    }
  }

  const filterItems = <T extends { content?: string; name?: string; type: string }>(items: T[]) => {
    if (!searchQuery) return items
    const query = searchQuery.toLowerCase()
    return items.filter(item =>
      item.content?.toLowerCase().includes(query) ||
      item.name?.toLowerCase().includes(query) ||
      item.type.toLowerCase().includes(query)
    )
  }

  const filteredProjectMemory = filterItems(projectMemory)
  const filteredGlobalMemory = filterItems(globalMemory)
  const filteredInfrastructure = filterItems(infrastructure)

  const handleExportMemory = async () => {
    setIsExporting(true)
    try {
      const url = currentProject
        ? `${API_BASE}/export?project_id=${currentProject.id}`
        : `${API_BASE}/export`
      const response = await fetch(url)
      if (!response.ok) {
        throw new Error('Failed to export memory')
      }
      const data = await response.json()
      const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' })
      const downloadUrl = window.URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = downloadUrl
      a.download = `memory_export_${new Date().toISOString().split('T')[0]}.json`
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
      window.URL.revokeObjectURL(downloadUrl)
      addToast('success', 'Export Complete', 'Memory items exported successfully.')
    } catch (error) {
      console.error('Failed to export memory:', error)
      addToast('error', 'Export Failed', 'Failed to export memory items.')
    } finally {
      setIsExporting(false)
    }
  }

  const handleOpenImportDialog = () => {
    setImportFile(null)
    setImportError(null)
    setShowImportDialog(true)
  }

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    setImportError(null)
    if (file) {
      if (!file.name.endsWith('.json')) {
        setImportError('Please select a JSON file.')
        setImportFile(null)
        return
      }
      setImportFile(file)
    }
  }

  const handleImportMemory = async () => {
    if (!importFile) return

    setIsImporting(true)
    setImportError(null)

    try {
      // Read the file contents
      const text = await importFile.text()

      // Try to parse the JSON
      let data: Record<string, unknown>
      try {
        data = JSON.parse(text)
      } catch {
        setImportError('Invalid JSON file: The file could not be parsed. Please check the file format.')
        setIsImporting(false)
        return
      }

      // Validate structure
      if (typeof data !== 'object' || data === null) {
        setImportError('Invalid file structure: Expected a JSON object.')
        setIsImporting(false)
        return
      }

      // Check for required arrays
      const hasProjectMemory = Array.isArray(data.project_memory)
      const hasGlobalMemory = Array.isArray(data.global_memory)
      const hasInfrastructure = Array.isArray(data.infrastructure)

      if (!hasProjectMemory && !hasGlobalMemory && !hasInfrastructure) {
        setImportError("Invalid import file: No memory data found. Expected 'project_memory', 'global_memory', or 'infrastructure' arrays.")
        setIsImporting(false)
        return
      }

      // Send to backend
      const url = currentProject
        ? `${API_BASE}/import?project_id=${currentProject.id}`
        : `${API_BASE}/import`

      const response = await fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data),
      })

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({ detail: 'Unknown error' }))
        setImportError(errorData.detail || 'Import failed. Please check the file format.')
        setIsImporting(false)
        return
      }

      const result = await response.json()

      // Refresh the data
      if (activeTab === 'project' && currentProject) {
        const refreshResponse = await fetch(`${API_BASE}/project/${currentProject.id}`)
        if (refreshResponse.ok) {
          const refreshedData = await refreshResponse.json()
          setProjectMemory(refreshedData)
        }
      } else if (activeTab === 'global') {
        const refreshResponse = await fetch(`${API_BASE}/global`)
        if (refreshResponse.ok) {
          const refreshedData = await refreshResponse.json()
          setGlobalMemory(refreshedData)
        }
      } else if (activeTab === 'infrastructure') {
        const refreshResponse = await fetch(`${API_BASE}/infrastructure`)
        if (refreshResponse.ok) {
          const refreshedData = await refreshResponse.json()
          setInfrastructure(refreshedData)
        }
      }

      setShowImportDialog(false)
      const totalImported = (result.imported_count?.project_memory || 0) +
                           (result.imported_count?.global_memory || 0) +
                           (result.imported_count?.infrastructure || 0)

      if (result.errors && result.errors.length > 0) {
        addToast('warning', 'Import Complete with Warnings', `Imported ${totalImported} items. ${result.errors.length} items had errors.`)
      } else {
        addToast('success', 'Import Complete', `Successfully imported ${totalImported} memory items.`)
      }
    } catch (error) {
      console.error('Failed to import memory:', error)
      setImportError('Failed to import memory items. Please try again.')
    } finally {
      setIsImporting(false)
    }
  }

  return (

      {/* Header */}

Memory Manager

          <button
            onClick={handleExportMemory}
            disabled={isExporting}
            className="flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors disabled:opacity-50"
            title="Export Memory Items"
          >
            <Download size={16} />
            {isExporting ? 'Exporting...' : 'Export'}
          </button>
          <button
            onClick={handleOpenAddDialog}
            className="btn-accent flex items-center gap-2"
          >
            <Plus size={18} />
            Add Memory Item
          </button>

      {/* Tabs */}

        {tabs.map((tab) => {
          const Icon = tab.icon
          return (
            <button
              key={tab.id}
              onClick={() => setActiveTab(tab.id)}
              className={`flex items-center gap-2 px-4 py-2 rounded-md transition-colors ${
                activeTab === tab.id
                  ? 'bg-primary text-primary-foreground'
                  : 'text-muted-foreground hover:text-foreground'
              }`}
            >
              <Icon size={16} />
              {tab.label}
            </button>
          )
        })}

      {/* Search */}

        <Search
          size={18}
          className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground"
        />
        <input
          type="text"
          value={searchQuery}
          onChange={(e) => setSearchQuery(e.target.value)}
          placeholder="Search memory items..."
          className="w-full pl-10 pr-4 py-2 bg-card border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-accent"
        />

      {/* Content */}

        {isLoading ? (

Loading...

        ) : (
          <>
            {activeTab === 'project' && (

                {filteredProjectMemory.length === 0 ? (
                  <EmptyState
                    title="No Project Memory"
                    description="Memory items from your current project will appear here."
                  />
                ) : (
                  filteredProjectMemory.map(item => (
                    <MemoryCard
                      key={item.id}
                      id={item.id}
                      type={item.type}
                      content={item.content}
                      createdAt={item.created_at}
                      onDelete={() => handleDeleteClick(item.id, 'project')}
                      onEdit={() => handleEditClick(item.id, item.type, item.content, 'project')}
                    />
                  ))
                )}

            )}

            {activeTab === 'global' && (

                {filteredGlobalMemory.length === 0 ? (
                  <EmptyState
                    title="No Global Memory"
                    description="Cross-project patterns and preferences will appear here."
                  />
                ) : (
                  filteredGlobalMemory.map(item => (
                    <MemoryCard
                      key={item.id}
                      id={item.id}
                      type={item.type}
                      content={item.content}
                      createdAt={item.created_at}
                      usageCount={item.usage_count}
                      onDelete={() => handleDeleteClick(item.id, 'global')}
                      onEdit={() => handleEditClick(item.id, item.type, item.content, 'global')}
                    />
                  ))
                )}

            )}

            {activeTab === 'infrastructure' && (

                {filteredInfrastructure.length === 0 ? (
                  <EmptyState
                    title="No Infrastructure Config"
                    description="Server and deployment configurations will appear here."
                  />
                ) : (
                  filteredInfrastructure.map(item => (
                    <InfrastructureCard
                      key={item.id}
                      id={item.id}
                      name={item.name}
                      type={item.type}
                      config={item.config}
                      createdAt={item.created_at}
                      onDelete={() => handleDeleteClick(item.id, 'infrastructure')}
                    />
                  ))
                )}

            )}
          </>
        )}

      {/* Add Memory Dialog */}
      <Dialog.Root open={showAddDialog} onOpenChange={setShowAddDialog}>
        <Dialog.Portal>
          <Dialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
          <Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-card border border-border rounded-lg p-4 md:p-6 w-[calc(100%-2rem)] max-w-md max-h-[calc(100vh-2rem)] overflow-y-auto z-50 shadow-xl">

              <Dialog.Title className="text-xl font-semibold text-foreground">
                Add {activeTab === 'project' ? 'Project' : activeTab === 'global' ? 'Global' : 'Infrastructure'} Memory
              </Dialog.Title>
              <Dialog.Close asChild>
                <button className="p-1 text-muted-foreground hover:text-foreground hover:bg-secondary rounded transition-colors" aria-label="Close">
                  <X size={20} />
                </button>
              </Dialog.Close>

              {activeTab === 'infrastructure' && (

                  Name *
                  <input
                    type="text"
                    value={newItemName}
                    onChange={(e) => setNewItemName(e.target.value)}
                    className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-accent"
                    placeholder="Enter config name"
                  />

              )}

                Type *
                <select
                  value={newItemType}
                  onChange={(e) => setNewItemType(e.target.value)}
                  className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground focus:outline-none focus:ring-2 focus:ring-accent"
                >
                  {getTypeOptions().map(type => (
                    <option key={type} value={type}>{type}</option>
                  ))}
                </select>

                Content *
                <textarea
                  value={newItemContent}
                  onChange={(e) => setNewItemContent(e.target.value)}
                  rows={4}
                  className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-accent resize-none"
                  placeholder="Enter memory content..."
                />

              <Dialog.Close asChild>
                <button className="px-4 py-2 text-sm text-secondary-foreground hover:bg-secondary rounded-lg transition-colors">
                  Cancel
                </button>
              </Dialog.Close>
              <button
                onClick={handleAddItem}
                disabled={isSaving || !newItemContent.trim() || (activeTab === 'infrastructure' && !newItemName.trim())}
                className="px-4 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
              >
                {isSaving ? 'Saving...' : 'Add Item'}
              </button>

          </Dialog.Content>
        </Dialog.Portal>
      </Dialog.Root>

      {/* Delete Confirmation Dialog */}
      <AlertDialog.Root open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
        <AlertDialog.Portal>
          <AlertDialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
          <AlertDialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-card border border-border rounded-lg p-4 md:p-6 w-[calc(100%-2rem)] max-w-md max-h-[calc(100vh-2rem)] overflow-y-auto z-50 shadow-xl">
            <AlertDialog.Title className="text-xl font-semibold text-foreground">
              Delete Memory Item
            </AlertDialog.Title>
            <AlertDialog.Description className="mt-3 text-muted-foreground">
              Are you sure you want to delete this memory item? This action cannot be undone.
            </AlertDialog.Description>

              <AlertDialog.Cancel asChild>
                <button className="px-4 py-2 text-sm text-secondary-foreground hover:bg-secondary rounded-lg transition-colors">
                  Cancel
                </button>
              </AlertDialog.Cancel>
              <AlertDialog.Action asChild>
                <button
                  onClick={handleDeleteConfirm}
                  disabled={isDeleting}
                  className="px-4 py-2 text-sm bg-destructive hover:bg-destructive/80 text-white rounded-lg transition-colors disabled:opacity-50"
                >
                  {isDeleting ? 'Deleting...' : 'Delete'}
                </button>
              </AlertDialog.Action>

          </AlertDialog.Content>
        </AlertDialog.Portal>
      </AlertDialog.Root>

      {/* Edit Memory Dialog */}
      <Dialog.Root open={showEditDialog} onOpenChange={setShowEditDialog}>
        <Dialog.Portal>
          <Dialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
          <Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-card border border-border rounded-lg p-4 md:p-6 w-[calc(100%-2rem)] max-w-md max-h-[calc(100vh-2rem)] overflow-y-auto z-50 shadow-xl">

              <Dialog.Title className="text-xl font-semibold text-foreground">
                Edit Memory Item
              </Dialog.Title>
              <Dialog.Close asChild>
                <button className="p-1 text-muted-foreground hover:text-foreground hover:bg-secondary rounded transition-colors" aria-label="Close">
                  <X size={20} />
                </button>
              </Dialog.Close>

                Type *
                <select
                  value={editItemType}
                  onChange={(e) => setEditItemType(e.target.value)}
                  className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground focus:outline-none focus:ring-2 focus:ring-accent"
                >
                  {(editItem?.memoryType === 'project'
                    ? ['insight', 'pattern', 'gotcha', 'codebase_map']
                    : ['preference', 'pattern', 'solution']
                  ).map(type => (
                    <option key={type} value={type}>{type}</option>
                  ))}
                </select>

                Content *
                <textarea
                  value={editItemContent}
                  onChange={(e) => setEditItemContent(e.target.value)}
                  rows={4}
                  className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-accent resize-none"
                  placeholder="Enter memory content..."
                />

              <Dialog.Close asChild>
                <button className="px-4 py-2 text-sm text-secondary-foreground hover:bg-secondary rounded-lg transition-colors">
                  Cancel
                </button>
              </Dialog.Close>
              <button
                onClick={handleEditSave}
                disabled={isEditing || !editItemContent.trim()}
                className="px-4 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
              >
                {isEditing ? 'Saving...' : 'Save Changes'}
              </button>

          </Dialog.Content>
        </Dialog.Portal>
      </Dialog.Root>

  )
}

function MemoryCard({
  id: _id,
  type,
  content,
  createdAt,
  usageCount,
  onDelete,
  onEdit,
}: {
  id: number
  type: string
  content: string
  createdAt: string
  usageCount?: number
  onDelete: () => void
  onEdit?: () => void
}) {
  return (

              {type}

            {usageCount !== undefined && (
              Used {usageCount} times
            )}

{content}

            Created: {new Date(createdAt).toLocaleString()}

          {onEdit && (
            <button
              onClick={onEdit}
              className="p-2 text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors"
              title="Edit"
              aria-label="Edit memory item"
            >
              <Pencil size={16} />
            </button>
          )}
          <button
            onClick={onDelete}
            className="p-2 text-muted-foreground hover:text-destructive hover:bg-destructive/10 rounded-lg transition-colors"
            title="Delete"
            aria-label="Delete memory item"
          >
            <Trash2 size={16} />
          </button>

  )
}

function InfrastructureCard({
  id: _id,
  name,
  type,
  config,
  createdAt,
  onDelete,
}: {
  id: number
  name: string
  type: string
  config: Record<string, unknown>
  createdAt: string
  onDelete: () => void
}) {
  return (

{name}

              {type}

            {JSON.stringify(config, null, 2)}

            Created: {new Date(createdAt).toLocaleString()}

        <button
          onClick={onDelete}
          className="p-2 text-muted-foreground hover:text-destructive hover:bg-destructive/10 rounded-lg transition-colors"
          title="Delete"
        >
          <Trash2 size={16} />
        </button>

  )
}

function EmptyState({
  title,
  description,
}: {
  title: string
  description: string
}) {
  return (

      <Brain size={48} className="text-muted-foreground mx-auto mb-4" />

{title}

{description}

  )
}

<div className="flex items-center gap-2">

+            onClick={handleOpenImportDialog}

+            className="flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors disabled:opacity-50"

+            title="Import Memory Items"

+            <span>{isImporting ? 'Importing...' : 'Import'}</span>


Now let me add the Import dialog at the end of the component, before the closing `</div>`:


720→                  {(editItem?.memoryType === 'project'
   721→                    ? ['insight', 'pattern', 'gotcha', 'codebase_map']
   722→                    : ['preference', 'pattern', 'solution']
   723→                  ).map(type => (
   724→                    <option key={type} value={type}>{type}</option>
   725→                  ))}
   726→                </select>
   727→

   728→
   729→

   730→                Content *
   731→                <textarea
   732→                  value={editItemContent}
   733→                  onChange={(e) => setEditItemContent(e.target.value)}
   734→                  rows={4}
   735→                  className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-accent resize-none"
   736→                  placeholder="Enter memory content..."
   737→                />
   738→

   739→

   740→
   741→

   742→              <Dialog.Close asChild>
   743→                <button className="px-4 py-2 text-sm text-secondary-foreground hover:bg-secondary rounded-lg transition-colors">
   744→                  Cancel
   745→                </button>
   746→              </Dialog.Close>
   747→              <button
   748→                onClick={handleEditSave}
   749→                disabled={isEditing || !editItemContent.trim()}
   750→                className="px-4 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
   751→              >
   752→                {isEditing ? 'Saving...' : 'Save Changes'}
   753→              </button>
   754→

   755→          </Dialog.Content>
   756→        </Dialog.Portal>
   757→      </Dialog.Root>
   758→

   759→  )
   760→}
   761→
   762→function MemoryCard({
   763→  id: _id,
   764→  type,
   765→  content,
   766→  createdAt,
   767→  usageCount,
   768→  onDelete,
   769→  onEdit,
   770→}: {
   771→  id: number
   772→  type: string
   773→  content: string
   774→  createdAt: string
   775→  usageCount?: number
   776→  onDelete: () => void
   777→  onEdit?: () => void
   778→}) {
   779→  return (
   780→

   781→

   782→

   783→

   784→
   785→              {type}
   786→
   787→            {usageCount !== undefined && (
   788→              Used {usageCount} times
   789→            )}
   790→

   791→
{content}

   792→

   793→            Created: {new Date(createdAt).toLocaleString()}
   794→

   795→

   796→

   797→          {onEdit && (
   798→            <button
   799→              onClick={onEdit}
   800→              className="p-2 text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors"
   801→              title="Edit"
   802→              aria-label="Edit memory item"
   803→            >
   804→              <Pencil size={16} />
   805→            </button>
   806→          )}
   807→          <button
   808→            onClick={onDelete}
   809→            className="p-2 text-muted-foreground hover:text-destructive hover:bg-destructive/10 rounded-lg transition-colors"
   810→            title="Delete"
   811→            aria-label="Delete memory item"
   812→          >
   813→            <Trash2 size={16} />
   814→          </button>
   815→

   816→

   817→

   818→  )
   819→}

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>

{(editItem?.memoryType === 'project'
                    ? ['insight', 'pattern', 'gotcha', 'codebase_map']
                    : ['preference', 'pattern', 'solution']
                  ).map(type => (
                    <option key={type} value={type}>{type}</option>
                  ))}
                </select>

                Content *
                <textarea
                  value={editItemContent}
                  onChange={(e) => setEditItemContent(e.target.value)}
                  rows={4}
                  className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-accent resize-none"
                  placeholder="Enter memory content..."
                />

              <Dialog.Close asChild>
                <button className="px-4 py-2 text-sm text-secondary-foreground hover:bg-secondary rounded-lg transition-colors">
                  Cancel
                </button>
              </Dialog.Close>
              <button
                onClick={handleEditSave}
                disabled={isEditing || !editItemContent.trim()}
                className="px-4 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
              >
                {isEditing ? 'Saving...' : 'Save Changes'}
              </button>

          </Dialog.Content>
        </Dialog.Portal>
      </Dialog.Root>

  )
}

function MemoryCard({
  id: _id,
  type,
  content,
  createdAt,
  usageCount,
  onDelete,
  onEdit,
}: {
  id: number
  type: string
  content: string
  createdAt: string
  usageCount?: number
  onDelete: () => void
  onEdit?: () => void
}) {
  return (

              {type}

            {usageCount !== undefined && (
              Used {usageCount} times
            )}

{content}

            Created: {new Date(createdAt).toLocaleString()}

          {onEdit && (
            <button
              onClick={onEdit}
              className="p-2 text-muted-foreground hover:text-accent hover:bg-accent/10 rounded-lg transition-colors"
              title="Edit"
              aria-label="Edit memory item"
            >
              <Pencil size={16} />
            </button>
          )}
          <button
            onClick={onDelete}
            className="p-2 text-muted-foreground hover:text-destructive hover:bg-destructive/10 rounded-lg transition-colors"
            title="Delete"
            aria-label="Delete memory item"
          >
            <Trash2 size={16} />
          </button>

  )
}


</Dialog.Content>
        </Dialog.Portal>
      </Dialog.Root>
    </div>
  )
}

function MemoryCard({

</Dialog.Content>
        </Dialog.Portal>
      </Dialog.Root>

      {/* Import Memory Dialog */}
      <Dialog.Root open={showImportDialog} onOpenChange={setShowImportDialog}>
        <Dialog.Portal>
          <Dialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
          <Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-card border border-border rounded-lg p-4 md:p-6 w-[calc(100%-2rem)] max-w-md max-h-[calc(100vh-2rem)] overflow-y-auto z-50 shadow-xl">

              <Dialog.Title className="text-xl font-semibold text-foreground">
                Import Memory Items
              </Dialog.Title>
              <Dialog.Close asChild>
                <button className="p-1 text-muted-foreground hover:text-foreground hover:bg-secondary rounded transition-colors" aria-label="Close">
                  <X size={20} />
                </button>
              </Dialog.Close>

            <Dialog.Description className="mt-3 text-muted-foreground text-sm">
              Select a JSON file exported from Memory Manager to import memory items.
            </Dialog.Description>

                Select File *
                <input
                  type="file"
                  accept=".json"
                  onChange={handleFileSelect}
                  className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground file:mr-4 file:py-1 file:px-3 file:rounded file:border-0 file:bg-primary file:text-primary-foreground file:text-sm file:cursor-pointer focus:outline-none focus:ring-2 focus:ring-accent"
                />
                {importFile && (

                    Selected: {importFile.name}

                )}

              {importError && (

{importError}

              )}

              <Dialog.Close asChild>
                <button className="px-4 py-2 text-sm text-secondary-foreground hover:bg-secondary rounded-lg transition-colors">
                  Cancel
                </button>
              </Dialog.Close>
              <button
                onClick={handleImportMemory}
                disabled={isImporting || !importFile}
                className="px-4 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
              >
                {isImporting ? 'Importing...' : 'Import'}
              </button>

          </Dialog.Content>
        </Dialog.Portal>
      </Dialog.Root>

  )
}

function MemoryCard({