ELNOR REPO READER TEXT MIRROR Original path: Design Mockups/Archived Mockups/DOC20 Mockups and Design/DOC20 Archived Mockups/Q_UNIFIED_WORKSPACE_V7_1_ALT_B.jsx Source repo: /Users/OpenClaw1/Elnor/Elnor Specs Git branch: main Git commit: dbaa25962edc11ab30e8d4ca1715f9ae5bf77331 Generated: 2026-06-09T01:23:58.539Z --- import { useState, useRef, useEffect, useMemo, useCallback } from "react"; const font={sans:"'DM Sans','Helvetica Neue',-apple-system,BlinkMacSystemFont,sans-serif"}; const R={sm:"6px",md:"10px",full:"9999px"}; const c={bgApp:"#F8F8F6",bgPanel:"#FFFFFF",bgPanelAlt:"#F9FAFB",bgCard:"#FFFFFF",bgInput:"#EFF1F3",bgSidebar:"#131820",textPri:"#1A1D21",textSec:"#5E6570",textTer:"#8B919A",accentBtn:"#31588c",warn:"#D97706",error:"#B04040",border:"#E0E2E5",borderLight:"#ECEEF0",green:"#2E8B57",neutral:"#6B7280",agentAv:"#a1a7aa",borderDark:"#263040",purple:"#7C3AED",incBg:"#2A1F3D",incBorder:"#3d2e5c",incText:"#a78bfa"}; const Ic=({d,size=18,color,sw=1.75})=>; const I={Search:p=>,Plus:p=>,ChevR:p=>,ChevD:p=>,Pin:p=>,Folder:p=>,File:p=>,X:p=>,Check:p=>,Save:p=>,Trash:p=>,Copy:p=>,Link:p=>,Maximize:p=>,Spark:p=>,MsgCircle:p=>,Undo:p=>,Redo:p=>,Eye:p=>,Edit:p=>,FileText:p=>,ExtLink:p=>,Printer:p=>,Clock:p=>,ArrowL:p=>,ArrowR:p=>,Refresh:p=>,Star:p=>,Lock:p=>,Book:p=>,Scissors:p=>,Globe:p=>,Home:p=>,Settings:p=>,Inbox:p=>,Grid:p=>,Download:p=>,List:p=>,Bell:p=>,Zap:p=>,Sun:p=>,Mail:p=>,Calendar:p=>,Mask:p=>,Grip:p=>,Archive:p=>,Sidebar:p=>,Paperclip:p=>,Compass:p=>,Users:p=>,User:p=>,Database:p=>,Layers:p=>}; const Dot=({color,size=8})=>; const Toast=({msg,onDone})=>{useEffect(()=>{const t=setTimeout(onDone,2200);return()=>clearTimeout(t)},[onDone]);return
{msg}
}; const TBtn=({icon,title,active,onClick,label,dropdown})=>; const Sep=()=>
; const Btn=({children,primary,ghost,small,onClick,disabled,style:s})=>; const Av=({letter,color,size=20})=>
{letter}
; const DItem=({children,onClick,active,disabled})=>; const Radio=({selected,label,desc,onClick,disabled})=>; const DragHandle=()=>
e.currentTarget.style.opacity=0.55} onMouseLeave={e=>e.currentTarget.style.opacity=0.18}>
; // ═══ DATA ═══ const agentName="Elnor"; // Default from settings — all UI uses agent.name dynamically const agents=[{name:"Elnor",color:c.agentAv,letter:"E"},{name:"Scout",color:"#5B5F97",letter:"S"}]; const chats=[{name:"Paramount damages",color:c.accentBtn,origin:true},{name:"Brooge causation",color:c.green},{name:"New chat",color:c.textTer}]; const typeColors={Note:c.accentBtn,Chat:c.green,Doc:c.textTer,Task:c.warn,Artifact:"#8B5CF6",Prompt:"#D97706",Preset:c.neutral,Skill:c.neutral,Agent:"#5B5F97",Overlay:"#9333EA",Template:"#0891B2",Chain:"#DC2626",Memory:c.green,Room:"#6366F1",Bookmark:c.warn}; const projects=[{id:1,name:"Paramount v. City of LA",color:"#31588c"},{id:2,name:"White v. Brooge Energy",color:"#2E8B57"},{id:3,name:"Internal Ops",color:"#8B7355"}]; const collections=[{name:"Priority",color:"#B04040"},{name:"Research",color:"#2E8B57"},{name:"Draft",color:"#D97706"},{name:"Archive",color:"#6B7280"},{name:"Urgent",color:"#9E5E5E"},{name:"Reference",color:"#5B5F97"}]; const scopeFams=["Collection","Project","Bucket","Places","Folders","Saved Views"]; const typeChips=["Document","Chat","Preset","Skill","Task","Agent","Overlay","Note","Artifact","Prompt","Template","Chain","Memory","Room","Bookmark","Panel","Forum"]; const sortOptions=["Modified","Alphabetical","Type","Created","Running"]; const savedViews=[{id:"sv1",name:"Current",sys:true},{id:"sv2",name:"Recent",sys:true},{id:"sv3",name:"No Project",sys:true}]; const tabColors={note:"#31588c",doc:"#2E8B57",web:"#D97706",clips:"#7C3AED",chat:"#2E8B57",room:"#6366F1",task:"#D97706",utility:c.neutral}; const groupColors=["#EF4444","#F97316","#22C55E","#3B82F6","#8B5CF6","#6B7280"]; const recentConvos=[{id:"cv1",name:"Paramount damages strategy",color:c.accentBtn,time:"1h",starred:true},{id:"cv2",name:"Brooge loss causation",color:c.green,time:"3h",starred:true},{id:"cv3",name:"Expert depo prep",color:c.warn,time:"1d"},{id:"cv4",name:"Trial brief §III draft",color:c.accentBtn,time:"1d"},{id:"cv5",name:"Signage rights research",color:"#5B5F97",time:"2d"},{id:"cv6",name:"Patent landscape scan",color:c.green,time:"3d"}]; const navPages=[{id:"tasks",icon:,label:"Tasks"},{id:"projects",icon:,label:"Projects"},{id:"knowledge",icon:,label:"Knowledge Manager"},{id:"forums",icon:,label:"Forums & Panels"},{id:"agents",icon:,label:"Agents"},{id:"skills",icon:,label:"Skills & Connectors"},{id:"overlays",icon:,label:"Overlays & Prompts"},{id:"buckets",icon:,label:"Context Buckets"},{id:"settings",icon:,label:"Settings"}]; const feedPresets=[{id:"fp1",name:"System Activity",icon:"spark",desc:"Agent completions, memory updates",category:"system"},{id:"fp2",name:"System Notices",icon:"bell",desc:"Errors, warnings, sync issues",category:"system"},{id:"fp3",name:"Gate Approvals",icon:"check",desc:"Pending chain gates",category:"system"},{id:"fp4",name:"Active Operations",icon:"zap",desc:"Running agents and tasks",category:"system"},{id:"fp5",name:"Morning Summary",icon:"sun",desc:"Daily briefing — priorities",category:"agent"},{id:"fp6",name:"Email Watch",icon:"mail",desc:"Flag important emails",category:"agent"},{id:"fp7",name:"Deadline Tracker",icon:"calendar",desc:"Calendar deadlines",category:"agent"}]; const feedIcons={spark:,bell:,check:,zap:,sun:,mail:,calendar:}; const initPlaces=[{id:"p1",title:"Paramount Case Files",path:"~/OneDrive-schallfirm/Paramount",status:"ok"},{id:"p2",title:"Firm Templates",path:"~/OneDrive-schallfirm/Templates",status:"ok"},{id:"p3",title:"Local Research",path:"~/Documents/Research",status:"ok"},{id:"p4",title:"Archived Cases",path:"/Volumes/External/Cases",status:"missing"}]; const placeContents={root:[{name:"Expert_Reports",isFolder:true},{name:"Exhibits",isFolder:true},{name:"Paramount_Complaint.pdf",type:"PDF",size:"2.4 MB",mod:"1d"},{name:"Privilege_Log_v4.docx",type:"DOCX",size:"340 KB",mod:"3h"}],Expert_Reports:[{name:"Sanli_Report.pdf",type:"PDF",size:"1.2 MB",mod:"1w"},{name:"Christensen_CV.pdf",type:"PDF",size:"890 KB",mod:"2w"}],Exhibits:[{name:"Exhibit_A.pdf",type:"PDF",size:"3.1 MB",mod:"3d"}]}; const allItems=[{type:"Note",title:"Today — April 4, 2026",time:"2h",pin:true,proj:1,cols:["Priority"]},{type:"Note",title:"Trial Prep Checklist",time:"4h",pin:true,proj:1,cols:[]},{type:"Doc",title:"Sanli Expert Report.pdf",time:"10m",proj:1,cols:["Priority"]},{type:"Artifact",title:"Motion in Limine No. 3",time:"1d",proj:1,cols:[]},{type:"Doc",title:"Christensen_CV.pdf",time:"1d",proj:1,cols:["Reference"]},{type:"Note",title:"Brooge Loss Causation",time:"1d",proj:2,cols:["Research"]},{type:"Task",title:"Review Sanli depo",time:"2h",proj:1,st:"running",cols:[]},{type:"Chat",title:"Paramount damages",time:"1h",proj:1,cols:["Priority"]},{type:"Artifact",title:"Fair Fund — Brooge",time:"2h",proj:2,cols:[]},{type:"Doc",title:"BC587659_MIL_3.pdf",time:"2d",proj:1,cols:[]},{type:"Task",title:"Draft trial brief §III",time:"4h",proj:1,st:"waiting",cols:["Priority"]},{type:"Prompt",title:"Expert Analysis Template",time:"1w",proj:null,cols:[]},{type:"Preset",title:"Legal Brief Review",time:"1w",proj:null,cols:[]},{type:"Doc",title:"Standing_Orders.md",time:"3d",proj:null,cols:["Reference"]}]; const timeVal=t=>{if(t.includes("m"))return parseInt(t);if(t.includes("h"))return parseInt(t)*60;if(t.includes("d"))return parseInt(t)*1440;if(t.includes("w"))return parseInt(t)*10080;return 99999}; const initTabs=[{id:"t1",type:"note",icon:"📝",title:"Today — April 4, 2026",color:tabColors.note,group:"g1"},{id:"t2",type:"doc",icon:"📄",title:"Sanli Expert Report.pdf",color:tabColors.doc},{id:"t3",type:"web",icon:"🌐",title:"Paramount MIL — PACER",color:tabColors.web,group:"g1"},{id:"t4",type:"clips",icon:"✂️",title:"Clips: 4.4-1",color:tabColors.clips},{id:"t5",type:"chat",icon:"💬",title:"Paramount damages",color:tabColors.chat}]; const initGroups=[{id:"g1",label:"Paramount Research",color:"#22C55E",collapsed:false}]; const initComments=[{id:"c1",author:"You",color:c.accentBtn,body:"Verify Sanli's discount rate — 18% seems unsupported.",time:"10m ago",status:"open",anchor:"discount rate of 18%",replies:[{id:"r1",author:agentName,color:c.agentAv,body:"Found 3 comparables: avg 8-12%. Sanli's 18% is an outlier.",time:"5m ago"}]},{id:"c2",author:"You",color:c.accentBtn,body:"Cross-ref with Christensen methodology.",time:"8m ago",status:"open",anchor:"willing buyer-willing seller",replies:[]},{id:"c3",author:agentName,color:c.agentAv,body:"Sargon gatekeeper standard briefed in §II.",time:"6m ago",status:"resolved",anchor:"Legal Standard",replies:[]}]; const tcColors={You:{del:c.accentBtn,ins:c.accentBtn},Agent:{del:"#B04040",ins:"#2E8B57"}}; const initChanges=[{id:"tc1",segId:"s4",author:"Agent",oldText:"discussing litigation posture",newText:"discussing litigation posture and insurance coverage",status:"pending"},{id:"tc2",segId:"s7",author:"You",oldText:"Prepare updated privilege log",newText:"Prepare updated privilege log with Bates-stamp cross-refs",status:"pending"}]; const noteSegs=[{id:"s1",t:"p",v:"Trial May 4 — 30 days out. Focus items for today."},{id:"s2",t:"h2",v:"Expert Motions"},{id:"s3",t:"p",v:"Finalize MIL No. 3 — Sanli discount rate argument."},{id:"s4",t:"p",v:"Cross-reference discussing litigation posture with Christensen opinions."},{id:"s7",t:"h2",v:"Next Steps"},{id:"s8",t:"p",v:"Prepare updated privilege log with all newly identified documents."}]; const initBlocks=[{id:"b2",type:"tasks",title:"To Do",collapsed:false,tasks:[{id:"t1",text:"Finalize MIL No. 3 re: Sanli",done:false,due:"Apr 7",sub:[{id:"s1",text:"Pull Sanli discount rate comparables",done:true},{id:"s2",text:"Draft Sargon gatekeeper argument",done:false}]},{id:"t2",text:"Review Christensen engagement",done:true,due:"Apr 3",sub:[]},{id:"t3",text:"Prep Sanli depo cross-exam",done:false,due:"Apr 10",sub:[]},{id:"t4",text:"File trial exhibit list",done:true,due:"Apr 1",sub:[]}]},{id:"b3",type:"thread",collapsed:false,contextQuote:"Sanli discount rate",messages:[{id:"m1",author:"You",color:c.accentBtn,body:"@Agent find comparable signage transactions with discount rates",time:"45m"},{id:"m2",author:"Agent",color:c.agentAv,body:"Found 3 comparables: avg 8-12%. Sanli's 18% is unsupported. See attached analysis.",time:"40m"}]},{id:"b5",type:"feed",title:"Activity Brief",collapsed:false,sections:[{key:"elnor",icon:"spark",label:"Agent",items:[{text:"Reviewed 3 depo transcripts — flagged 2 issues",time:"5h"},{text:"Updated patent landscape — 4 new filings",time:"4h"}]},{key:"system",icon:"bell",label:"System",items:[{text:"OneDrive sync paused — re-auth needed",time:"6h",accent:c.warn}]}]}]; const initNoteFolders=[{id:"nf1",title:"Case Notes",parent:null},{id:"nf2",title:"Paramount",parent:"nf1"},{id:"nf3",title:"Brooge",parent:"nf1"},{id:"nf4",title:"Session Notes",parent:null}]; const initNotes=[{id:"n1",title:"Today — April 4, 2026",mod:"2h",pinned:true,folder:"nf2",comments:2},{id:"n2",title:"Trial Prep Checklist",mod:"4h",pinned:true,folder:"nf2",comments:0},{id:"n3",title:"Danny Christensen",mod:"3d",folder:"nf2",comments:1},{id:"n4",title:"Brooge Loss Causation",mod:"1d",folder:"nf3",comments:0},{id:"n5",title:"Clips: 4.4-1",mod:"2h",folder:"nf4",comments:0}]; const initBrowserFolders=[{id:"f1",title:"Paramount Case",parent:null},{id:"f2",title:"Expert Reports",parent:"f1"},{id:"f3",title:"Motion Practice",parent:"f1"},{id:"f4",title:"Brooge Research",parent:null}]; const initBookmarks=[ {id:"bm1",title:"Legal Research",parent:null,items:[{id:"bi1",title:"PACER — CACD",url:"pacer.uscourts.gov",color:"#1a5276"},{id:"bi2",title:"Westlaw",url:"westlaw.com",color:"#8B0000"},{id:"bi3",title:"CM/ECF Login",url:"ecf.cacd.uscourts.gov",color:"#2c3e50"},{id:"bi4",title:"EDGAR Full-Text",url:"sec.gov",color:"#1B4F72"}]}, {id:"bm2",title:"Clients",parent:null,items:[{id:"bi5",title:"Paramount SharePoint",url:"schallfirm.sharepoint.com",color:"#0078d4"},{id:"bi6",title:"Brooge Portal",url:"brooge.com",color:"#2E8B57"}]}, {id:"bm3",title:"Reference",parent:null,items:[{id:"bi7",title:"Cal. Rules of Court",url:"courts.ca.gov",color:"#8B7355"},{id:"bi8",title:"LAMC Full Text",url:"codelibrary.amlegal.com",color:"#6B7280"}]}, {id:"bm4",title:"Daily",parent:"bm1",items:[{id:"bi9",title:"Bloomberg Law",url:"bloomberglaw.com",color:"#000"}]} ]; export default function UnifiedWorkspaceV4(){ const idC=useRef(500);const nid=()=>"x"+(++idC.current); const [tabs,setTabs]=useState(initTabs);const [tabGroups,setTabGroups]=useState(initGroups); const [activeTabId,setActiveTabId]=useState("t1");const [selectedTabs,setSelectedTabs]=useState(new Set()); const [tabContextMenu,setTabContextMenu]=useState(null);const [newTabDrop,setNewTabDrop]=useState(false); const [dragTabId,setDragTabId]=useState(null);const [groupCtx,setGroupCtx]=useState(null); const [savedGroupsList,setSavedGroupsList]=useState([]);const [savedGroupsDrop,setSavedGroupsDrop]=useState(false); // Browser const [browserOpen,setBrowserOpen]=useState(true);const [browserWidth,setBrowserWidth]=useState(280); const [browserMode,setBrowserMode]=useState("browser"); const [activeScope,setActiveScope]=useState(null);const [activeProjIdx,setActiveProjIdx]=useState(0);const [noProject,setNoProject]=useState(false); const [activeTypes,setActiveTypes]=useState(new Set());const [selectedCollections,setSelectedCollections]=useState(new Set()); const [splitterPos,setSplitterPos]=useState(150);const [selectedIdx,setSelectedIdx]=useState(null); const [browserFolders,setBrowserFolders]=useState(initBrowserFolders);const [expandedFolders,setExpandedFolders]=useState(new Set(["f1"])); const [activeFolder,setActiveFolder]=useState(null);const [hoverFolder,setHoverFolder]=useState(null); const [newFolderMode,setNewFolderMode]=useState(null);const [newFolderName,setNewFolderName]=useState(""); const [deletingFolder,setDeletingFolder]=useState(null); const [searchMode,setSearchMode]=useState("this_view");const [sortKey,setSortKey]=useState("Modified");const [sortDrop,setSortDrop]=useState(false); const [folderOverlay,setFolderOverlay]=useState(false);const [dropTarget,setDropTarget]=useState(null);const [dragItem,setDragItem]=useState(null); const [places,setPlaces]=useState(initPlaces);const [activePlace,setActivePlace]=useState(null);const [placePath,setPlacePath]=useState([]); const [hoverPlace,setHoverPlace]=useState(null);const [removingPlace,setRemovingPlace]=useState(null); const [activeSavedView,setActiveSavedView]=useState(null);const [userSavedViews,setUserSavedViews]=useState([]); const [saveFromBar,setSaveFromBar]=useState(false);const [saveViewName,setSaveViewName]=useState(""); // Notes browser const [noteFolders,setNoteFolders]=useState(initNoteFolders);const [noteExpandedFolders,setNoteExpandedFolders]=useState(new Set(["nf1"])); const [notes]=useState(initNotes);const [selectedNote,setSelectedNote]=useState("n1"); const [noteSearch,setNoteSearch]=useState("");const [noteSort,setNoteSort]=useState("Modified");const [noteSortDrop,setNoteSortDrop]=useState(false); const [allNotesSort,setAllNotesSort]=useState("Modified");const [allNotesSortDrop,setAllNotesSortDrop]=useState(false); const [noteNewFolderMode,setNoteNewFolderMode]=useState(null);const [noteNewFolderName,setNoteNewFolderName]=useState(""); const [noteHoverFolder,setNoteHoverFolder]=useState(null); const [renamingNoteFolder,setRenamingNoteFolder]=useState(null);const [renamingNoteFolderText,setRenamingNoteFolderText]=useState(""); const [deletingNoteFolder,setDeletingNoteFolder]=useState(null); const [showArchived,setShowArchived]=useState(false); const [noteContextMenu,setNoteContextMenu]=useState(null); // Bookmarks const [bmExpanded,setBmExpanded]=useState(new Set(["bm1"])); const [bmFolders,setBmFolders]=useState(initBookmarks); const [bmHoverFolder,setBmHoverFolder]=useState(null);const [bmHoverItem,setBmHoverItem]=useState(null); const [bmRenamingFolder,setBmRenamingFolder]=useState(null);const [bmRenamingText,setBmRenamingText]=useState(""); const [bmDeletingFolder,setBmDeletingFolder]=useState(null); const [bmNewFolderMode,setBmNewFolderMode]=useState(null);const [bmNewFolderName,setBmNewFolderName]=useState(""); const [bmRenamingItem,setBmRenamingItem]=useState(null);const [bmRenamingItemText,setBmRenamingItemText]=useState(""); const [bmSearch,setBmSearch]=useState(""); // Right panel const [rightOpen,setRightOpen]=useState(false);const [rightTab,setRightTab]=useState("comments");const [rightWidth,setRightWidth]=useState(290); const [comments,setComments]=useState(initComments);const [activeComment,setActiveComment]=useState(null); const [replyingTo,setReplyingTo]=useState(null);const [replyText,setReplyText]=useState(""); const [editingId,setEditingId]=useState(null);const [editText,setEditText]=useState("");const [deletingId,setDeletingId]=useState(null); const [newCm,setNewCm]=useState(null);const [newCmText,setNewCmText]=useState(""); // Send to Agent const [agentIdx,setAgentIdx]=useState(0);const [agentDrop,setAgentDrop]=useState(false); const [chatIdx,setChatIdx]=useState(0);const [chatDrop,setChatDrop]=useState(false); const [sendScope,setSendScope]=useState("full");const [selectedCmIds,setSelectedCmIds]=useState(new Set()); const [outputMode,setOutputMode]=useState("respond_in_chat");const [subMode,setSubMode]=useState("tracked_changes");const [instruction,setInstruction]=useState(""); // Content const [showMarkup,setShowMarkup]=useState(true);const [findBar,setFindBar]=useState(false); const [pinned,setPinned]=useState(false);const [bookmarked,setBookmarked]=useState(false);const [readerMode,setReaderMode]=useState(false); const [openDrop,setOpenDrop]=useState(null);const [bubbleMenu,setBubbleMenu]=useState(null); const [changes,setChanges]=useState(initChanges); // Blocks (from V5.2) const [blocks,setBlocks]=useState(initBlocks);const [expandedTask,setExpandedTask]=useState(null); const [threadReplyId,setThreadReplyId]=useState(null);const [threadReplyText,setThreadReplyText]=useState(""); const [newTaskText,setNewTaskText]=useState("");const [newSubText,setNewSubText]=useState({}); const [collapsedFeeds,setCollapsedFeeds]=useState(new Set());const [editingTitle,setEditingTitle]=useState(null); const [pickerOpen,setPickerOpen]=useState(false);const [pickerStep,setPickerStep]=useState("choose");const [pickerTab,setPickerTab]=useState("system"); const [customName,setCustomName]=useState("");const [customInstruction,setCustomInstruction]=useState("");const [insertionPoint,setInsertionPoint]=useState(null); const [showDownloads,setShowDownloads]=useState(false); const [chatColumnOpen,setChatColumnOpen]=useState(false); const [agentResponse,setAgentResponse]=useState(null); const [sessionMinutes,setSessionMinutes]=useState(47);const [clipsCount,setClipsCount]=useState(2); const [toast,setToast]=useState(null); const editorRef=useRef(null);const cmRef=useRef(null);const nfRef=useRef(null); const flash=msg=>setToast(msg);const agent=agents[agentIdx]; const activeTab=tabs.find(t=>t.id===activeTabId)||tabs[0]; const openC=comments.filter(x=>x.status==="open");const resolvedC=comments.filter(x=>x.status==="resolved"); const isNoteType=activeTab.type==="note"||activeTab.type==="clips"; const pendingChanges=changes.filter(x=>x.status==="pending"); useEffect(()=>{const iv=setInterval(()=>setSessionMinutes(m=>m+1),60000);return()=>clearInterval(iv)},[]); useEffect(()=>{if(activeTab.type==="note"||activeTab.type==="clips")setBrowserMode("notes");else if(activeTab.type==="web")setBrowserMode("bookmarks");else if(activeTab.type==="chat"||activeTab.type==="utility")setBrowserMode("nav");else setBrowserMode("browser")},[activeTabId]); // Reset right panel on tab switch useEffect(()=>{setActiveComment(null);setReplyingTo(null);setEditingId(null);setNewCm(null);setNewCmText("");setAgentResponse(null)},[activeTabId]); // Auto-close transient utility tab when switching away useEffect(()=>{const prev=tabs.find(t=>t.type==="utility"&&!t.pinned&&t.id!==activeTabId);if(prev&&activeTab.type!=="utility")setTabs(p=>p.filter(t=>t.id!==prev.id))},[activeTabId]); // Open tab with duplicate prevention + transient handling const openTab=(type,title,icon,extra={})=>{ const existing=tabs.find(t=>t.title===title&&t.type===type); if(existing){setActiveTabId(existing.id);flash("Already open — switched to tab");return} if(type==="utility"){const old=tabs.find(t=>t.type==="utility"&&!t.pinned);if(old)setTabs(p=>p.filter(t=>t.id!==old.id))} const id="t"+Date.now();const newTab={id,type,icon,title,color:tabColors[type]||c.neutral,...extra}; if(type==="utility"){setTabs(p=>[newTab,...p])}else{setTabs(p=>[...p,newTab])} setActiveTabId(id);setNewTabDrop(false)}; // Helpers const toggleType=t=>{const s=new Set(activeTypes);s.has(t)?s.delete(t):s.add(t);setActiveTypes(s)}; const toggleCollection=n=>{const s=new Set(selectedCollections);s.has(n)?s.delete(n):s.add(n);setSelectedCollections(s)}; const toggleFolder=id=>{const s=new Set(expandedFolders);s.has(id)?s.delete(id):s.add(id);setExpandedFolders(s)}; const selectScope=s=>{if(activeScope===s){setActiveScope(null);setActiveFolder(null);setActivePlace(null);setPlacePath([])}else{setActiveScope(s);setActiveFolder(null);setActivePlace(null);setPlacePath([])}}; const toggleCmSelect=id=>{const s=new Set(selectedCmIds);s.has(id)?s.delete(id):s.add(id);setSelectedCmIds(s)}; const createBrowserFolder=parent=>{if(!newFolderName.trim())return;setBrowserFolders(p=>[...p,{id:"f"+(p.length+10),title:newFolderName.trim(),parent}]);setNewFolderMode(null);setNewFolderName("");flash("Folder created")}; const deleteBrowserFolder=id=>{setBrowserFolders(p=>p.filter(f=>f.id!==id&&f.parent!==id));setDeletingFolder(null);flash("Folder deleted")}; const removePlace=id=>{setPlaces(p=>p.filter(x=>x.id!==id));setRemovingPlace(null);flash("Place removed")}; const currentPlaceFiles=()=>{const key=placePath.length?placePath[placePath.length-1]:"root";return placeContents[key]||[{name:"(empty)",dimmed:true,type:"—",size:"—",mod:"—"}]}; const createNoteFolder=parent=>{if(!noteNewFolderName.trim())return;setNoteFolders(p=>[...p,{id:"nf"+(p.length+10),title:noteNewFolderName.trim(),parent}]);setNoteNewFolderMode(null);setNoteNewFolderName("");flash("Folder created")}; const renameNoteFolder=(id,name)=>{if(!name.trim())return;setNoteFolders(p=>p.map(f=>f.id===id?{...f,title:name.trim()}:f));setRenamingNoteFolder(null);flash("Renamed")}; const deleteNoteFolder=id=>{setNoteFolders(p=>p.filter(f=>f.id!==id&&f.parent!==id));setDeletingNoteFolder(null);flash("Folder removed (notes kept)")}; // Bookmark management const createBmFolder=parent=>{if(!bmNewFolderName.trim())return;setBmFolders(p=>[...p,{id:"bm"+Date.now(),title:bmNewFolderName.trim(),parent,items:[]}]);setBmNewFolderMode(null);setBmNewFolderName("");flash("Bookmark folder created")}; const renameBmFolder=(id,name)=>{if(!name.trim())return;setBmFolders(p=>p.map(f=>f.id===id?{...f,title:name.trim()}:f));setBmRenamingFolder(null);flash("Renamed")}; const deleteBmFolder=id=>{setBmFolders(p=>p.filter(f=>f.id!==id&&f.parent!==id));setBmDeletingFolder(null);flash("Folder deleted")}; const renameBmItem=(folderId,itemId,name)=>{if(!name.trim())return;setBmFolders(p=>p.map(f=>f.id===folderId?{...f,items:f.items.map(i=>i.id===itemId?{...i,title:name.trim()}:i)}:f));setBmRenamingItem(null);flash("Renamed")}; const deleteBmItem=(folderId,itemId)=>{setBmFolders(p=>p.map(f=>f.id===folderId?{...f,items:f.items.filter(i=>i.id!==itemId)}:f));flash("Bookmark deleted")}; // Block helpers from V5.2 const toggleBlock=id=>setBlocks(p=>p.map(b=>b.id===id?{...b,collapsed:!b.collapsed}:b)); const toggleTask=(bid,tid)=>setBlocks(p=>p.map(b=>b.id===bid?{...b,tasks:b.tasks.map(t=>t.id===tid?{...t,done:!t.done}:t)}:b)); const toggleSub=(bid,tid,sid)=>setBlocks(p=>p.map(b=>b.id===bid?{...b,tasks:b.tasks.map(t=>t.id===tid?{...t,sub:t.sub.map(s=>s.id===sid?{...s,done:!s.done}:s)}:t)}:b)); const deleteBlock=id=>setBlocks(p=>p.filter(b=>b.id!==id)); const toggleFeedSection=key=>{const s=new Set(collapsedFeeds);s.has(key)?s.delete(key):s.add(key);setCollapsedFeeds(s)}; const addTask=(bid,text)=>{if(!text.trim())return;setBlocks(p=>p.map(b=>b.id===bid?{...b,tasks:[...b.tasks,{id:nid(),text:text.trim(),done:false,sub:[]}]}:b));setNewTaskText("")}; const addSubtask=(bid,tid,text)=>{if(!text.trim())return;setBlocks(p=>p.map(b=>b.id===bid?{...b,tasks:b.tasks.map(t=>t.id===tid?{...t,sub:[...t.sub,{id:nid(),text:text.trim(),done:false}]}:t)}:b));setNewSubText(p=>({...p,[tid]:""}))}; const addThreadReply=bid=>{if(!threadReplyText.trim())return;setBlocks(p=>p.map(b=>b.id===bid?{...b,messages:[...b.messages,{id:nid(),author:"You",color:c.accentBtn,body:threadReplyText.trim(),time:"now"}]}:b));setThreadReplyId(null);setThreadReplyText("")}; const insertBlock=(type,preset)=>{const newId=nid();let block;if(type==="tasks")block={id:newId,type:"tasks",title:"New Task List",collapsed:false,tasks:[]};else if(type==="feed"){const p=preset||{name:"Custom Feed"};block={id:newId,type:"feed",title:p.name,collapsed:false,sections:[{key:"custom",icon:"spark",label:p.name,items:[{text:"Waiting for events…",time:"now"}]}]}}else if(type==="thread")block={id:newId,type:"thread",collapsed:false,contextQuote:"",messages:[{id:nid(),author:"You",color:c.accentBtn,body:`@${agent.name} `,time:"now"}]};else if(type==="bar")block={id:newId,type:"bar",title:"New notice",accent:c.warn};else return;setBlocks(p=>[...p,block]);setPickerOpen(false);setPickerStep("choose");flash(`${type} added`)}; const acceptChange=id=>setChanges(p=>p.map(x=>x.id===id?{...x,status:"accepted"}:x)); const rejectChange=id=>setChanges(p=>p.map(x=>x.id===id?{...x,status:"rejected"}:x)); // Comments const addReply=cmId=>{if(!replyText.trim())return;setComments(p=>p.map(cm=>cm.id===cmId?{...cm,replies:[...cm.replies,{id:"r"+Date.now(),author:"You",color:c.accentBtn,body:replyText.trim(),time:"just now"}]}:cm));setReplyingTo(null);setReplyText("")}; const resolveComment=id=>setComments(p=>p.map(cm=>cm.id===id?{...cm,status:"resolved"}:cm)); const reopenComment=id=>setComments(p=>p.map(cm=>cm.id===id?{...cm,status:"open"}:cm)); const saveEdit=id=>{if(!editText.trim())return;setComments(p=>p.map(cm=>cm.id===id?{...cm,body:editText.trim()}:cm));setEditingId(null)}; const doDelete=id=>{setComments(p=>p.filter(cm=>cm.id!==id));setDeletingId(null)}; const addComment=()=>{if(!newCmText.trim())return;setComments(p=>[...p,{id:"c"+Date.now(),author:"You",color:c.accentBtn,body:newCmText.trim(),time:"just now",status:"open",anchor:newCm?.text||null,replies:[]}]);setNewCm(null);setNewCmText("")}; // Tabs const closeTab=id=>{if(tabs.length<=1)return;const idx=tabs.findIndex(t=>t.id===id);setTabs(p=>p.filter(t=>t.id!==id));if(activeTabId===id){const next=tabs[idx===0?1:idx-1];if(next)setActiveTabId(next.id)}}; const addTab=(type,inc=false)=>{const id="t"+Date.now();const t=type==="note"?{id,type:"note",icon:"📝",title:"Untitled Note",color:tabColors.note}:type==="doc"?{id,type:"doc",icon:"📄",title:"Open Document…",color:tabColors.doc}:{id,type:"web",icon:"🌐",title:"New Tab",color:tabColors.web,incognito:inc};setTabs(p=>[...p,t]);setActiveTabId(id);setNewTabDrop(false);flash(inc?"Incognito tab":type==="doc"?"Opening file picker…":"New "+type)}; const handleTabDrop=targetId=>{if(!dragTabId||dragTabId===targetId)return;setTabs(prev=>{const d=prev.find(t=>t.id===dragTabId);const r=prev.filter(t=>t.id!==dragTabId);const ti=r.findIndex(t=>t.id===targetId);return [...r.slice(0,ti),d,...r.slice(ti)]});setDragTabId(null)}; const handleSend=()=>{if(outputMode==="respond_in_chat")flash(`Opening "${chats[chatIdx].name}"…`);else{if(!instruction.trim())return;flash(`${agent.name}: ${subMode}…`)}}; const sendToAgent=()=>{if(!instruction.trim())return;setAgentResponse({text:`Based on "${activeTab.title}": The discount rate of 18% lacks comparable transaction support. Three signage transactions show 8-12% average. This is a strong Sargon gatekeeper argument.`,time:"just now"});setInstruction("")};; const handleMouseUp=useCallback(e=>{if(e.target.closest("[data-bubble]"))return;const sel=window.getSelection();if(!sel||sel.isCollapsed||!sel.toString().trim()){setBubbleMenu(null);return}const text=sel.toString().trim();if(text.length<3)return;const rect=sel.getRangeAt(0).getBoundingClientRect();const er=editorRef.current?.getBoundingClientRect();if(!er)return;setBubbleMenu({x:rect.left-er.left+rect.width/2,y:rect.top-er.top-8,text})},[]); const dismissBubble=()=>{setBubbleMenu(null);window.getSelection()?.removeAllRanges()}; const filtered=useMemo(()=>{let items=[...allItems];if(activeScope==="Project"&&!noProject)items=items.filter(it=>it.proj===projects[activeProjIdx].id);if(activeScope==="Project"&&noProject)items=items.filter(it=>it.proj===null);if(selectedCollections.size>0)items=items.filter(it=>[...selectedCollections].every(col=>it.cols?.includes(col)));if(activeTypes.size>0)items=items.filter(it=>activeTypes.has(it.type));if(sortKey==="Alphabetical")items.sort((a,b)=>a.title.localeCompare(b.title));else if(sortKey==="Type")items.sort((a,b)=>a.type.localeCompare(b.type));else items.sort((a,b)=>timeVal(a.time)-timeVal(b.time));return [...items.filter(x=>x.pin),...items.filter(x=>!x.pin)]},[activeScope,activeProjIdx,noProject,selectedCollections,activeTypes,sortKey]); const filteredNotes=(noteSearch?notes.filter(n=>n.title.toLowerCase().includes(noteSearch.toLowerCase())):notes).sort((a,b)=>{if(a.pinned&&!b.pinned)return -1;if(!a.pinned&&b.pinned)return 1;return timeVal(a.mod)-timeVal(b.mod)}); // Rendered text with tracked changes const renderText=seg=>{const tc=changes.find(x=>x.segId===seg.id&&x.status==="pending");if(!tc||!showMarkup)return {tc&&!showMarkup?seg.v.replace(tc.oldText,tc.newText):seg.v};const idx=seg.v.indexOf(tc.oldText);if(idx===-1)return {seg.v};const ac=tcColors[tc.author]||tcColors.Agent;return {seg.v.slice(0,idx)}{tc.oldText}{tc.newText}{" "}{tc.author}{seg.v.slice(idx+tc.oldText.length)}}; // Browser folder tree const renderBFolders=(parentId,depth,isOverlay=false)=>browserFolders.filter(f=>f.parent===parentId).map(f=>{const hasKids=browserFolders.some(ch=>ch.parent===f.id);const isExp=expandedFolders.has(f.id);const isActive=!isOverlay&&activeFolder===f.id;const isDrop=dropTarget===f.id;const isHov=hoverFolder===f.id;const isDel=deletingFolder===f.id; return
{if(!isOverlay)setActiveFolder(isActive?null:f.id)}} onMouseEnter={()=>setHoverFolder(f.id)} onMouseLeave={()=>setHoverFolder(null)} onDragOver={e=>{e.preventDefault();setDropTarget(f.id)}} onDragLeave={()=>setDropTarget(null)} onDrop={e=>{e.preventDefault();setDropTarget(null);if(dragItem)flash(`Added to ${f.title}`)}} style={{display:"flex",alignItems:"center",gap:3,padding:isOverlay?"2px 6px":"3px 8px",paddingLeft:(isOverlay?6:8)+depth*(isOverlay?12:14),borderRadius:R.sm,cursor:isOverlay?"default":"pointer",backgroundColor:isDrop?c.accentBtn+"20":isActive?c.accentBtn+"10":"transparent",fontSize:isOverlay?10.5:11.5,fontWeight:isActive?600:400,color:isActive?c.accentBtn:c.textSec,border:isDrop?`1px dashed ${c.accentBtn}`:"1px solid transparent"}}> {hasKids?{e.stopPropagation();toggleFolder(f.id)}} style={{display:"flex",width:10}}>{isExp?:}:} {f.title} {isHov&&!isOverlay&&!isDel&&<>{e.stopPropagation();setNewFolderMode({parent:f.id});setNewFolderName("");setTimeout(()=>nfRef.current?.focus(),50)}} style={{cursor:"pointer",display:"flex",color:c.textTer}} title="Add subfolder">{e.stopPropagation();setDeletingFolder(f.id)}} style={{cursor:"pointer",display:"flex",color:c.textTer}} title="Delete">} {isDel&&e.stopPropagation()}>Delete?deleteBrowserFolder(f.id)}>YessetDeletingFolder(null)}>No}
{isExp&&hasKids&&renderBFolders(f.id,depth+1,isOverlay)}{!isOverlay&&newFolderMode?.parent===f.id&&
setNewFolderName(e.target.value)} placeholder="Subfolder…" onKeyDown={e=>{if(e.key==="Enter")createBrowserFolder(f.id);if(e.key==="Escape")setNewFolderMode(null)}} style={{flex:1,border:`1px solid ${c.accentBtn}40`,borderRadius:3,padding:"2px 6px",fontSize:11,fontFamily:font.sans,outline:"none",backgroundColor:c.bgCard}}/>
}
}); // Notes folder tree with full management const renderNoteFolders=(parentId,depth)=>noteFolders.filter(f=>f.parent===parentId).map(f=>{const hasKids=noteFolders.some(ch=>ch.parent===f.id);const isExp=noteExpandedFolders.has(f.id);const folderNotes=filteredNotes.filter(n=>n.folder===f.id);const isHov=noteHoverFolder===f.id; return
{e.stopPropagation();e.dataTransfer.setData("text","folder:"+f.id)}} onDragOver={e=>{e.preventDefault();e.stopPropagation()}} onDrop={e=>{e.preventDefault();e.stopPropagation();flash(`Moved to ${f.title}`)}} onMouseEnter={()=>setNoteHoverFolder(f.id)} onMouseLeave={()=>setNoteHoverFolder(null)} onClick={()=>{const s=new Set(noteExpandedFolders);s.has(f.id)?s.delete(f.id):s.add(f.id);setNoteExpandedFolders(s)}} style={{display:"flex",alignItems:"center",gap:4,padding:`4px 8px 4px ${8+depth*14}px`,cursor:"grab",backgroundColor:c.bgPanelAlt,borderBottom:`1px solid ${c.borderLight}`}}> {isExp?:} {renamingNoteFolder===f.id?setRenamingNoteFolderText(e.target.value)} autoFocus onClick={e=>e.stopPropagation()} onKeyDown={e=>{if(e.key==="Enter")renameNoteFolder(f.id,renamingNoteFolderText);if(e.key==="Escape")setRenamingNoteFolder(null)}} onBlur={()=>renameNoteFolder(f.id,renamingNoteFolderText)} style={{flex:1,fontSize:11.5,fontWeight:600,border:`1px solid ${c.accentBtn}40`,borderRadius:3,padding:"1px 6px",outline:"none",fontFamily:font.sans,backgroundColor:c.bgCard}}/> :{f.title}} {isHov&&!deletingNoteFolder&&renamingNoteFolder!==f.id&&<>{e.stopPropagation();setNoteNewFolderMode({parent:f.id});setNoteNewFolderName("")}} style={{cursor:"pointer",display:"flex",color:c.textTer}} title="Add subfolder">{e.stopPropagation();setRenamingNoteFolder(f.id);setRenamingNoteFolderText(f.title)}} style={{cursor:"pointer",display:"flex",color:c.textTer}} title="Rename">{e.stopPropagation();setDeletingNoteFolder(f.id)}} style={{cursor:"pointer",display:"flex",color:c.textTer}} title="Delete">} {deletingNoteFolder===f.id&&e.stopPropagation()}>Remove?deleteNoteFolder(f.id)}>YessetDeletingNoteFolder(null)}>No}
{isExp&&<>{noteNewFolderMode?.parent===f.id&&
setNoteNewFolderName(e.target.value)} placeholder="Subfolder…" autoFocus onKeyDown={e=>{if(e.key==="Enter")createNoteFolder(f.id);if(e.key==="Escape")setNoteNewFolderMode(null)}} style={{flex:1,border:`1px solid ${c.accentBtn}40`,borderRadius:3,padding:"2px 6px",fontSize:11,fontFamily:font.sans,outline:"none",backgroundColor:c.bgCard}}/>
} {folderNotes.map(n=>
{setSelectedNote(n.id);flash(`Open "${n.title}"`)}} onContextMenu={e=>{e.preventDefault();setNoteContextMenu({x:e.clientX,y:e.clientY,noteId:n.id})}} style={{display:"flex",alignItems:"center",gap:4,padding:`4px 10px 4px ${14+depth*14}px`,height:30,borderBottom:`1px solid ${c.borderLight}`,cursor:"pointer",backgroundColor:selectedNote===n.id?c.accentBtn+"06":"transparent",borderLeft:selectedNote===n.id?`2px solid ${c.accentBtn}`:"2px solid transparent"}}> {n.pinned&&}{n.title}{n.comments>0&&💬{n.comments}}{n.mod}
)} {renderNoteFolders(f.id,depth+1)} }
}); // Comment card with full edit/delete const CmCard=({cm,resolved})=>{const isAct=activeComment===cm.id;return
setActiveComment(isAct?null:cm.id)}>
{cm.anchor&&
"{cm.anchor.slice(0,55)}"
}
{cm.author}{cm.time}
{editingId===cm.id?
e.stopPropagation()}>