1→import { useState, useEffect } from 'react'
     2→import { Brain, Globe, Server, Plus, Search, Trash2, X, Pencil } from 'lucide-react'
     3→import * as Dialog from '@radix-ui/react-dialog'
     4→import * as AlertDialog from '@radix-ui/react-alert-dialog'
     5→import { useProjectStore } from '../stores/projectStore'
     6→
     7→type MemoryTab = 'project' | 'global' | 'infrastructure'
     8→
     9→interface ProjectMemoryItem {
    10→  id: number
    11→  project_id: number
    12→  type: string
    13→  content: string
    14→  metadata: Record<string, unknown> | null
    15→  created_at: string
    16→}
    17→
    18→interface GlobalMemoryItem {
    19→  id: number
    20→  type: string
    21→  content: string
    22→  metadata: Record<string, unknown> | null
    23→  usage_count: number
    24→  created_at: string
    25→}
    26→
    27→interface InfrastructureItem {
    28→  id: number
    29→  name: string
    30→  type: string
    31→  config: Record<string, unknown>
    32→  projects: number[] | null
    33→  created_at: string
    34→  updated_at: string
    35→}
    36→
    37→const API_BASE = 'http://localhost:8000/api/memory'
    38→
    39→export default function MemoryManager() {
    40→  const { currentProject } = useProjectStore()
    41→  const [activeTab, setActiveTab] = useState<MemoryTab>('project')
    42→  const [searchQuery, setSearchQuery] = useState('')
    43→
    44→  // Data states
    45→  const [projectMemory, setProjectMemory] = useState<ProjectMemoryItem[]>([])
    46→  const [globalMemory, setGlobalMemory] = useState<GlobalMemoryItem[]>([])
    47→  const [infrastructure, setInfrastructure] = useState<InfrastructureItem[]>([])
    48→  const [isLoading, setIsLoading] = useState(false)
    49→
    50→  // Dialog states
    51→  const [showAddDialog, setShowAddDialog] = useState(false)
    52→  const [newItemType, setNewItemType] = useState('')
    53→  const [newItemContent, setNewItemContent] = useState('')
    54→  const [newItemName, setNewItemName] = useState('')
    55→  const [isSaving, setIsSaving] = useState(false)
    56→
    57→  // Delete dialog states
    58→  const [showDeleteDialog, setShowDeleteDialog] = useState(false)
    59→  const [itemToDelete, setItemToDelete] = useState<{ id: number; type: MemoryTab } | null>(null)
    60→  const [isDeleting, setIsDeleting] = useState(false)
    61→
    62→  // Edit dialog states
    63→  const [showEditDialog, setShowEditDialog] = useState(false)
    64→  const [editItem, setEditItem] = useState<{ id: number; type: string; content: string; memoryType: MemoryTab } | null>(null)
    65→  const [editItemType, setEditItemType] = useState('')
    66→  const [editItemContent, setEditItemContent] = useState('')
    67→  const [isEditing, setIsEditing] = useState(false)
    68→
    69→  const tabs = [
    70→    { id: 'project' as const, label: 'Project Memory', icon: Brain },
    71→    { id: 'global' as const, label: 'Global Memory', icon: Globe },
    72→    { id: 'infrastructure' as const, label: 'Infrastructure', icon: Server },
    73→  ]
    74→
    75→  // Fetch data based on active tab
    76→  useEffect(() => {
    77→    const fetchData = async () => {
    78→      setIsLoading(true)
    79→      try {
    80→        if (activeTab === 'project' && currentProject) {
    81→          const response = await fetch(`${API_BASE}/project/${currentProject.id}`)
    82→          if (response.ok) {
    83→            const data = await response.json()
    84→            setProjectMemory(data)
    85→          }
    86→        } else if (activeTab === 'global') {
    87→          const response = await fetch(`${API_BASE}/global`)
    88→          if (response.ok) {
    89→            const data = await response.json()
    90→            setGlobalMemory(data)
    91→          }
    92→        } else if (activeTab === 'infrastructure') {
    93→          const response = await fetch(`${API_BASE}/infrastructure`)
    94→          if (response.ok) {
    95→            const data = await response.json()
    96→            setInfrastructure(data)
    97→          }
    98→        }
    99→      } catch (error) {
   100→        console.error('Failed to fetch memory items:', error)
   101→      } finally {
   102→        setIsLoading(false)
   103→      }
   104→    }
   105→    fetchData()
   106→  }, [activeTab, currentProject])
   107→
   108→  const getTypeOptions = () => {
   109→    switch (activeTab) {
   110→      case 'project':
   111→        return ['insight', 'pattern', 'gotcha', 'codebase_map']
   112→      case 'global':
   113→        return ['preference', 'pattern', 'solution']
   114→      case 'infrastructure':
   115→        return ['server', 'docker', 'database', 'deployment']
   116→      default:
   117→        return []
   118→    }
   119→  }
   120→
   121→  const handleOpenAddDialog = () => {
   122→    setNewItemType(getTypeOptions()[0] || '')
   123→    setNewItemContent('')
   124→    setNewItemName('')
   125→    setShowAddDialog(true)
   126→  }
   127→
   128→  const handleAddItem = async () => {
   129→    if (!newItemType || (!newItemContent.trim() && activeTab !== 'infrastructure')) return
   130→    if (activeTab === 'infrastructure' && !newItemName.trim()) return
   131→
   132→    setIsSaving(true)
   133→    try {
   134→      let response: Response
   135→
   136→      if (activeTab === 'project' && currentProject) {
   137→        response = await fetch(`${API_BASE}/project/${currentProject.id}`, {
   138→          method: 'POST',
   139→          headers: { 'Content-Type': 'application/json' },
   140→          body: JSON.stringify({ type: newItemType, content: newItemContent.trim() }),
   141→        })
   142→        if (response.ok) {
   143→          const newItem = await response.json()
   144→          setProjectMemory([...projectMemory, newItem])
   145→        }
   146→      } else if (activeTab === 'global') {
   147→        response = await fetch(`${API_BASE}/global`, {
   148→          method: 'POST',
   149→          headers: { 'Content-Type': 'application/json' },
   150→          body: JSON.stringify({ type: newItemType, content: newItemContent.trim() }),
   151→        })
   152→        if (response.ok) {
   153→          const newItem = await response.json()
   154→          setGlobalMemory([...globalMemory, newItem])
   155→        }
   156→      } else if (activeTab === 'infrastructure') {
   157→        response = await fetch(`${API_BASE}/infrastructure`, {
   158→          method: 'POST',
   159→          headers: { 'Content-Type': 'application/json' },
   160→          body: JSON.stringify({
   161→            name: newItemName.trim(),
   162→            type: newItemType,
   163→            config: { content: newItemContent.trim() }
   164→          }),
   165→        })
   166→        if (response.ok) {
   167→          const newItem = await response.json()
   168→          setInfrastructure([...infrastructure, newItem])
   169→        }
   170→      }
   171→
   172→      setShowAddDialog(false)
   173→    } catch (error) {
   174→      console.error('Failed to add memory item:', error)
   175→    } finally {
   176→      setIsSaving(false)
   177→    }
   178→  }
   179→
   180→  const handleDeleteClick = (id: number, type: MemoryTab) => {
   181→    setItemToDelete({ id, type })
   182→    setShowDeleteDialog(true)
   183→  }
   184→
   185→  const handleDeleteConfirm = async () => {
   186→    if (!itemToDelete) return
   187→
   188→    setIsDeleting(true)
   189→    try {
   190→      let endpoint: string
   191→
   192→      if (itemToDelete.type === 'project' && currentProject) {
   193→        endpoint = `${API_BASE}/project/${currentProject.id}/${itemToDelete.id}`
   194→      } else if (itemToDelete.type === 'global') {
   195→        endpoint = `${API_BASE}/global/${itemToDelete.id}`
   196→      } else {
   197→        endpoint = `${API_BASE}/infrastructure/${itemToDelete.id}`
   198→      }
   199→
   200→      const response = await fetch(endpoint, { method: 'DELETE' })
   201→
   202→      if (response.ok || response.status === 204) {
   203→        if (itemToDelete.type === 'project') {
   204→          setProjectMemory(projectMemory.filter(item => item.id !== itemToDelete.id))
   205→        } else if (itemToDelete.type === 'global') {
   206→          setGlobalMemory(globalMemory.filter(item => item.id !== itemToDelete.id))
   207→        } else {
   208→          setInfrastructure(infrastructure.filter(item => item.id !== itemToDelete.id))
   209→        }
   210→      }
   211→
   212→      setShowDeleteDialog(false)
   213→      setItemToDelete(null)
   214→    } catch (error) {
   215→      console.error('Failed to delete memory item:', error)
   216→    } finally {
   217→      setIsDeleting(false)
   218→    }
   219→  }
   220→
   221→  const handleEditClick = (id: number, type: string, content: string, memoryType: MemoryTab) => {
   222→    setEditItem({ id, type, content, memoryType })
   223→    setEditItemType(type)
   224→    setEditItemContent(content)
   225→    setShowEditDialog(true)
   226→  }
   227→
   228→  const handleEditSave = async () => {
   229→    if (!editItem || !editItemContent.trim()) return
   230→
   231→    setIsEditing(true)
   232→    try {
   233→      let endpoint: string
   234→      let body: Record<string, unknown>
   235→
   236→      if (editItem.memoryType === 'project' && currentProject) {
   237→        endpoint = `${API_BASE}/project/${currentProject.id}/${editItem.id}`
   238→        body = { type: editItemType, content: editItemContent.trim() }
   239→      } else if (editItem.memoryType === 'global') {
   240→        endpoint = `${API_BASE}/global/${editItem.id}`
   241→        body = { type: editItemType, content: editItemContent.trim() }
   242→      } else {
   243→        // Infrastructure uses different update endpoint
   244→        setShowEditDialog(false)
   245→        setEditItem(null)
   246→        return
   247→      }
   248→
   249→      const response = await fetch(endpoint, {
   250→        method: 'PUT',
   251→        headers: { 'Content-Type': 'application/json' },
   252→        body: JSON.stringify(body),
   253→      })
   254→
   255→      if (response.ok) {
   256→        const updatedItem = await response.json()
   257→        if (editItem.memoryType === 'project') {
   258→          setProjectMemory(projectMemory.map(item =>
   259→            item.id === editItem.id ? updatedItem : item
   260→          ))
   261→        } else if (editItem.memoryType === 'global') {
   262→          setGlobalMemory(globalMemory.map(item =>
   263→            item.id === editItem.id ? updatedItem : item
   264→          ))
   265→        }
   266→      }
   267→
   268→      setShowEditDialog(false)
   269→      setEditItem(null)
   270→    } catch (error) {
   271→      console.error('Failed to update memory item:', error)
   272→    } finally {
   273→      setIsEditing(false)
   274→    }
   275→  }
   276→
   277→  const filterItems = <T extends { content?: string; name?: string; type: string }>(items: T[]) => {
   278→    if (!searchQuery) return items
   279→    const query = searchQuery.toLowerCase()
   280→    return items.filter(item =>
   281→      item.content?.toLowerCase().includes(query) ||
   282→      item.name?.toLowerCase().includes(query) ||
   283→      item.type.toLowerCase().includes(query)
   284→    )
   285→  }
   286→
   287→  const filteredProjectMemory = filterItems(projectMemory)
   288→  const filteredGlobalMemory = filterItems(globalMemory)
   289→  const filteredInfrastructure = filterItems(infrastructure)
   290→
   291→  return (
   292→

   293→      {/* Header */}
   294→

   295→
Memory Manager

   296→        <button
   297→          onClick={handleOpenAddDialog}
   298→          className="btn-accent flex items-center gap-2"
   299→        >
   300→          <Plus size={18} />
   301→          Add Memory Item
   302→        </button>
   303→

   304→
   305→      {/* Tabs */}
   306→

   307→        {tabs.map((tab) => {
   308→          const Icon = tab.icon
   309→          return (
   310→            <button
   311→              key={tab.id}
   312→              onClick={() => setActiveTab(tab.id)}
   313→              className={`flex items-center gap-2 px-4 py-2 rounded-md transition-colors ${
   314→                activeTab === tab.id
   315→                  ? 'bg-primary-700 text-white'
   316→                  : 'text-slate-400 hover:text-white'
   317→              }`}
   318→            >
   319→              <Icon size={16} />
   320→              {tab.label}
   321→            </button>
   322→          )
   323→        })}
   324→

   325→
   326→      {/* Search */}
   327→

   328→        <Search
   329→          size={18}
   330→          className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400"
   331→        />
   332→        <input
   333→          type="text"
   334→          value={searchQuery}
   335→          onChange={(e) => setSearchQuery(e.target.value)}
   336→          placeholder="Search memory items..."
   337→          className="w-full pl-10 pr-4 py-2 bg-slate-800 border border-slate-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-accent"
   338→        />
   339→

   340→
   341→      {/* Content */}
   342→

   343→        {isLoading ? (
   344→
Loading...

   345→        ) : (
   346→          <>
   347→            {activeTab === 'project' && (
   348→

   349→                {filteredProjectMemory.length === 0 ? (
   350→                  <EmptyState
   351→                    title="No Project Memory"
   352→                    description="Memory items from your current project will appear here."
   353→                  />
   354→                ) : (
   355→                  filteredProjectMemory.map(item => (
   356→                    <MemoryCard
   357→                      key={item.id}
   358→                      id={item.id}
   359→                      type={item.type}
   360→                      content={item.content}
   361→                      createdAt={item.created_at}
   362→                      onDelete={() => handleDeleteClick(item.id, 'project')}
   363→                      onEdit={() => handleEditClick(item.id, item.type, item.content, 'project')}
   364→                    />
   365→                  ))
   366→                )}
   367→

   368→            )}
   369→
   370→            {activeTab === 'global' && (
   371→

   372→                {filteredGlobalMemory.length === 0 ? (
   373→                  <EmptyState
   374→                    title="No Global Memory"
   375→                    description="Cross-project patterns and preferences will appear here."
   376→                  />
   377→                ) : (
   378→                  filteredGlobalMemory.map(item => (
   379→                    <MemoryCard
   380→                      key={item.id}
   381→                      id={item.id}
   382→                      type={item.type}
   383→                      content={item.content}
   384→                      createdAt={item.created_at}
   385→                      usageCount={item.usage_count}
   386→                      onDelete={() => handleDeleteClick(item.id, 'global')}
   387→                      onEdit={() => handleEditClick(item.id, item.type, item.content, 'global')}
   388→                    />
   389→                  ))
   390→                )}
   391→

   392→            )}
   393→
   394→            {activeTab === 'infrastructure' && (
   395→

   396→                {filteredInfrastructure.length === 0 ? (
   397→                  <EmptyState
   398→                    title="No Infrastructure Config"
   399→                    description="Server and deployment configurations will appear here."
   400→                  />
   401→                ) : (
   402→                  filteredInfrastructure.map(item => (
   403→                    <InfrastructureCard
   404→                      key={item.id}
   405→                      id={item.id}
   406→                      name={item.name}
   407→                      type={item.type}
   408→                      config={item.config}
   409→                      createdAt={item.created_at}
   410→                      onDelete={() => handleDeleteClick(item.id, 'infrastructure')}
   411→                    />
   412→                  ))
   413→                )}
   414→

   415→            )}
   416→          </>
   417→        )}
   418→

   419→
   420→      {/* Add Memory Dialog */}
   421→      <Dialog.Root open={showAddDialog} onOpenChange={setShowAddDialog}>
   422→        <Dialog.Portal>
   423→          <Dialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
   424→          <Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-slate-800 border border-slate-700 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">
   425→

   426→              <Dialog.Title className="text-xl font-semibold text-white">
   427→                Add {activeTab === 'project' ? 'Project' : activeTab === 'global' ? 'Global' : 'Infrastructure'} Memory
   428→              </Dialog.Title>
   429→              <Dialog.Close asChild>
   430→                <button className="p-1 text-slate-400 hover:text-white hover:bg-slate-700 rounded transition-colors" aria-label="Close">
   431→                  <X size={20} />
   432→                </button>
   433→              </Dialog.Close>
   434→

   435→
   436→

   437→              {activeTab === 'infrastructure' && (
   438→

   439→                  Name *
   440→                  <input
   441→                    type="text"
   442→                    value={newItemName}
   443→                    onChange={(e) => setNewItemName(e.target.value)}
   444→                    className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent"
   445→                    placeholder="Enter config name"
   446→                  />
   447→

   448→              )}
   449→
   450→

   451→                Type *
   452→                <select
   453→                  value={newItemType}
   454→                  onChange={(e) => setNewItemType(e.target.value)}
   455→                  className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-accent"
   456→                >
   457→                  {getTypeOptions().map(type => (
   458→                    <option key={type} value={type}>{type}</option>
   459→                  ))}
   460→                </select>
   461→

   462→
   463→

   464→                Content *
   465→                <textarea
   466→                  value={newItemContent}
   467→                  onChange={(e) => setNewItemContent(e.target.value)}
   468→                  rows={4}
   469→                  className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent resize-none"
   470→                  placeholder="Enter memory content..."
   471→                />
   472→

   473→

   474→
   475→

   476→              <Dialog.Close asChild>
   477→                <button className="px-4 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors">
   478→                  Cancel
   479→                </button>
   480→              </Dialog.Close>
   481→              <button
   482→                onClick={handleAddItem}
   483→                disabled={isSaving || !newItemContent.trim() || (activeTab === 'infrastructure' && !newItemName.trim())}
   484→                className="px-4 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
   485→              >
   486→                {isSaving ? 'Saving...' : 'Add Item'}
   487→              </button>
   488→

   489→          </Dialog.Content>
   490→        </Dialog.Portal>
   491→      </Dialog.Root>
   492→
   493→      {/* Delete Confirmation Dialog */}
   494→      <AlertDialog.Root open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
   495→        <AlertDialog.Portal>
   496→          <AlertDialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
   497→          <AlertDialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-slate-800 border border-slate-700 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">
   498→            <AlertDialog.Title className="text-xl font-semibold text-white">
   499→              Delete Memory Item
   500→            </AlertDialog.Title>
   501→            <AlertDialog.Description className="mt-3 text-slate-400">
   502→              Are you sure you want to delete this memory item? This action cannot be undone.
   503→            </AlertDialog.Description>
   504→

   505→              <AlertDialog.Cancel asChild>
   506→                <button className="px-4 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors">
   507→                  Cancel
   508→                </button>
   509→              </AlertDialog.Cancel>
   510→              <AlertDialog.Action asChild>
   511→                <button
   512→                  onClick={handleDeleteConfirm}
   513→                  disabled={isDeleting}
   514→                  className="px-4 py-2 text-sm bg-destructive hover:bg-destructive/80 text-white rounded-lg transition-colors disabled:opacity-50"
   515→                >
   516→                  {isDeleting ? 'Deleting...' : 'Delete'}
   517→                </button>
   518→              </AlertDialog.Action>
   519→

   520→          </AlertDialog.Content>
   521→        </AlertDialog.Portal>
   522→      </AlertDialog.Root>
   523→
   524→      {/* Edit Memory Dialog */}
   525→      <Dialog.Root open={showEditDialog} onOpenChange={setShowEditDialog}>
   526→        <Dialog.Portal>
   527→          <Dialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
   528→          <Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-slate-800 border border-slate-700 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">
   529→

   530→              <Dialog.Title className="text-xl font-semibold text-white">
   531→                Edit Memory Item
   532→              </Dialog.Title>
   533→              <Dialog.Close asChild>
   534→                <button className="p-1 text-slate-400 hover:text-white hover:bg-slate-700 rounded transition-colors" aria-label="Close">
   535→                  <X size={20} />
   536→                </button>
   537→              </Dialog.Close>
   538→

   539→
   540→

   541→

   542→                Type *
   543→                <select
   544→                  value={editItemType}
   545→                  onChange={(e) => setEditItemType(e.target.value)}
   546→                  className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-accent"
   547→                >
   548→                  {(editItem?.memoryType === 'project'
   549→                    ? ['insight', 'pattern', 'gotcha', 'codebase_map']
   550→                    : ['preference', 'pattern', 'solution']
   551→                  ).map(type => (
   552→                    <option key={type} value={type}>{type}</option>
   553→                  ))}
   554→                </select>
   555→

   556→
   557→

   558→                Content *
   559→                <textarea
   560→                  value={editItemContent}
   561→                  onChange={(e) => setEditItemContent(e.target.value)}
   562→                  rows={4}
   563→                  className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent resize-none"
   564→                  placeholder="Enter memory content..."
   565→                />
   566→

   567→

   568→
   569→

   570→              <Dialog.Close asChild>
   571→                <button className="px-4 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors">
   572→                  Cancel
   573→                </button>
   574→              </Dialog.Close>
   575→              <button
   576→                onClick={handleEditSave}
   577→                disabled={isEditing || !editItemContent.trim()}
   578→                className="px-4 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
   579→              >
   580→                {isEditing ? 'Saving...' : 'Save Changes'}
   581→              </button>
   582→

   583→          </Dialog.Content>
   584→        </Dialog.Portal>
   585→      </Dialog.Root>
   586→

   587→  )
   588→}
   589→
   590→function MemoryCard({
   591→  id: _id,
   592→  type,
   593→  content,
   594→  createdAt,
   595→  usageCount,
   596→  onDelete,
   597→  onEdit,
   598→}: {
   599→  id: number
   600→  type: string
   601→  content: string
   602→  createdAt: string
   603→  usageCount?: number
   604→  onDelete: () => void
   605→  onEdit?: () => void
   606→}) {
   607→  return (
   608→

   609→

   610→

   611→

   612→
   613→              {type}
   614→
   615→            {usageCount !== undefined && (
   616→              Used {usageCount} times
   617→            )}
   618→

   619→
{content}

   620→

   621→            Created: {new Date(createdAt).toLocaleString()}
   622→

   623→

   624→

   625→          {onEdit && (
   626→            <button
   627→              onClick={onEdit}
   628→              className="p-2 text-slate-400 hover:text-accent hover:bg-accent/10 rounded-lg transition-colors"
   629→              title="Edit"
   630→              aria-label="Edit memory item"
   631→            >
   632→              <Pencil size={16} />
   633→            </button>
   634→          )}
   635→          <button
   636→            onClick={onDelete}
   637→            className="p-2 text-slate-400 hover:text-destructive hover:bg-destructive/10 rounded-lg transition-colors"
   638→            title="Delete"
   639→            aria-label="Delete memory item"
   640→          >
   641→            <Trash2 size={16} />
   642→          </button>
   643→

   644→

   645→

   646→  )
   647→}
   648→
   649→function InfrastructureCard({
   650→  id: _id,
   651→  name,
   652→  type,
   653→  config,
   654→  createdAt,
   655→  onDelete,
   656→}: {
   657→  id: number
   658→  name: string
   659→  type: string
   660→  config: Record<string, unknown>
   661→  createdAt: string
   662→  onDelete: () => void
   663→}) {
   664→  return (
   665→

   666→

   667→

   668→

   669→
{name}

   670→
   671→              {type}
   672→
   673→

   674→

   675→            {JSON.stringify(config, null, 2)}
   676→

   677→

   678→            Created: {new Date(createdAt).toLocaleString()}
   679→

   680→

   681→        <button
   682→          onClick={onDelete}
   683→          className="p-2 text-slate-400 hover:text-destructive hover:bg-destructive/10 rounded-lg transition-colors"
   684→          title="Delete"
   685→        >
   686→          <Trash2 size={16} />
   687→        </button>
   688→

   689→

   690→  )
   691→}
   692→
   693→function EmptyState({
   694→  title,
   695→  description,
   696→}: {
   697→  title: string
   698→  description: string
   699→}) {
   700→  return (
   701→

   702→      <Brain size={48} className="text-slate-600 mx-auto mb-4" />
   703→
{title}

   704→
{description}

   705→

   706→  )
   707→}
   708→

<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>

import { useState, useEffect } from 'react'
import { Brain, Globe, Server, Plus, Search, Trash2, X, Pencil } 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'

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 [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 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)

  return (

      {/* Header */}

Memory Manager

        <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-700 text-white'
                  : 'text-slate-400 hover:text-white'
              }`}
            >
              <Icon size={16} />
              {tab.label}
            </button>
          )
        })}

      {/* Search */}

        <Search
          size={18}
          className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400"
        />
        <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-slate-800 border border-slate-700 rounded-lg 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-slate-800 border border-slate-700 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-white">
                Add {activeTab === 'project' ? 'Project' : activeTab === 'global' ? 'Global' : 'Infrastructure'} Memory
              </Dialog.Title>
              <Dialog.Close asChild>
                <button className="p-1 text-slate-400 hover:text-white hover:bg-slate-700 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-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 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-slate-900 border border-slate-700 rounded-lg text-white 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-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 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-slate-300 hover:bg-slate-700 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-slate-800 border border-slate-700 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-white">
              Delete Memory Item
            </AlertDialog.Title>
            <AlertDialog.Description className="mt-3 text-slate-400">
              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-slate-300 hover:bg-slate-700 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-slate-800 border border-slate-700 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-white">
                Edit Memory Item
              </Dialog.Title>
              <Dialog.Close asChild>
                <button className="p-1 text-slate-400 hover:text-white hover:bg-slate-700 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-slate-900 border border-slate-700 rounded-lg text-white 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-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 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-slate-300 hover:bg-slate-700 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-slate-400 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-slate-400 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-slate-400 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-slate-600 mx-auto mb-4" />

{title}

{description}

  )
}


Let me also check ProjectWizard and AgentTerminals:


1→import { useState } from 'react'
     2→import { useNavigate } from 'react-router-dom'
     3→import { useProjectStore } from '../stores/projectStore'
     4→import { ArrowLeft, ArrowRight, Check, Loader2, Plus, X } from 'lucide-react'
     5→
     6→interface TechStack {
     7→  frontend: string[]
     8→  backend: string[]
     9→  database: string[]
    10→  other: string[]
    11→}
    12→
    13→interface DesignPreferences {
    14→  theme: 'light' | 'dark' | 'system'
    15→  primaryColor: string
    16→  style: 'minimal' | 'modern' | 'classic'
    17→  designMode: 'mvp' | 'finished'
    18→}
    19→
    20→export default function ProjectWizard() {
    21→  const navigate = useNavigate()
    22→  const { createProject, isLoading } = useProjectStore()
    23→  const [step, setStep] = useState(1)
    24→  const [formData, setFormData] = useState({
    25→    name: '',
    26→    description: '',
    27→    complexity: 'medium',
    28→    path: '',
    29→  })
    30→  const [techStack, setTechStack] = useState<TechStack>({
    31→    frontend: [],
    32→    backend: [],
    33→    database: [],
    34→    other: [],
    35→  })
    36→  const [features, setFeatures] = useState<string[]>([])
    37→  const [newFeature, setNewFeature] = useState('')
    38→  const [designPreferences, setDesignPreferences] = useState<DesignPreferences>({
    39→    theme: 'dark',
    40→    primaryColor: '#0d9488',
    41→    style: 'modern',
    42→    designMode: 'mvp',
    43→  })
    44→  const [errors, setErrors] = useState<{ name?: string }>({})
    45→  const [touched, setTouched] = useState<{ name?: boolean }>({})
    46→
    47→  const totalSteps = 5
    48→
    49→  const validateName = (name: string): string | undefined => {
    50→    if (!name.trim()) {
    51→      return 'Project name is required'
    52→    }
    53→    if (name.trim().length < 2) {
    54→      return 'Project name must be at least 2 characters'
    55→    }
    56→    if (name.trim().length > 100) {
    57→      return 'Project name must be less than 100 characters'
    58→    }
    59→    return undefined
    60→  }
    61→
    62→  const handleNext = () => {
    63→    if (step === 1) {
    64→      const nameError = validateName(formData.name)
    65→      setTouched({ ...touched, name: true })
    66→      setErrors({ ...errors, name: nameError })
    67→      if (nameError) return
    68→    }
    69→    if (step < totalSteps) {
    70→      setStep(step + 1)
    71→    }
    72→  }
    73→
    74→  const handleBack = () => {
    75→    if (step > 1) {
    76→      setStep(step - 1)
    77→    }
    78→  }
    79→
    80→  const handleSubmit = async () => {
    81→    try {
    82→      await createProject({
    83→        name: formData.name,
    84→        description: formData.description,
    85→        design_mode: designPreferences.designMode,
    86→      })
    87→      navigate('/')
    88→    } catch (error) {
    89→      console.error('Failed to create project:', error)
    90→    }
    91→  }
    92→
    93→  return (
    94→

    95→      {/* Progress */}
    96→

    97→

    98→
    99→            Step {step} of {totalSteps}
   100→
   101→
   102→            {Math.round((step / totalSteps) * 100)}% complete
   103→
   104→

   105→

   106→          <div
   107→            className="h-full bg-accent transition-all duration-300"
   108→            style={{ width: `${(step / totalSteps) * 100}%` }}
   109→          />
   110→

   111→

   112→
   113→      {/* Step Content */}
   114→

   115→        {step === 1 && (
   116→

   117→
Project Basics

   118→

   119→

   120→
   121→                  Project Name *
   122→
   123→                <input
   124→                  id="project-name"
   125→                  type="text"
   126→                  value={formData.name}
   127→                  onChange={(e) => {
   128→                    const newName = e.target.value
   129→                    setFormData({ ...formData, name: newName })
   130→                    if (touched.name) {
   131→                      setErrors({ ...errors, name: validateName(newName) })
   132→                    }
   133→                  }}
   134→                  onBlur={() => {
   135→                    setTouched({ ...touched, name: true })
   136→                    setErrors({ ...errors, name: validateName(formData.name) })
   137→                  }}
   138→                  placeholder="My Awesome Project"
   139→                  className={`w-full px-4 py-2 bg-slate-700 border rounded-lg focus:outline-none focus:ring-2 ${
   140→                    touched.name && errors.name
   141→                      ? 'border-red-500 focus:ring-red-500'
   142→                      : 'border-slate-600 focus:ring-accent'
   143→                  }`}
   144→                />
   145→                {touched.name && errors.name && (
   146→
{errors.name}

   147→                )}
   148→

   149→

   150→
   151→                  Description
   152→
   153→                <textarea
   154→                  id="project-description"
   155→                  value={formData.description}
   156→                  onChange={(e) =>
   157→                    setFormData({ ...formData, description: e.target.value })
   158→                  }
   159→                  placeholder="A brief description of your project..."
   160→                  rows={3}
   161→                  className="w-full px-4 py-2 bg-slate-700 border border-slate-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-accent"
   162→                />
   163→

   164→

   165→

   166→        )}
   167→
   168→        {step === 2 && (
   169→

   170→
Technology Stack

   171→

   172→              {/* Frontend Technologies */}
   173→

   174→                Frontend
   175→

   176→                  {['React', 'Vue', 'Angular', 'Svelte', 'Next.js', 'HTML/CSS'].map((tech) => (
   177→                    <button
   178→                      key={tech}
   179→                      onClick={() => {
   180→                        const current = techStack.frontend
   181→                        setTechStack({
   182→                          ...techStack,
   183→                          frontend: current.includes(tech)
   184→                            ? current.filter((t) => t !== tech)
   185→                            : [...current, tech],
   186→                        })
   187→                      }}
   188→                      className={`px-3 py-1.5 rounded-lg border text-sm transition-colors ${
   189→                        techStack.frontend.includes(tech)
   190→                          ? 'border-accent bg-accent/20 text-accent'
   191→                          : 'border-slate-600 hover:border-slate-500'
   192→                      }`}
   193→                    >
   194→                      {tech}
   195→                    </button>
   196→                  ))}
   197→

   198→

   199→              {/* Backend Technologies */}
   200→

   201→                Backend
   202→

   203→                  {['Python', 'Node.js', 'Go', 'Rust', 'Java', 'Ruby', 'PHP'].map((tech) => (
   204→                    <button
   205→                      key={tech}
   206→                      onClick={() => {
   207→                        const current = techStack.backend
   208→                        setTechStack({
   209→                          ...techStack,
   210→                          backend: current.includes(tech)
   211→                            ? current.filter((t) => t !== tech)
   212→                            : [...current, tech],
   213→                        })
   214→                      }}
   215→                      className={`px-3 py-1.5 rounded-lg border text-sm transition-colors ${
   216→                        techStack.backend.includes(tech)
   217→                          ? 'border-accent bg-accent/20 text-accent'
   218→                          : 'border-slate-600 hover:border-slate-500'
   219→                      }`}
   220→                    >
   221→                      {tech}
   222→                    </button>
   223→                  ))}
   224→

   225→

   226→              {/* Database */}
   227→

   228→                Database
   229→

   230→                  {['PostgreSQL', 'MySQL', 'SQLite', 'MongoDB', 'Redis', 'Firebase'].map((tech) => (
   231→                    <button
   232→                      key={tech}
   233→                      onClick={() => {
   234→                        const current = techStack.database
   235→                        setTechStack({
   236→                          ...techStack,
   237→                          database: current.includes(tech)
   238→                            ? current.filter((t) => t !== tech)
   239→                            : [...current, tech],
   240→                        })
   241→                      }}
   242→                      className={`px-3 py-1.5 rounded-lg border text-sm transition-colors ${
   243→                        techStack.database.includes(tech)
   244→                          ? 'border-accent bg-accent/20 text-accent'
   245→                          : 'border-slate-600 hover:border-slate-500'
   246→                      }`}
   247→                    >
   248→                      {tech}
   249→                    </button>
   250→                  ))}
   251→

   252→

   253→

   254→

   255→        )}
   256→
   257→        {step === 3 && (
   258→

   259→
Features

   260→

   261→              Add the main features you want your project to have.
   262→

   263→

   264→              {/* Add feature input */}
   265→

   266→                Add a feature
   267→                <input
   268→                  id="new-feature"
   269→                  type="text"
   270→                  value={newFeature}
   271→                  onChange={(e) => setNewFeature(e.target.value)}
   272→                  onKeyDown={(e) => {
   273→                    if (e.key === 'Enter' && newFeature.trim()) {
   274→                      setFeatures([...features, newFeature.trim()])
   275→                      setNewFeature('')
   276→                    }
   277→                  }}
   278→                  placeholder="Enter a feature..."
   279→                  className="flex-1 px-4 py-2 bg-slate-700 border border-slate-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-accent"
   280→                />
   281→                <button
   282→                  onClick={() => {
   283→                    if (newFeature.trim()) {
   284→                      setFeatures([...features, newFeature.trim()])
   285→                      setNewFeature('')
   286→                    }
   287→                  }}
   288→                  disabled={!newFeature.trim()}
   289→                  className="btn-accent disabled:opacity-50 disabled:cursor-not-allowed"
   290→                >
   291→                  <Plus size={18} />
   292→                </button>
   293→

   294→              {/* Feature list */}
   295→

   296→                {features.length === 0 ? (
   297→
No features added yet

   298→                ) : (
   299→                  features.map((feature, index) => (
   300→

   304→                      {feature}
   305→                      <button
   306→                        onClick={() => setFeatures(features.filter((_, i) => i !== index))}
   307→                        className="text-slate-400 hover:text-destructive transition-colors"
   308→                      >
   309→                        <X size={16} />
   310→                      </button>
   311→

   312→                  ))
   313→                )}
   314→

   315→

   316→

   317→        )}
   318→
   319→        {step === 4 && (
   320→

   321→
Design Preferences

   322→

   323→              {/* Design Mode - MVP vs Finished */}
   324→

   325→                Design Mode
   326→

   327→                  Choose how strictly design requirements should be applied.
   328→

   329→

   330→                  <button
   331→                    onClick={() => setDesignPreferences({ ...designPreferences, designMode: 'mvp' })}
   332→                    className={`w-full p-4 rounded-lg border text-left transition-colors ${
   333→                      designPreferences.designMode === 'mvp'
   334→                        ? 'border-accent bg-accent/10'
   335→                        : 'border-slate-600 hover:border-slate-500'
   336→                    }`}
   337→                  >
   338→

   339→
MVP Mode

   340→                      {designPreferences.designMode === 'mvp' && (
   341→                        Selected
   342→                      )}
   343→

   344→

   345→                      Functional drafts are acceptable. Focus on getting features working first,
   346→                      with polished design coming later. Best for rapid prototyping and early development.
   347→

   348→                  </button>
   349→                  <button
   350→                    onClick={() => setDesignPreferences({ ...designPreferences, designMode: 'finished' })}
   351→                    className={`w-full p-4 rounded-lg border text-left transition-colors ${
   352→                      designPreferences.designMode === 'finished'
   353→                        ? 'border-accent bg-accent/10'
   354→                        : 'border-slate-600 hover:border-slate-500'
   355→                    }`}
   356→                  >
   357→

   358→
Finished Mode

   359→                      {designPreferences.designMode === 'finished' && (
   360→                        Selected
   361→                      )}
   362→

   363→

   364→                      Stricter design requirements apply. All frontend work must meet polish standards
   365→                      with proper typography, color, motion, and spatial composition. Best for production-ready builds.
   366→

   367→                  </button>
   368→

   369→

   370→              {/* Theme */}
   371→

   372→                Theme
   373→

   374→                  {(['light', 'dark', 'system'] as const).map((theme) => (
   375→                    <button
   376→                      key={theme}
   377→                      onClick={() => setDesignPreferences({ ...designPreferences, theme })}
   378→                      className={`flex-1 p-3 rounded-lg border text-center capitalize transition-colors ${
   379→                        designPreferences.theme === theme
   380→                          ? 'border-accent bg-accent/10'
   381→                          : 'border-slate-600 hover:border-slate-500'
   382→                      }`}
   383→                    >
   384→                      {theme}
   385→                    </button>
   386→                  ))}
   387→

   388→

   389→              {/* Style */}
   390→

   391→                UI Style
   392→

   393→                  {(['minimal', 'modern', 'classic'] as const).map((style) => (
   394→                    <button
   395→                      key={style}
   396→                      onClick={() => setDesignPreferences({ ...designPreferences, style })}
   397→                      className={`w-full p-3 rounded-lg border text-left transition-colors ${
   398→                        designPreferences.style === style
   399→                          ? 'border-accent bg-accent/10'
   400→                          : 'border-slate-600 hover:border-slate-500'
   401→                      }`}
   402→                    >
   403→
{style}

   404→

   405→                        {style === 'minimal' && 'Clean and simple design'}
   406→                        {style === 'modern' && 'Contemporary with subtle effects'}
   407→                        {style === 'classic' && 'Traditional and familiar layout'}
   408→

   409→                    </button>
   410→                  ))}
   411→

   412→

   413→              {/* Primary Color */}
   414→

   415→                Primary Color
   416→

   417→                  {['#0d9488', '#3b82f6', '#8b5cf6', '#ef4444', '#f59e0b'].map((color) => (
   418→                    <button
   419→                      key={color}
   420→                      onClick={() => setDesignPreferences({ ...designPreferences, primaryColor: color })}
   421→                      className={`w-10 h-10 rounded-lg border-2 transition-transform ${
   422→                        designPreferences.primaryColor === color
   423→                          ? 'border-white scale-110'
   424→                          : 'border-transparent hover:scale-105'
   425→                      }`}
   426→                      style={{ backgroundColor: color }}
   427→                    />
   428→                  ))}
   429→

   430→

   431→

   432→

   433→        )}
   434→
   435→        {step === 5 && (
   436→

   437→
Review & Create

   438→

   439→              {/* Project Basics */}
   440→

   441→
Project Name

   442→
{formData.name || 'Not set'}

   443→

   444→

   445→
Description

   446→

   447→                  {formData.description || 'No description'}
   448→

   449→

   450→              {/* Technology Stack */}
   451→

   452→
Technology Stack

   453→

   454→                  {techStack.frontend.length > 0 && (
   455→
Frontend: {techStack.frontend.join(', ')}

   456→                  )}
   457→                  {techStack.backend.length > 0 && (
   458→
Backend: {techStack.backend.join(', ')}

   459→                  )}
   460→                  {techStack.database.length > 0 && (
   461→
Database: {techStack.database.join(', ')}

   462→                  )}
   463→                  {techStack.frontend.length === 0 && techStack.backend.length === 0 && techStack.database.length === 0 && (
   464→
No technologies selected

   465→                  )}
   466→

   467→

   468→              {/* Features */}
   469→

   470→
Features

   471→                {features.length > 0 ? (
   472→

   473→                    {features.map((feature, i) => (
   474→
{feature}

   475→                    ))}
   476→

   477→                ) : (
   478→
No features added

   479→                )}
   480→

   481→              {/* Design Preferences */}
   482→

   483→
Design Preferences

   484→

   485→

   486→                    Design Mode:{' '}
   487→
   490→                      {designPreferences.designMode === 'mvp' ? 'MVP (Functional Drafts)' : 'Finished (Polished)'}
   491→
   492→

   493→
Theme: {designPreferences.theme}

   494→
Style: {designPreferences.style}

   495→

   496→                    Primary Color:
   497→
   501→

   502→

   503→

   504→

   505→

   506→        )}
   507→

   508→
   509→      {/* Navigation */}
   510→

   511→        <button
   512→          onClick={step === 1 ? () => navigate('/') : handleBack}
   513→          className="btn-secondary flex items-center gap-2"
   514→        >
   515→          <ArrowLeft size={18} />
   516→          {step === 1 ? 'Cancel' : 'Back'}
   517→        </button>
   518→
   519→        {step < totalSteps ? (
   520→          <button
   521→            onClick={handleNext}
   522→            disabled={step === 1 && !formData.name.trim()}
   523→            className="btn-accent flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed"
   524→          >
   525→            Next
   526→            <ArrowRight size={18} />
   527→          </button>
   528→        ) : (
   529→          <button
   530→            onClick={handleSubmit}
   531→            disabled={isLoading || !formData.name.trim()}
   532→            className="btn-accent flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed"
   533→          >
   534→            {isLoading ? (
   535→              <>
   536→                <Loader2 size={18} className="animate-spin" />
   537→                Creating...
   538→              </>
   539→            ) : (
   540→              <>
   541→                <Check size={18} />
   542→                Create Project
   543→              </>
   544→            )}
   545→          </button>
   546→        )}
   547→

   548→

   549→  )
   550→}
   551→

<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>

import { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { useProjectStore } from '../stores/projectStore'
import { ArrowLeft, ArrowRight, Check, Loader2, Plus, X } from 'lucide-react'

interface TechStack {
  frontend: string[]
  backend: string[]
  database: string[]
  other: string[]
}

interface DesignPreferences {
  theme: 'light' | 'dark' | 'system'
  primaryColor: string
  style: 'minimal' | 'modern' | 'classic'
  designMode: 'mvp' | 'finished'
}

export default function ProjectWizard() {
  const navigate = useNavigate()
  const { createProject, isLoading } = useProjectStore()
  const [step, setStep] = useState(1)
  const [formData, setFormData] = useState({
    name: '',
    description: '',
    complexity: 'medium',
    path: '',
  })
  const [techStack, setTechStack] = useState<TechStack>({
    frontend: [],
    backend: [],
    database: [],
    other: [],
  })
  const [features, setFeatures] = useState<string[]>([])
  const [newFeature, setNewFeature] = useState('')
  const [designPreferences, setDesignPreferences] = useState<DesignPreferences>({
    theme: 'dark',
    primaryColor: '#0d9488',
    style: 'modern',
    designMode: 'mvp',
  })
  const [errors, setErrors] = useState<{ name?: string }>({})
  const [touched, setTouched] = useState<{ name?: boolean }>({})

  const totalSteps = 5

  const validateName = (name: string): string | undefined => {
    if (!name.trim()) {
      return 'Project name is required'
    }
    if (name.trim().length < 2) {
      return 'Project name must be at least 2 characters'
    }
    if (name.trim().length > 100) {
      return 'Project name must be less than 100 characters'
    }
    return undefined
  }

  const handleNext = () => {
    if (step === 1) {
      const nameError = validateName(formData.name)
      setTouched({ ...touched, name: true })
      setErrors({ ...errors, name: nameError })
      if (nameError) return
    }
    if (step < totalSteps) {
      setStep(step + 1)
    }
  }

  const handleBack = () => {
    if (step > 1) {
      setStep(step - 1)
    }
  }

  const handleSubmit = async () => {
    try {
      await createProject({
        name: formData.name,
        description: formData.description,
        design_mode: designPreferences.designMode,
      })
      navigate('/')
    } catch (error) {
      console.error('Failed to create project:', error)
    }
  }

  return (

      {/* Progress */}

            Step {step} of {totalSteps}

            {Math.round((step / totalSteps) * 100)}% complete

          <div
            className="h-full bg-accent transition-all duration-300"
            style={{ width: `${(step / totalSteps) * 100}%` }}
          />

      {/* Step Content */}

        {step === 1 && (

Project Basics

                  Project Name *

                <input
                  id="project-name"
                  type="text"
                  value={formData.name}
                  onChange={(e) => {
                    const newName = e.target.value
                    setFormData({ ...formData, name: newName })
                    if (touched.name) {
                      setErrors({ ...errors, name: validateName(newName) })
                    }
                  }}
                  onBlur={() => {
                    setTouched({ ...touched, name: true })
                    setErrors({ ...errors, name: validateName(formData.name) })
                  }}
                  placeholder="My Awesome Project"
                  className={`w-full px-4 py-2 bg-slate-700 border rounded-lg focus:outline-none focus:ring-2 ${
                    touched.name && errors.name
                      ? 'border-red-500 focus:ring-red-500'
                      : 'border-slate-600 focus:ring-accent'
                  }`}
                />
                {touched.name && errors.name && (

{errors.name}

                )}

                  Description

                <textarea
                  id="project-description"
                  value={formData.description}
                  onChange={(e) =>
                    setFormData({ ...formData, description: e.target.value })
                  }
                  placeholder="A brief description of your project..."
                  rows={3}
                  className="w-full px-4 py-2 bg-slate-700 border border-slate-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-accent"
                />

        )}

        {step === 2 && (

Technology Stack

              {/* Frontend Technologies */}

                Frontend

                  {['React', 'Vue', 'Angular', 'Svelte', 'Next.js', 'HTML/CSS'].map((tech) => (
                    <button
                      key={tech}
                      onClick={() => {
                        const current = techStack.frontend
                        setTechStack({
                          ...techStack,
                          frontend: current.includes(tech)
                            ? current.filter((t) => t !== tech)
                            : [...current, tech],
                        })
                      }}
                      className={`px-3 py-1.5 rounded-lg border text-sm transition-colors ${
                        techStack.frontend.includes(tech)
                          ? 'border-accent bg-accent/20 text-accent'
                          : 'border-slate-600 hover:border-slate-500'
                      }`}
                    >
                      {tech}
                    </button>
                  ))}

              {/* Backend Technologies */}

                Backend

                  {['Python', 'Node.js', 'Go', 'Rust', 'Java', 'Ruby', 'PHP'].map((tech) => (
                    <button
                      key={tech}
                      onClick={() => {
                        const current = techStack.backend
                        setTechStack({
                          ...techStack,
                          backend: current.includes(tech)
                            ? current.filter((t) => t !== tech)
                            : [...current, tech],
                        })
                      }}
                      className={`px-3 py-1.5 rounded-lg border text-sm transition-colors ${
                        techStack.backend.includes(tech)
                          ? 'border-accent bg-accent/20 text-accent'
                          : 'border-slate-600 hover:border-slate-500'
                      }`}
                    >
                      {tech}
                    </button>
                  ))}

              {/* Database */}

                Database

                  {['PostgreSQL', 'MySQL', 'SQLite', 'MongoDB', 'Redis', 'Firebase'].map((tech) => (
                    <button
                      key={tech}
                      onClick={() => {
                        const current = techStack.database
                        setTechStack({
                          ...techStack,
                          database: current.includes(tech)
                            ? current.filter((t) => t !== tech)
                            : [...current, tech],
                        })
                      }}
                      className={`px-3 py-1.5 rounded-lg border text-sm transition-colors ${
                        techStack.database.includes(tech)
                          ? 'border-accent bg-accent/20 text-accent'
                          : 'border-slate-600 hover:border-slate-500'
                      }`}
                    >
                      {tech}
                    </button>
                  ))}

        )}

        {step === 3 && (

Features

              Add the main features you want your project to have.

              {/* Add feature input */}

                Add a feature
                <input
                  id="new-feature"
                  type="text"
                  value={newFeature}
                  onChange={(e) => setNewFeature(e.target.value)}
                  onKeyDown={(e) => {
                    if (e.key === 'Enter' && newFeature.trim()) {
                      setFeatures([...features, newFeature.trim()])
                      setNewFeature('')
                    }
                  }}
                  placeholder="Enter a feature..."
                  className="flex-1 px-4 py-2 bg-slate-700 border border-slate-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-accent"
                />
                <button
                  onClick={() => {
                    if (newFeature.trim()) {
                      setFeatures([...features, newFeature.trim()])
                      setNewFeature('')
                    }
                  }}
                  disabled={!newFeature.trim()}
                  className="btn-accent disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  <Plus size={18} />
                </button>

              {/* Feature list */}

                {features.length === 0 ? (

No features added yet

                ) : (
                  features.map((feature, index) => (

                      {feature}
                      <button
                        onClick={() => setFeatures(features.filter((_, i) => i !== index))}
                        className="text-slate-400 hover:text-destructive transition-colors"
                      >
                        <X size={16} />
                      </button>

                  ))
                )}

        )}

        {step === 4 && (

Design Preferences

              {/* Design Mode - MVP vs Finished */}

                Design Mode

                  Choose how strictly design requirements should be applied.

                  <button
                    onClick={() => setDesignPreferences({ ...designPreferences, designMode: 'mvp' })}
                    className={`w-full p-4 rounded-lg border text-left transition-colors ${
                      designPreferences.designMode === 'mvp'
                        ? 'border-accent bg-accent/10'
                        : 'border-slate-600 hover:border-slate-500'
                    }`}
                  >

MVP Mode

                      {designPreferences.designMode === 'mvp' && (
                        Selected
                      )}

                      Functional drafts are acceptable. Focus on getting features working first,
                      with polished design coming later. Best for rapid prototyping and early development.

                  </button>
                  <button
                    onClick={() => setDesignPreferences({ ...designPreferences, designMode: 'finished' })}
                    className={`w-full p-4 rounded-lg border text-left transition-colors ${
                      designPreferences.designMode === 'finished'
                        ? 'border-accent bg-accent/10'
                        : 'border-slate-600 hover:border-slate-500'
                    }`}
                  >

Finished Mode

                      {designPreferences.designMode === 'finished' && (
                        Selected
                      )}

                      Stricter design requirements apply. All frontend work must meet polish standards
                      with proper typography, color, motion, and spatial composition. Best for production-ready builds.

                  </button>

              {/* Theme */}

                Theme

                  {(['light', 'dark', 'system'] as const).map((theme) => (
                    <button
                      key={theme}
                      onClick={() => setDesignPreferences({ ...designPreferences, theme })}
                      className={`flex-1 p-3 rounded-lg border text-center capitalize transition-colors ${
                        designPreferences.theme === theme
                          ? 'border-accent bg-accent/10'
                          : 'border-slate-600 hover:border-slate-500'
                      }`}
                    >
                      {theme}
                    </button>
                  ))}

              {/* Style */}

                UI Style

                  {(['minimal', 'modern', 'classic'] as const).map((style) => (
                    <button
                      key={style}
                      onClick={() => setDesignPreferences({ ...designPreferences, style })}
                      className={`w-full p-3 rounded-lg border text-left transition-colors ${
                        designPreferences.style === style
                          ? 'border-accent bg-accent/10'
                          : 'border-slate-600 hover:border-slate-500'
                      }`}
                    >

{style}

                        {style === 'minimal' && 'Clean and simple design'}
                        {style === 'modern' && 'Contemporary with subtle effects'}
                        {style === 'classic' && 'Traditional and familiar layout'}

                    </button>
                  ))}

              {/* Primary Color */}

                Primary Color

                  {['#0d9488', '#3b82f6', '#8b5cf6', '#ef4444', '#f59e0b'].map((color) => (
                    <button
                      key={color}
                      onClick={() => setDesignPreferences({ ...designPreferences, primaryColor: color })}
                      className={`w-10 h-10 rounded-lg border-2 transition-transform ${
                        designPreferences.primaryColor === color
                          ? 'border-white scale-110'
                          : 'border-transparent hover:scale-105'
                      }`}
                      style={{ backgroundColor: color }}
                    />
                  ))}

        )}

        {step === 5 && (

Review & Create

              {/* Project Basics */}

Project Name

{formData.name || 'Not set'}

Description

                  {formData.description || 'No description'}

              {/* Technology Stack */}

Technology Stack

                  {techStack.frontend.length > 0 && (

Frontend: {techStack.frontend.join(', ')}

                  )}
                  {techStack.backend.length > 0 && (

Backend: {techStack.backend.join(', ')}

                  )}
                  {techStack.database.length > 0 && (

Database: {techStack.database.join(', ')}

                  )}
                  {techStack.frontend.length === 0 && techStack.backend.length === 0 && techStack.database.length === 0 && (

No technologies selected

                  )}

              {/* Features */}

Features

                {features.length > 0 ? (

                    {features.map((feature, i) => (

{feature}

                    ))}

                ) : (

No features added

                )}

              {/* Design Preferences */}

Design Preferences

                    Design Mode:{' '}

                      {designPreferences.designMode === 'mvp' ? 'MVP (Functional Drafts)' : 'Finished (Polished)'}

Theme: {designPreferences.theme}

Style: {designPreferences.style}

                    Primary Color:

        )}

      {/* Navigation */}

        <button
          onClick={step === 1 ? () => navigate('/') : handleBack}
          className="btn-secondary flex items-center gap-2"
        >
          <ArrowLeft size={18} />
          {step === 1 ? 'Cancel' : 'Back'}
        </button>

        {step < totalSteps ? (
          <button
            onClick={handleNext}
            disabled={step === 1 && !formData.name.trim()}
            className="btn-accent flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed"
          >
            Next
            <ArrowRight size={18} />
          </button>
        ) : (
          <button
            onClick={handleSubmit}
            disabled={isLoading || !formData.name.trim()}
            className="btn-accent flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed"
          >
            {isLoading ? (
              <>
                <Loader2 size={18} className="animate-spin" />
                Creating...
              </>
            ) : (
              <>
                <Check size={18} />
                Create Project
              </>
            )}
          </button>
        )}

  )
}


1→import { useState } from 'react'
     2→import { useAgentStore } from '../stores/agentStore'
     3→import { Play, Square, Maximize2 } from 'lucide-react'
     4→
     5→export default function AgentTerminals() {
     6→  const { activeSessions, stopAgent } = useAgentStore()
     7→  const [selectedTerminal, setSelectedTerminal] = useState<number | null>(null)
     8→
     9→  const handleStop = async (sessionId: number) => {
    10→    try {
    11→      await stopAgent(sessionId)
    12→    } catch (error) {
    13→      console.error('Failed to stop agent:', error)
    14→    }
    15→  }
    16→
    17→  return (
    18→

    19→      {/* Header */}
    20→

    21→
Agent Terminals

    22→

    23→
    24→            {activeSessions.filter((s) => s.status === 'running').length} active
    25→
    26→

    27→

    28→
    29→      {/* Terminal Grid */}
    30→      {activeSessions.length === 0 ? (
    31→

    32→

    33→            <Play size={48} className="text-slate-600 mx-auto mb-4" />
    34→

    35→              No Active Agents
    36→

    37→

    38→              Start an agent from the Kanban board to see terminal output here.
    39→

    40→

    41→

    42→      ) : (
    43→

    44→          {activeSessions.map((session) => (
    45→

    51→              {/* Terminal Header */}
    52→

    53→

    54→                  <div
    55→                    className={`w-2 h-2 rounded-full ${
    56→                      session.status === 'running'
    57→                        ? 'bg-accent animate-pulse'
    58→                        : session.status === 'completed'
    59→                        ? 'bg-green-400'
    60→                        : session.status === 'failed'
    61→                        ? 'bg-error'
    62→                        : 'bg-slate-500'
    63→                    }`}
    64→                  />
    65→
    66→                    {session.agent_type.replace('_', ' ')}
    67→
    68→

    69→

    70→                  {session.status === 'running' && (
    71→                    <button
    72→                      onClick={() => handleStop(session.id)}
    73→                      className="p-1 hover:bg-slate-700 rounded"
    74→                      title="Stop agent"
    75→                    >
    76→                      <Square size={14} className="text-error" />
    77→                    </button>
    78→                  )}
    79→                  <button
    80→                    onClick={() =>
    81→                      setSelectedTerminal(
    82→                        selectedTerminal === session.id ? null : session.id
    83→                      )
    84→                    }
    85→                    className="p-1 hover:bg-slate-700 rounded"
    86→                    title="Expand"
    87→                  >
    88→                    <Maximize2 size={14} />
    89→                  </button>
    90→

    91→

    92→
    93→              {/* Terminal Content */}
    94→

    95→

    96→                  [Session {session.id}] Started at{' '}
    97→                  {new Date(session.started_at).toLocaleTimeString()}
    98→

    99→

   100→                  Agent type: {session.agent_type}
   101→

   102→

   103→                  Status: {session.status}
   104→

   105→

   106→                  Iterations: {session.iterations}
   107→

   108→                {session.status === 'running' && (
   109→

   110→                    Processing...
   111→

   112→                )}
   113→

   114→

   115→          ))}
   116→

   117→      )}
   118→

   119→  )
   120→}
   121→

<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>

import { useState } from 'react'
import { useAgentStore } from '../stores/agentStore'
import { Play, Square, Maximize2 } from 'lucide-react'

export default function AgentTerminals() {
  const { activeSessions, stopAgent } = useAgentStore()
  const [selectedTerminal, setSelectedTerminal] = useState<number | null>(null)

  const handleStop = async (sessionId: number) => {
    try {
      await stopAgent(sessionId)
    } catch (error) {
      console.error('Failed to stop agent:', error)
    }
  }

  return (

      {/* Header */}

Agent Terminals

            {activeSessions.filter((s) => s.status === 'running').length} active

      {/* Terminal Grid */}
      {activeSessions.length === 0 ? (

            <Play size={48} className="text-slate-600 mx-auto mb-4" />

              No Active Agents

              Start an agent from the Kanban board to see terminal output here.

      ) : (

          {activeSessions.map((session) => (

              {/* Terminal Header */}

                    {session.agent_type.replace('_', ' ')}

                  {session.status === 'running' && (
                    <button
                      onClick={() => handleStop(session.id)}
                      className="p-1 hover:bg-slate-700 rounded"
                      title="Stop agent"
                    >
                      <Square size={14} className="text-error" />
                    </button>
                  )}
                  <button
                    onClick={() =>
                      setSelectedTerminal(
                        selectedTerminal === session.id ? null : session.id
                      )
                    }
                    className="p-1 hover:bg-slate-700 rounded"
                    title="Expand"
                  >
                    <Maximize2 size={14} />
                  </button>

              {/* Terminal Content */}

                  [Session {session.id}] Started at{' '}
                  {new Date(session.started_at).toLocaleTimeString()}

                  Agent type: {session.agent_type}

                  Status: {session.status}

                  Iterations: {session.iterations}

                {session.status === 'running' && (

                    Processing...

                )}

          ))}

      )}

  )
}


Now I have a comprehensive understanding of all the pages that need theme updates. Let me update them all to use CSS variable-based classes instead of hardcoded slate colors. I'll start with Dashboard.tsx:


TodoWrite

Update Dashboard.tsx theme colors

Update KanbanBoard.tsx theme colors

Update MemoryManager.tsx theme colors

Update InfrastructureConfig.tsx theme colors

Updating InfrastructureConfig.tsx theme colors

Update ProjectWizard.tsx theme colors

Update AgentTerminals.tsx theme colors

Updating AgentTerminals.tsx theme colors

Verify light theme in browser


Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable

Update Dashboard.tsx theme colors

Update KanbanBoard.tsx theme colors

Update MemoryManager.tsx theme colors

Update InfrastructureConfig.tsx theme colors

Updating InfrastructureConfig.tsx theme colors

Update ProjectWizard.tsx theme colors

Update AgentTerminals.tsx theme colors

Updating AgentTerminals.tsx theme colors

Verify light theme in browser


Edit

if (!currentProject) {
    return (

        <FolderOpen size={64} className="text-slate-600 mb-4" />

          No Project Selected

          Select a project from the sidebar or create a new one to get started.

    )
  }

if (!currentProject) {
    return (

        <FolderOpen size={64} className="text-muted-foreground mb-4" />

          No Project Selected

          Select a project from the sidebar or create a new one to get started.

    )
  }