claude-mpm 4.1.11__py3-none-any.whl → 4.1.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/INSTRUCTIONS.md +8 -0
  3. claude_mpm/cli/__init__.py +1 -1
  4. claude_mpm/cli/commands/monitor.py +88 -627
  5. claude_mpm/cli/commands/mpm_init.py +127 -107
  6. claude_mpm/cli/commands/mpm_init_handler.py +24 -23
  7. claude_mpm/cli/parsers/mpm_init_parser.py +34 -28
  8. claude_mpm/core/config.py +18 -0
  9. claude_mpm/core/instruction_reinforcement_hook.py +266 -0
  10. claude_mpm/core/pm_hook_interceptor.py +105 -8
  11. claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
  12. claude_mpm/dashboard/static/built/components/code-tree.js +1 -1
  13. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  14. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  15. claude_mpm/dashboard/static/css/activity.css +1239 -267
  16. claude_mpm/dashboard/static/css/dashboard.css +511 -0
  17. claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
  18. claude_mpm/dashboard/static/dist/components/code-tree.js +1 -1
  19. claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
  20. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  21. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  22. claude_mpm/dashboard/static/js/components/activity-tree.js +1193 -892
  23. claude_mpm/dashboard/static/js/components/build-tracker.js +15 -13
  24. claude_mpm/dashboard/static/js/components/code-tree.js +534 -143
  25. claude_mpm/dashboard/static/js/components/module-viewer.js +21 -7
  26. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +1066 -0
  27. claude_mpm/dashboard/static/js/connection-manager.js +1 -1
  28. claude_mpm/dashboard/static/js/dashboard.js +227 -84
  29. claude_mpm/dashboard/static/js/socket-client.js +2 -2
  30. claude_mpm/dashboard/templates/index.html +100 -23
  31. claude_mpm/services/agents/deployment/agent_template_builder.py +11 -7
  32. claude_mpm/services/cli/socketio_manager.py +39 -8
  33. claude_mpm/services/infrastructure/monitoring.py +1 -1
  34. claude_mpm/services/socketio/handlers/code_analysis.py +83 -136
  35. claude_mpm/tools/code_tree_analyzer.py +290 -202
  36. {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/METADATA +1 -1
  37. {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/RECORD +41 -39
  38. {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/WHEEL +0 -0
  39. {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/entry_points.txt +0 -0
  40. {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/licenses/LICENSE +0 -0
  41. {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/top_level.txt +0 -0
@@ -1,2 +1,2 @@
1
- class t{constructor(){this.container=null,this.svg=null,this.treeData=null,this.root=null,this.treeLayout=null,this.treeGroup=null,this.nodes=new Map,this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.isRadialLayout=!0,this.margin={top:20,right:20,bottom:20,left:20},this.width=960-this.margin.left-this.margin.right,this.height=600-this.margin.top-this.margin.bottom,this.radius=Math.min(this.width,this.height)/2,this.nodeId=0,this.duration=750,this.languageFilter="all",this.searchTerm="",this.tooltip=null,this.initialized=!1,this.analyzing=!1,this.selectedNode=null,this.socket=null,this.autoDiscovered=!1,this.zoom=null,this.activeNode=null,this.loadingNodes=new Set}initialize(){if(this.initialized)return;if(this.container=document.getElementById("code-tree-container"),!this.container)return void console.error("Code tree container not found");const t=document.getElementById("code-tab");if(!t)return void console.error("Code tab panel not found");const e=this.getWorkingDirectory();if(!e||"Loading..."===e||"Not selected"===e)return this.showNoWorkingDirectoryMessage(),void(this.initialized=!0);this.setupControls(),this.initializeTreeData(),this.subscribeToEvents();document.getElementById("breadcrumb-content")&&!this.analyzing&&this.updateActivityTicker("Loading project structure...","info"),t.classList.contains("active")&&(this.createVisualization(),this.root&&this.svg&&this.update(this.root),this.autoDiscoverRootLevel()),this.initialized=!0}renderWhenVisible(){const t=this.getWorkingDirectory();t&&"Loading..."!==t&&"Not selected"!==t?(this.removeNoWorkingDirectoryMessage(),this.initialized?(this.svg?this.root&&this.svg&&this.update(this.root):(this.createVisualization(),this.svg&&this.treeGroup&&this.update(this.root)),this.autoDiscovered||this.autoDiscoverRootLevel()):this.initialize()):this.showNoWorkingDirectoryMessage()}setupControls(){const t=document.getElementById("language-filter");t&&t.addEventListener("change",t=>{this.languageFilter=t.target.value,this.filterTree()});const e=document.getElementById("code-search");e&&e.addEventListener("input",t=>{this.searchTerm=t.target.value.toLowerCase(),this.filterTree()});const s=document.getElementById("code-expand-all");s&&s.addEventListener("click",()=>this.expandAll());const i=document.getElementById("code-collapse-all");i&&i.addEventListener("click",()=>this.collapseAll());const o=document.getElementById("code-reset-zoom");o&&o.addEventListener("click",()=>this.resetZoom());const a=document.getElementById("code-toggle-legend");a&&a.addEventListener("click",()=>this.toggleLegend());const n=document.getElementById("show-hidden-files");n&&n.addEventListener("change",()=>{this.autoDiscovered=!1,this.initializeTreeData(),this.autoDiscoverRootLevel(),this.showNotification(n.checked?"Showing hidden files":"Hiding hidden files","info")}),document.addEventListener("workingDirectoryChanged",t=>{console.log("Working directory changed to:",t.detail.directory),this.onWorkingDirectoryChanged(t.detail.directory)})}onWorkingDirectoryChanged(t){if(!t||"Loading..."===t||"Not selected"===t)return this.showNoWorkingDirectoryMessage(),this.autoDiscovered=!1,this.analyzing=!1,this.nodes.clear(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},void this.updateStats();this.removeNoWorkingDirectoryMessage(),this.autoDiscovered=!1,this.analyzing=!1,this.nodes.clear(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.initializeTreeData(),this.svg&&this.update(this.root);const e=document.getElementById("code-tab");e&&e.classList.contains("active")&&this.autoDiscoverRootLevel(),this.updateStats()}showLoading(){let t=document.getElementById("code-tree-loading");if(!t){const e=document.getElementById("code-tree-container");e&&(t=document.createElement("div"),t.id="code-tree-loading",t.innerHTML='\n <div class="code-tree-spinner"></div>\n <div class="code-tree-loading-text">Analyzing code structure...</div>\n ',e.appendChild(t))}t&&t.classList.remove("hidden")}hideLoading(){const t=document.getElementById("code-tree-loading");t&&t.classList.add("hidden")}createVisualization(){if("undefined"==typeof d3)return void console.error("D3.js is not loaded");const t=d3.select("#code-tree-container");if(t.selectAll("*").remove(),!t||!t.node())return void console.error("Code tree container not found");const e=t.node(),s=e.clientWidth||960,i=e.clientHeight||600;this.width=s-this.margin.left-this.margin.right,this.height=i-this.margin.top-this.margin.bottom,this.radius=Math.min(this.width,this.height)/2,this.svg=t.append("svg").attr("width",s).attr("height",i);const o=s/2,a=i/2;this.isRadialLayout?this.treeGroup=this.svg.append("g").attr("transform",`translate(${o},${a})`):this.treeGroup=this.svg.append("g").attr("transform",`translate(${this.margin.left+100},${a})`),this.isRadialLayout?this.treeLayout=d3.cluster().size([2*Math.PI,this.radius-100]).separation((t,e)=>{if(t.parent==e.parent){const e=Math.max(1,4-t.depth),s=t.parent&&t.parent.children?.length||1,i=s>5?2:s>3?1.5:1,o=1+.2*t.depth;return e*i/(t.depth||1)*o}return 4/(t.depth||1)}):this.treeLayout=d3.tree().nodeSize([30,200]).separation((t,e)=>t.parent==e.parent?1:1.5),this.zoom=d3.zoom().scaleExtent([.1,10]).on("zoom",t=>{this.isRadialLayout?this.treeGroup.attr("transform",`translate(${o+t.transform.x},${a+t.transform.y}) scale(${t.transform.k})`):this.treeGroup.attr("transform",`translate(${this.margin.left+100+t.transform.x},${a+t.transform.y}) scale(${t.transform.k})`)}),this.svg.call(this.zoom),this.addVisualizationControls(),this.tooltip=d3.select("body").append("div").attr("class","code-tree-tooltip").style("opacity",0).style("position","absolute").style("background","rgba(0, 0, 0, 0.8)").style("color","white").style("padding","8px").style("border-radius","4px").style("font-size","12px").style("pointer-events","none")}initializeTreeData(){const t=this.getWorkingDirectory(),e=t&&t.split("/").pop()||"Project Root",s=t||".";this.treeData={name:e,path:s,type:"root",children:[],loaded:!1,expanded:!0},"undefined"!=typeof d3&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0)}subscribeToEvents(){this.socket||(window.socket?(this.socket=window.socket,this.setupEventHandlers()):window.dashboard?.socketClient?.socket?(this.socket=window.dashboard.socketClient.socket,this.setupEventHandlers()):window.socketClient?.socket&&(this.socket=window.socketClient.socket,this.setupEventHandlers()))}autoDiscoverRootLevel(){if(this.autoDiscovered||this.analyzing)return;this.updateActivityTicker("🔍 Discovering project structure...","info");const t=this.getWorkingDirectory();if(!t||"Loading..."===t||"Not selected"===t)return console.warn("Cannot auto-discover: no working directory set"),void this.showNoWorkingDirectoryMessage();if(!t.startsWith("/")&&!t.match(/^[A-Z]:\\/))return console.error("Working directory is not absolute:",t),void this.showNotification("Invalid working directory path","error");console.log("Auto-discovering root level for:",t),this.autoDiscovered=!0,this.analyzing=!0,this.nodes.clear(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.socket&&!this.socket.hasListeners("code:node:found")&&this.setupEventHandlers();const e=t.split("/").pop()||"Project Root";this.treeData={name:e,path:t,type:"root",children:[],loaded:!1,expanded:!0},"undefined"!=typeof d3&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0),this.showLoading(),this.updateBreadcrumb(`Discovering structure in ${e}...`,"info");const s=[];document.querySelectorAll(".language-checkbox:checked").forEach(t=>{s.push(t.value)});const i=document.getElementById("ignore-patterns")?.value||"",o=document.getElementById("show-hidden-files")?.checked||!1;console.log("[DEBUG] Show hidden files checkbox value:",o),console.log("[DEBUG] Checkbox element:",document.getElementById("show-hidden-files"));const a={path:t,depth:"top_level",languages:s,ignore_patterns:i,show_hidden_files:o};console.log("[DEBUG] Sending discovery request with payload:",a),this.socket&&this.socket.emit("code:discover:top_level",a),this.updateStats()}analyzeCode(){this.analyzing||this.autoDiscoverRootLevel()}cancelAnalysis(){this.analyzing=!1,this.hideLoading(),this.socket&&this.socket.emit("code:analysis:cancel"),this.updateBreadcrumb("Analysis cancelled","warning"),this.showNotification("Analysis cancelled","warning"),this.addEventToDisplay("Analysis cancelled","warning")}createEventsDisplay(){let t=document.getElementById("analysis-events");if(!t){const e=document.getElementById("code-tree-container");e&&(t=document.createElement("div"),t.id="analysis-events",t.className="analysis-events",t.style.display="none",e.appendChild(t))}}clearEventsDisplay(){const t=document.getElementById("analysis-events");t&&(t.innerHTML="",t.style.display="block")}addEventToDisplay(t,e="info"){const s=document.getElementById("analysis-events");if(s){const i=document.createElement("div");i.className="analysis-event",i.style.borderLeftColor="warning"===e?"#f59e0b":"error"===e?"#ef4444":"#3b82f6";const o=(new Date).toLocaleTimeString();i.innerHTML=`<span style="color: #718096;">[${o}]</span> ${t}`,s.appendChild(i),s.scrollTop=s.scrollHeight}}setupEventHandlers(){this.socket&&(this.socket.on("code:analysis:accepted",t=>this.onAnalysisAccepted(t)),this.socket.on("code:analysis:queued",t=>this.onAnalysisQueued(t)),this.socket.on("code:analysis:start",t=>this.onAnalysisStart(t)),this.socket.on("code:analysis:complete",t=>this.onAnalysisComplete(t)),this.socket.on("code:analysis:cancelled",t=>this.onAnalysisCancelled(t)),this.socket.on("code:analysis:error",t=>this.onAnalysisError(t)),this.socket.on("code:directory:discovered",t=>this.onDirectoryDiscovered(t)),this.socket.on("code:file:discovered",t=>this.onFileDiscovered(t)),this.socket.on("code:file:analyzed",t=>this.onFileAnalyzed(t)),this.socket.on("code:node:found",t=>this.onNodeFound(t)),this.socket.on("code:analysis:progress",t=>this.onProgressUpdate(t)),this.socket.on("code:directory:contents",t=>{if(t.path){const e=this.findNodeByPath(t.path);if(e&&t.children){const s=this.findD3NodeByPath(t.path);s&&this.loadingNodes.has(t.path)&&this.removeLoadingPulse(s),e.children=t.children.map(t=>({...t,loaded:"directory"!==t.type&&void 0,analyzed:"file"!==t.type&&void 0,expanded:!1,children:[]})),e.loaded=!0,this.root&&this.svg&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.update(this.root)),t.stats&&(this.stats.files+=t.stats.files||0,this.stats.directories+=t.stats.directories||0,this.updateStats()),this.updateBreadcrumb(`Loaded ${t.path}`,"success"),this.hideLoading()}}}),this.socket.on("code:top_level:discovered",t=>{t.items&&Array.isArray(t.items)&&(this.treeData.children=t.items.map(t=>({name:t.name,path:t.path,type:t.type,language:"file"===t.type?this.detectLanguage(t.path):void 0,size:t.size,lines:t.lines,loaded:"directory"!==t.type&&void 0,analyzed:"file"!==t.type&&void 0,expanded:!1,children:[]})),this.treeData.loaded=!0,t.stats&&(this.stats={...this.stats,...t.stats},this.updateStats()),"undefined"!=typeof d3&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.svg&&this.update(this.root)),this.analyzing=!1,this.hideLoading(),this.updateBreadcrumb(`Discovered ${t.items.length} root items`,"success"),this.showNotification(`Found ${t.items.length} items in project root`,"success"))}))}onAnalysisStart(t){this.analyzing=!0;const e=t.message||"Starting code analysis...";this.updateActivityTicker("🚀 Starting analysis...","info"),this.updateBreadcrumb(e,"info"),this.addEventToDisplay(`🚀 ${e}`,"info"),this.treeData&&0!==this.treeData.children.length||this.initializeTreeData(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.updateStats()}onDirectoryDiscovered(t){this.updateActivityTicker(`📁 Discovered: ${t.name||"directory"}`),this.addEventToDisplay(`📁 Found ${(t.children||[]).length} items in: ${t.name||t.path}`,"info");const e=this.findNodeByPath(t.path);if(e&&t.children){e.children=t.children.map(t=>({name:t.name,path:t.path,type:t.type,loaded:"directory"!==t.type&&void 0,analyzed:"file"!==t.type&&void 0,expanded:!1,children:"directory"===t.type?[]:void 0,size:t.size,has_code:t.has_code})),e.loaded=!0,e.expanded=!0;const s=this.findD3NodeByPath(t.path);s&&(this.loadingNodes.has(t.path)&&this.removeLoadingPulse(s),s.data&&(s.data.children=e.children,s._children=null)),this.root&&this.svg&&(this.root=d3.hierarchy(this.treeData),this.update(this.root)),this.updateBreadcrumb(`Loaded ${e.children.length} items from ${e.name}`,"success"),this.updateStats()}else if(!e){const e=t.path?t.path.split("/").filter(t=>t):[];if(1===e.length||t.forceAdd){const s={name:t.name||e[e.length-1]||"Unknown",path:t.path,type:"directory",children:[],loaded:!1,expanded:!1,stats:t.stats||{}};this.addNodeToTree(s,t.parent||""),this.updateBreadcrumb(`Discovered: ${t.path}`,"info")}}}onFileDiscovered(t){const e=t.name||(t.path?t.path.split("/").pop():"file");this.updateActivityTicker(`📄 Found: ${e}`),this.addEventToDisplay(`📄 Discovered: ${t.path||"Unknown file"}`,"info");const s=t.path?t.path.split("/").filter(t=>t):[],i=s.slice(0,-1).join("/"),o={name:t.name||s[s.length-1]||"Unknown",path:t.path,type:"file",language:t.language||this.detectLanguage(t.path),size:t.size||0,lines:t.lines||0,children:[],analyzed:!1};this.addNodeToTree(o,i),this.stats.files++,this.updateStats(),this.updateBreadcrumb(`Found: ${t.path}`,"info")}onFileAnalyzed(t){const e=this.findD3NodeByPath(t.path);if(e&&this.loadingNodes.has(t.path)&&this.removeLoadingPulse(e),t.path){const e=t.path.split("/").pop();this.updateActivityTicker(`🔍 Analyzed: ${e}`)}const s=this.findNodeByPath(t.path);s&&(s.analyzed=!0,s.complexity=t.complexity||0,s.lines=t.lines||0,t.elements&&Array.isArray(t.elements)&&(s.children=t.elements.map(e=>({name:e.name,type:e.type.toLowerCase(),path:`${t.path}#${e.name}`,line:e.line,complexity:e.complexity||1,docstring:e.docstring||"",children:e.methods?e.methods.map(s=>({name:s.name,type:"method",path:`${t.path}#${e.name}.${s.name}`,line:s.line,complexity:s.complexity||1,docstring:s.docstring||""})):[]}))),t.stats&&(this.stats.classes+=t.stats.classes||0,this.stats.functions+=t.stats.functions||0,this.stats.methods+=t.stats.methods||0,this.stats.lines+=t.stats.lines||0),this.updateStats(),this.root&&this.update(this.root),this.updateBreadcrumb(`Analyzed: ${t.path}`,"success"))}onNodeFound(t){const e="class"===t.type?"🏛️":"function"===t.type?"⚡":"method"===t.type?"🔧":"📦";this.addEventToDisplay(`${e} Found ${t.type||"node"}: ${t.name||"Unknown"}`);const s={name:t.name||"Unknown",type:(t.type||"unknown").toLowerCase(),path:t.path||"",line:t.line||0,complexity:t.complexity||1,docstring:t.docstring||""};s.type={class:"class",function:"function",method:"method",module:"module",file:"file",directory:"directory"}[s.type]||s.type;let i="";if(t.parent_path)i=t.parent_path;else if(t.file_path)i=t.file_path;else if(s.path.includes("/")){const t=s.path.split("/");t.pop(),i=t.join("/")}switch(s.type){case"class":this.stats.classes++;break;case"function":this.stats.functions++;break;case"method":this.stats.methods++;break;case"file":this.stats.files++}this.addNodeToTree(s,i),this.updateStats();const o=s.type.charAt(0).toUpperCase()+s.type.slice(1);this.updateBreadcrumb(`Found ${o}: ${s.name}`,"info")}onProgressUpdate(t){const e=t.progress||0,s=t.message||`Processing... ${e}%`;this.updateBreadcrumb(s,"info");const i=document.querySelector(".code-tree-progress");i&&(i.style.width=`${e}%`)}onAnalysisComplete(t){this.analyzing=!1,this.hideLoading(),this.updateActivityTicker("✅ Ready","success"),this.addEventToDisplay("✅ Analysis complete!","success"),this.root&&this.svg&&this.update(this.root),t.stats&&(this.stats={...this.stats,...t.stats},this.updateStats());const e=t.message||`Analysis complete: ${this.stats.files} files, ${this.stats.classes} classes, ${this.stats.functions} functions`;this.updateBreadcrumb(e,"success"),this.showNotification(e,"success")}onAnalysisError(t){this.analyzing=!1,this.hideLoading();const e=t.message||t.error||"Analysis failed";this.updateBreadcrumb(e,"error"),this.showNotification(e,"error")}onAnalysisAccepted(t){const e=t.message||"Analysis request accepted";this.updateBreadcrumb(e,"info")}onAnalysisQueued(t){const e=`Analysis queued (position ${t.position||0})`;this.updateBreadcrumb(e,"warning"),this.showNotification(e,"info")}onInfoEvent(t){if(console.log("[INFO]",t.type,t.message),t.type&&t.type.startsWith("discovery."))"discovery.start"===t.type?this.updateBreadcrumb(t.message,"info"):"discovery.complete"===t.type?(this.updateBreadcrumb(t.message,"success"),t.stats&&console.log("[DISCOVERY STATS]",t.stats)):"discovery.directory"!==t.type&&"discovery.file"!==t.type||this.updateBreadcrumb(t.message,"info");else if(t.type&&t.type.startsWith("analysis."))if("analysis.start"===t.type)this.updateBreadcrumb(t.message,"info");else if("analysis.complete"===t.type){if(this.updateBreadcrumb(t.message,"success"),t.stats){const e=`Found: ${t.stats.classes||0} classes, ${t.stats.functions||0} functions, ${t.stats.methods||0} methods`;console.log("[ANALYSIS STATS]",e)}}else("analysis.class"===t.type||"analysis.function"===t.type||"analysis.method"===t.type||"analysis.parse"===t.type)&&this.updateBreadcrumb(t.message,"info");else t.type&&t.type.startsWith("filter.")?(window.debugMode||this.showFilterEvents)&&(console.debug("[FILTER]",t.type,t.path,t.reason),this.showFilterEvents&&this.updateBreadcrumb(t.message,"warning")):t.type&&t.type.startsWith("cache.")&&("cache.hit"===t.type?(console.debug("[CACHE HIT]",t.file),this.showCacheEvents&&this.updateBreadcrumb(t.message,"info")):"cache.miss"===t.type&&console.debug("[CACHE MISS]",t.file));this.eventLogEnabled&&t.message&&this.addEventToDisplay(t)}addEventToDisplay(t){this.recentEvents||(this.recentEvents=[]),this.recentEvents.unshift({timestamp:t.timestamp||(new Date).toISOString(),type:t.type,message:t.message,data:t}),this.recentEvents.length>100&&this.recentEvents.pop(),console.log("[EVENT LOG]",t.type,t.message)}onAnalysisCancelled(t){this.analyzing=!1,this.hideLoading();const e=t.message||"Analysis cancelled";this.updateBreadcrumb(e,"warning")}showNotification(t,e="info"){const s=document.createElement("div");s.className=`code-tree-notification ${e}`,s.textContent=t;const i=document.getElementById("code-tree-container");i&&(s.style.position="absolute",s.style.top="10px",s.style.right="10px",s.style.zIndex="1000",i.style.position&&"static"!==i.style.position||(i.style.position="relative"),i.appendChild(s),setTimeout(()=>{s.style.animation="slideOutRight 0.3s ease",setTimeout(()=>s.remove(),300)},3e3))}addNodeToTree(t,e=""){if(t.path&&t.path.startsWith("/"))return void console.error("Absolute path detected in node, skipping:",t.path);if(e&&e.startsWith("/"))return void console.error("Absolute path detected in parent, skipping:",e);let s=this.treeData;if(e&&(s=this.findNodeByPath(e),!s))return console.warn("Parent node not found, skipping node creation:",e),void console.warn("Attempted to add node:",t);const i=s.children?.find(e=>e.path===t.path||e.name===t.name&&e.type===t.type);i?Object.assign(i,t):(s.children||(s.children=[]),t.children||(t.children=[]),s.children.push(t),this.nodes.set(t.path,t),this.root&&this.svg&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,(this.nodes.size<1e3||this.nodes.size%100==0)&&this.update(this.root)))}findNodeByPath(t,e=null){if(e||(e=this.treeData),e.path===t)return e;if(e.children)for(const s of e.children){const e=this.findNodeByPath(t,s);if(e)return e}return null}findD3NodeByPath(t){return this.root?this.root.descendants().find(e=>e.data.path===t):null}updateStats(){const t={"file-count":this.stats.files,"class-count":this.stats.classes,"function-count":this.stats.functions,"line-count":this.stats.lines};for(const[s,i]of Object.entries(t)){const t=document.getElementById(s);t&&(t.textContent=i.toLocaleString())}const e=document.getElementById("code-progress-text");if(e){const t=this.analyzing?`Analyzing... ${this.stats.files} files processed`:`Ready - ${this.stats.files} files in tree`;e.textContent=t}}updateBreadcrumb(t,e="info"){const s=document.getElementById("breadcrumb-content");s&&(s.textContent=t,s.className=`breadcrumb-${e}`)}detectLanguage(t){return{py:"python",js:"javascript",ts:"typescript",jsx:"javascript",tsx:"typescript",java:"java",cpp:"cpp",c:"c",cs:"csharp",rb:"ruby",go:"go",rs:"rust",php:"php",swift:"swift",kt:"kotlin",scala:"scala",r:"r",sh:"bash",ps1:"powershell"}[t.split(".").pop().toLowerCase()]||"unknown"}addVisualizationControls(){const t=this.svg.append("g").attr("class","viz-controls").attr("transform","translate(10, 10)").append("g").attr("class","layout-toggle").style("cursor","pointer").on("click",()=>this.toggleLayout());t.append("rect").attr("width",120).attr("height",30).attr("rx",5).attr("fill","#3b82f6").attr("opacity",.8),t.append("text").attr("x",60).attr("y",20).attr("text-anchor","middle").attr("fill","white").style("font-size","12px").text(this.isRadialLayout?"Switch to Linear":"Switch to Radial")}toggleLayout(){this.isRadialLayout=!this.isRadialLayout,this.createVisualization(),this.root&&this.update(this.root),this.showNotification(this.isRadialLayout?"Switched to radial layout":"Switched to linear layout","info")}radialPoint(t,e){return[(e=+e)*Math.cos(t-=Math.PI/2),e*Math.sin(t)]}update(t){if(!this.treeLayout||!this.treeGroup||!t)return;const e=this.treeLayout(this.root),s=e.descendants(),i=e.descendants().slice(1);this.isRadialLayout&&s.forEach(t=>{void 0===t.x0&&(t.x0=t.x,t.y0=t.y)});const o=this.treeGroup.selectAll("g.node").data(s,t=>t.id||(t.id=++this.nodeId)),a=o.enter().append("g").attr("class","node").attr("transform",e=>{if(this.isRadialLayout){const[e,s]=this.radialPoint(t.x0||0,t.y0||0);return`translate(${e},${s})`}return`translate(${t.y0},${t.x0})`}).on("click",(t,e)=>this.onNodeClick(t,e));a.append("circle").attr("class","node-circle").attr("r",1e-6).style("fill",t=>this.getNodeColor(t)).style("stroke",t=>this.getNodeStrokeColor(t)).style("stroke-width",2).on("mouseover",(t,e)=>this.showTooltip(t,e)).on("mouseout",()=>this.hideTooltip()),a.append("text").attr("class","node-label").attr("dy",".35em").attr("x",t=>this.isRadialLayout?0:t.children||t._children?-13:13).attr("text-anchor",t=>this.isRadialLayout?"start":t.children||t._children?"end":"start").text(t=>{const e=t.data.name||"";return e.length>20?e.substring(0,17)+"...":e}).style("fill-opacity",1e-6).style("font-size","12px").style("font-family",'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif').style("text-shadow","1px 1px 2px rgba(255,255,255,0.8), -1px -1px 2px rgba(255,255,255,0.8)"),a.append("text").attr("class","node-icon").attr("dy",".35em").attr("x",0).attr("text-anchor","middle").text(t=>this.getNodeIcon(t)).style("font-size","10px").style("fill","white");const n=a.merge(o);n.transition().duration(this.duration).attr("transform",t=>{if(this.isRadialLayout){const[e,s]=this.radialPoint(t.x,t.y);return`translate(${e},${s})`}return`translate(${t.y},${t.x})`}),n.select("circle.node-circle").attr("r",8).style("fill",t=>this.getNodeColor(t)).style("stroke",t=>this.getNodeStrokeColor(t)).attr("cursor","pointer");const r=this.isRadialLayout;n.select("text.node-label").style("fill-opacity",1).style("fill","#333").each(function(t){const e=d3.select(this);if(r){const s=180*t.x/Math.PI-90;s>90||s<-90?e.attr("transform",`rotate(${s+180})`).attr("x",-15).attr("text-anchor","end").attr("dy",".35em"):e.attr("transform",`rotate(${s})`).attr("x",15).attr("text-anchor","start").attr("dy",".35em")}else e.attr("transform",null).attr("x",t.children||t._children?-13:13).attr("text-anchor",t.children||t._children?"end":"start").attr("dy",".35em")});const d=o.exit().transition().duration(this.duration).attr("transform",e=>{if(this.isRadialLayout){const[e,s]=this.radialPoint(t.x,t.y);return`translate(${e},${s})`}return`translate(${t.y},${t.x})`}).remove();d.select("circle").attr("r",1e-6),d.select("text.node-label").style("fill-opacity",1e-6),d.select("text.node-icon").style("fill-opacity",1e-6);const l=this.treeGroup.selectAll("path.link").data(i,t=>t.id);l.enter().insert("path","g").attr("class","link").attr("d",e=>{const s={x:t.x0,y:t.y0};return this.isRadialLayout?this.radialDiagonal(s,s):this.diagonal(s,s)}).style("fill","none").style("stroke","#ccc").style("stroke-width",2).merge(l).transition().duration(this.duration).attr("d",t=>this.isRadialLayout?this.radialDiagonal(t,t.parent):this.diagonal(t,t.parent)),l.exit().transition().duration(this.duration).attr("d",e=>{const s={x:t.x,y:t.y};return this.isRadialLayout?this.radialDiagonal(s,s):this.diagonal(s,s)}).remove(),s.forEach(t=>{t.x0=t.x,t.y0=t.y})}centerOnNode(t){if(!this.svg||!this.zoom)return;const e=d3.zoomTransform(this.svg.node()),s=-t.y*e.k+this.width/2,i=-t.x*e.k+this.height/2;this.svg.transition().duration(750).call(this.zoom.transform,d3.zoomIdentity.translate(s,i).scale(e.k))}centerOnNodeRadial(t){if(!this.svg||!this.zoom)return;const[e,s]=this.radialPoint(t.x,t.y),i=d3.zoomTransform(this.svg.node()),o=this.width/2-e*i.k,a=this.height/2-s*i.k;this.svg.transition().duration(750).call(this.zoom.transform,d3.zoomIdentity.translate(o,a).scale(i.k))}highlightActiveNode(t){this.treeGroup.selectAll("circle.node-circle").transition().duration(300).attr("r",8).classed("active",!1).classed("parent-context",!1).style("stroke",null).style("stroke-width",null).style("opacity",null),this.treeGroup.selectAll("g.node").filter(e=>e===t).select("circle.node-circle").transition().duration(300).attr("r",12).classed("active",!0).style("stroke","#3b82f6").style("stroke-width",3),this.activeNode=t}addLoadingPulse(t){const e=this.treeGroup.selectAll("g.node").filter(e=>e===t).select("circle.node-circle");this.loadingNodes.add(t.data.path),e.classed("loading-pulse",!0).style("fill","#fb923c");const s=()=>{this.loadingNodes.has(t.data.path)&&e.transition().duration(600).attr("r",14).style("opacity",.6).transition().duration(600).attr("r",10).style("opacity",1).on("end",()=>{this.loadingNodes.has(t.data.path)&&s()})};s()}removeLoadingPulse(t){this.loadingNodes.delete(t.data.path);this.treeGroup.selectAll("g.node").filter(e=>e===t).select("circle.node-circle").classed("loading-pulse",!1).interrupt().transition().duration(300).attr("r",this.activeNode===t?12:8).style("opacity",1).style("fill",t=>this.getNodeColor(t))}showWithParent(t){if(!t.parent)return;if(this.treeGroup.selectAll("g.node").filter(e=>e===t.parent).select("circle.node-circle").classed("parent-context",!0).style("stroke","#10b981").style("stroke-width",3).style("opacity",.8),this.isRadialLayout&&t.parent){const e=[t,t.parent];t.children?e.push(...t.children):t._children&&e.push(...t._children);const s=e.map(t=>t.x),i=e.map(t=>t.y),o=Math.min(...s),a=Math.max(...s),n=Math.max(...i),r=a-o,d=Math.min(r>0?2*Math.PI/(2*r):2.5,this.width/(2*n),2.5),l=(o+a)/2,c=n/2,h=c*Math.cos(l-Math.PI/2),p=c*Math.sin(l-Math.PI/2);this.svg.transition().duration(750).call(this.zoom.transform,d3.zoomIdentity.translate(this.width/2-h*d,this.height/2-p*d).scale(d))}}onNodeClick(t,e){t.stopPropagation(),this.isRadialLayout?this.centerOnNodeRadial(e):this.centerOnNode(e),this.highlightActiveNode(e),this.showWithParent(e);const s=[];document.querySelectorAll(".language-checkbox:checked").forEach(t=>{s.push(t.value)});const i=document.getElementById("ignore-patterns")?.value||"",o=document.getElementById("show-hidden-files")?.checked||!1;if("directory"!==e.data.type||e.data.loaded)if("file"!==e.data.type||e.data.analyzed)(e.children||e._children)&&(e.children?(e._children=e.children,e.children=null,e.data.expanded=!1):(e.children=e._children,e._children=null,e.data.expanded=!0),this.update(e));else{const t=this.detectLanguage(e.data.path);if(!s.includes(t)&&"unknown"!==t)return void this.showNotification(`Skipping ${e.data.name} - ${t} not selected`,"warning");this.addLoadingPulse(e);const i=this.ensureFullPath(e.data.path),o=document.getElementById("show-hidden-files"),a=!!o&&o.checked;this.socket&&(this.socket.emit("code:analyze:file",{path:i,show_hidden_files:a}),e.data.analyzed="loading",this.updateBreadcrumb(`Analyzing ${e.data.name}...`,"info"),this.showNotification(`Analyzing: ${e.data.name}`,"info"))}else{this.addLoadingPulse(e);const t=this.ensureFullPath(e.data.path);this.socket&&(this.socket.emit("code:discover:directory",{path:t,depth:1,languages:s,ignore_patterns:i,show_hidden_files:o}),e.data.loaded="loading",this.updateBreadcrumb(`Loading ${e.data.name}...`,"info"),this.showNotification(`Loading directory: ${e.data.name}`,"info"))}this.selectedNode=e,this.highlightNode(e)}ensureFullPath(t){if(!t)return t;if(t.startsWith("/"))return t;const e=this.getWorkingDirectory();return e?"."===t||t===e?e:`${e}/${t}`.replace(/\/+/g,"/"):t}highlightNode(t){this.treeGroup.selectAll("circle.node-circle").style("stroke-width",2).classed("selected",!1),this.treeGroup.selectAll("circle.node-circle").filter(e=>e===t).style("stroke-width",4).classed("selected",!0)}diagonal(t,e){return`M ${t.y} ${t.x}\n C ${(t.y+e.y)/2} ${t.x},\n ${(t.y+e.y)/2} ${e.x},\n ${e.y} ${e.x}`}radialDiagonal(t,e){return d3.linkRadial().angle(t=>t.x).radius(t=>t.y)({source:t,target:e})}getNodeColor(t){const e=t.data.type,s=t.data.complexity||1,i={root:"#6B7280",directory:"#3B82F6",file:"#10B981",module:"#8B5CF6",class:"#F59E0B",function:"#EF4444",method:"#EC4899"}[e]||"#6B7280";return s>10?d3.color(i).darker(.5):s>5?d3.color(i).darker(.25):i}getNodeStrokeColor(t){return"loading"===t.data.loaded||"loading"===t.data.analyzed?"#FCD34D":"directory"!==t.data.type||t.data.loaded?"file"!==t.data.type||t.data.analyzed?this.getNodeColor(t):"#CBD5E1":"#94A3B8"}getNodeIcon(t){return{root:"📦",directory:"📁",file:"📄",module:"📦",class:"C",function:"ƒ",method:"m"}[t.data.type]||"•"}showTooltip(t,e){if(!this.tooltip)return;const s=[];s.push(`<strong>${e.data.name}</strong>`),s.push(`Type: ${e.data.type}`),e.data.language&&s.push(`Language: ${e.data.language}`),e.data.complexity&&s.push(`Complexity: ${e.data.complexity}`),e.data.lines&&s.push(`Lines: ${e.data.lines}`),e.data.path&&s.push(`Path: ${e.data.path}`),"directory"!==e.data.type||e.data.loaded?"file"!==e.data.type||e.data.analyzed||s.push("<em>Click to analyze file</em>"):s.push("<em>Click to explore contents</em>"),this.tooltip.transition().duration(200).style("opacity",.9),this.tooltip.html(s.join("<br>")).style("left",t.pageX+10+"px").style("top",t.pageY-28+"px")}hideTooltip(){this.tooltip&&this.tooltip.transition().duration(500).style("opacity",0)}filterTree(){this.root&&(this.root.descendants().forEach(t=>{t.data._hidden=!1,"all"!==this.languageFilter&&"file"===t.data.type&&t.data.language!==this.languageFilter&&(t.data._hidden=!0),this.searchTerm&&(t.data.name.toLowerCase().includes(this.searchTerm)||(t.data._hidden=!0))}),this.update(this.root))}expandAll(){if(!this.root)return;const t=e=>{e._children&&(e.children=e._children,e._children=null),e.children&&e.children.forEach(t)};t(this.root),this.update(this.root),this.showNotification("All nodes expanded","info")}collapseAll(){if(!this.root)return;const t=e=>{e.children&&(e._children=e.children,e.children=null),e._children&&e._children.forEach(t)};this.root.children?.forEach(t),this.update(this.root),this.showNotification("All nodes collapsed","info")}resetZoom(){this.svg&&this.zoom&&(this.svg.transition().duration(750).call(this.zoom.transform,d3.zoomIdentity),this.showNotification("Zoom reset","info"))}focusOnNode(t){if(!this.svg||!this.zoom||!t)return;const e=t.descendants?t.descendants():[t];if(this.isRadialLayout){const t=e.map(t=>t.x),s=e.map(t=>t.y),i=Math.min(...t),o=Math.max(...t),a=Math.min(...s),n=Math.max(...s),r=(i+o)/2,d=(a+n)/2,l=d*Math.cos(r-Math.PI/2),c=d*Math.sin(r-Math.PI/2),h=o-i,p=n-a;let u=1;if(h>0&&p>0){const t=2*Math.PI/h,e=this.radius/p;u=Math.min(t,e,3),u=Math.max(u,1)}this.svg.transition().duration(750).call(this.zoom.transform,d3.zoomIdentity.translate(this.width/2-l*u,this.height/2-c*u).scale(u))}else{const t=e.map(t=>t.x),s=e.map(t=>t.y),i=Math.min(...t),o=Math.max(...t),a=Math.min(...s),n=Math.max(...s),r=(i+o)/2,d=(a+n)/2,l=o-i,c=n-a,h=100;let p=1;if(l>0&&c>0){const t=(this.width-h)/l,e=(this.height-h)/c;p=Math.min(t,e,2.5),p=Math.max(p,.5)}this.svg.transition().duration(750).call(this.zoom.transform,d3.zoomIdentity.translate(this.width/2-r*p,this.height/2-d*p).scale(p))}const s=this.getNodePath(t);this.updateBreadcrumb(`Focused: ${s}`,"info")}getNodePath(t){const e=[];let s=t;for(;s;)s.data&&s.data.name&&e.unshift(s.data.name),s=s.parent;return e.join(" / ")}toggleLegend(){const t=document.getElementById("tree-legend");t&&("none"===t.style.display?t.style.display="block":t.style.display="none")}getWorkingDirectory(){if(window.dashboard&&window.dashboard.workingDirectoryManager)return window.dashboard.workingDirectoryManager.getCurrentWorkingDir();const t=document.getElementById("working-dir-path");if(t){const e=t.textContent.trim();if(e&&"Loading..."!==e&&"Not selected"!==e)return e}return null}showNoWorkingDirectoryMessage(){const t=document.getElementById("code-tree-container");if(!t)return;this.removeNoWorkingDirectoryMessage(),this.hideLoading();const e=document.createElement("div");e.id="no-working-dir-message",e.className="no-working-dir-message",e.innerHTML='\n <div class="message-icon">📁</div>\n <h3>No Working Directory Selected</h3>\n <p>Please select a working directory from the top menu to analyze code.</p>\n <button id="select-working-dir-btn" class="btn btn-primary">\n Select Working Directory\n </button>\n ',e.style.cssText="\n text-align: center;\n padding: 40px;\n color: #666;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n ";const s=e.querySelector(".message-icon");s&&(s.style.cssText="font-size: 48px; margin-bottom: 16px; opacity: 0.5;");const i=e.querySelector("h3");i&&(i.style.cssText="margin: 16px 0; color: #333; font-size: 20px;");const o=e.querySelector("p");o&&(o.style.cssText="margin: 16px 0; color: #666; font-size: 14px;");const a=e.querySelector("button");a&&(a.style.cssText="\n margin-top: 20px;\n padding: 10px 20px;\n background: #3b82f6;\n color: white;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n transition: background 0.2s;\n ",a.addEventListener("mouseenter",()=>{a.style.background="#2563eb"}),a.addEventListener("mouseleave",()=>{a.style.background="#3b82f6"}),a.addEventListener("click",()=>{const t=document.getElementById("change-dir-btn");t?t.click():window.dashboard&&window.dashboard.workingDirectoryManager&&window.dashboard.workingDirectoryManager.showChangeDirDialog()})),t.appendChild(e),this.updateBreadcrumb("Please select a working directory","warning")}removeNoWorkingDirectoryMessage(){const t=document.getElementById("no-working-dir-message");t&&t.remove()}exportTree(){const t={timestamp:(new Date).toISOString(),workingDirectory:this.getWorkingDirectory(),stats:this.stats,tree:this.treeData},e=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),s=URL.createObjectURL(e),i=document.createElement("a");i.href=s,i.download=`code-tree-${Date.now()}.json`,i.click(),URL.revokeObjectURL(s),this.showNotification("Tree exported successfully","success")}updateActivityTicker(t,e="info"){const s=document.getElementById("breadcrumb-content");if(s){const i="info"===e&&t.includes("...")?"⟳ ":"";s.innerHTML=`${i}${t}`,s.className=`breadcrumb-${e}`}}updateTicker(t,e="info"){const s=document.getElementById("code-tree-ticker");s&&(s.textContent=t,s.className=`ticker ticker-${e}`,"error"!==e&&setTimeout(()=>{s.style.opacity="0",setTimeout(()=>{s.style.opacity="1",s.textContent=""},300)},5e3))}}window.CodeTree=t,document.addEventListener("DOMContentLoaded",()=>{document.getElementById("code-tree-container")&&(window.codeTree=new t,document.addEventListener("click",t=>{t.target.matches('[data-tab="code"]')&&setTimeout(()=>{window.codeTree&&!window.codeTree.initialized?window.codeTree.initialize():window.codeTree&&window.codeTree.renderWhenVisible()},100)}))});
1
+ class t{constructor(){this.container=null,this.svg=null,this.treeData=null,this.root=null,this.treeLayout=null,this.treeGroup=null,this.nodes=new Map,this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.isRadialLayout=!0,this.margin={top:20,right:20,bottom:20,left:20},this.width=960-this.margin.left-this.margin.right,this.height=600-this.margin.top-this.margin.bottom,this.radius=Math.min(this.width,this.height)/2,this.nodeId=0,this.duration=750,this.languageFilter="all",this.searchTerm="",this.tooltip=null,this.initialized=!1,this.analyzing=!1,this.selectedNode=null,this.socket=null,this.autoDiscovered=!1,this.zoom=null,this.activeNode=null,this.loadingNodes=new Set}initialize(){if(this.initialized)return;if(this.container=document.getElementById("code-tree-container"),!this.container)return void console.error("Code tree container not found");const t=document.getElementById("code-tab");if(!t)return void console.error("Code tab panel not found");const e=this.getWorkingDirectory();if(!e||"Loading..."===e||"Not selected"===e)return this.showNoWorkingDirectoryMessage(),void(this.initialized=!0);this.setupControls(),this.initializeTreeData(),this.subscribeToEvents();document.getElementById("breadcrumb-content")&&!this.analyzing&&this.updateActivityTicker("Loading project structure...","info"),t.classList.contains("active")&&(this.createVisualization(),this.root&&this.svg&&this.update(this.root),this.autoDiscoverRootLevel()),this.initialized=!0}renderWhenVisible(){const t=this.getWorkingDirectory();t&&"Loading..."!==t&&"Not selected"!==t?(this.removeNoWorkingDirectoryMessage(),this.initialized?(this.svg?this.root&&this.svg&&this.update(this.root):(this.createVisualization(),this.svg&&this.treeGroup&&this.update(this.root)),this.autoDiscovered||this.autoDiscoverRootLevel()):this.initialize()):this.showNoWorkingDirectoryMessage()}setupControls(){const t=document.getElementById("language-filter");t&&t.addEventListener("change",t=>{this.languageFilter=t.target.value,this.filterTree()});const e=document.getElementById("code-search");e&&e.addEventListener("input",t=>{this.searchTerm=t.target.value.toLowerCase(),this.filterTree()});const i=document.getElementById("code-expand-all");i&&i.addEventListener("click",()=>this.expandAll());const s=document.getElementById("code-collapse-all");s&&s.addEventListener("click",()=>this.collapseAll());const o=document.getElementById("code-reset-zoom");o&&o.addEventListener("click",()=>this.resetZoom());const n=document.getElementById("code-toggle-legend");n&&n.addEventListener("click",()=>this.toggleLegend()),document.addEventListener("workingDirectoryChanged",t=>{this.onWorkingDirectoryChanged(t.detail.directory)})}onWorkingDirectoryChanged(t){if(!t||"Loading..."===t||"Not selected"===t)return this.showNoWorkingDirectoryMessage(),this.autoDiscovered=!1,this.analyzing=!1,this.nodes.clear(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},void this.updateStats();this.removeNoWorkingDirectoryMessage(),this.autoDiscovered=!1,this.analyzing=!1,this.nodes.clear(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.initializeTreeData(),this.svg&&this.update(this.root);const e=document.getElementById("code-tab");e&&e.classList.contains("active")&&this.autoDiscoverRootLevel(),this.updateStats()}showLoading(){let t=document.getElementById("code-tree-loading");if(!t){const e=document.getElementById("code-tree-container");e&&(t=document.createElement("div"),t.id="code-tree-loading",t.innerHTML='\n <div class="code-tree-spinner"></div>\n <div class="code-tree-loading-text">Analyzing code structure...</div>\n ',e.appendChild(t))}t&&t.classList.remove("hidden")}hideLoading(){const t=document.getElementById("code-tree-loading");t&&t.classList.add("hidden")}createVisualization(){if("undefined"==typeof d3)return void console.error("D3.js is not loaded");const t=d3.select("#code-tree-container");if(t.selectAll("*").remove(),!t||!t.node())return void console.error("Code tree container not found");const e=t.node(),i=e.clientWidth||960,s=e.clientHeight||600;this.width=i-this.margin.left-this.margin.right,this.height=s-this.margin.top-this.margin.bottom,this.radius=Math.min(this.width,this.height)/2,this.svg=t.append("svg").attr("width",i).attr("height",s);const o=i/2,n=s/2;this.isRadialLayout?this.treeGroup=this.svg.append("g").attr("transform",`translate(${o},${n})`):this.treeGroup=this.svg.append("g").attr("transform",`translate(${this.margin.left+100},${n})`),this.isRadialLayout?this.treeLayout=d3.cluster().size([2*Math.PI,this.radius-100]).separation((t,e)=>{if(t.parent==e.parent){const e=Math.max(1,4-t.depth),i=t.parent&&t.parent.children?.length||1,s=i>5?2:i>3?1.5:1,o=1+.2*t.depth;return e*s/(t.depth||1)*o}return 4/(t.depth||1)}):this.treeLayout=d3.tree().nodeSize([30,200]).separation((t,e)=>t.parent==e.parent?1:1.5),this.zoom=d3.zoom().scaleExtent([.1,10]).on("zoom",t=>{this.isRadialLayout?this.treeGroup.attr("transform",`translate(${o+t.transform.x},${n+t.transform.y}) scale(${t.transform.k})`):this.treeGroup.attr("transform",`translate(${this.margin.left+100+t.transform.x},${n+t.transform.y}) scale(${t.transform.k})`)}),this.svg.call(this.zoom),this.addVisualizationControls(),this.tooltip=d3.select("body").append("div").attr("class","code-tree-tooltip").style("opacity",0).style("position","absolute").style("background","rgba(0, 0, 0, 0.8)").style("color","white").style("padding","8px").style("border-radius","4px").style("font-size","12px").style("pointer-events","none")}clearD3Visualization(){this.treeGroup&&(this.treeGroup.selectAll("g.node").remove(),this.treeGroup.selectAll("path.link").remove()),this.nodeId=0}initializeTreeData(){const t=this.getWorkingDirectory(),e=t&&t.split("/").pop()||"Project Root";this.treeData={name:e,path:".",type:"root",children:[],loaded:!1,expanded:!0},"undefined"!=typeof d3&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0)}subscribeToEvents(){this.socket||(window.socket?(this.socket=window.socket,this.setupEventHandlers()):window.dashboard?.socketClient?.socket?(this.socket=window.dashboard.socketClient.socket,this.setupEventHandlers()):window.socketClient?.socket&&(this.socket=window.socketClient.socket,this.setupEventHandlers()))}autoDiscoverRootLevel(){if(this.autoDiscovered||this.analyzing)return;this.updateActivityTicker("🔍 Discovering project structure...","info");const t=this.getWorkingDirectory();if(!t||"Loading..."===t||"Not selected"===t)return console.warn("Cannot auto-discover: no working directory set"),void this.showNoWorkingDirectoryMessage();if(!t.startsWith("/")&&!t.match(/^[A-Z]:\\/))return console.error("Working directory is not absolute:",t),void this.showNotification("Invalid working directory path","error");this.autoDiscovered=!0,this.analyzing=!0,this.nodes.clear(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.socket&&!this.socket.hasListeners("code:node:found")&&this.setupEventHandlers();const e=t.split("/").pop()||"Project Root";this.treeData={name:e,path:".",type:"root",children:[],loaded:!1,expanded:!0},"undefined"!=typeof d3&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0),this.showLoading(),this.updateBreadcrumb(`Discovering structure in ${e}...`,"info");const i=[];document.querySelectorAll(".language-checkbox:checked").forEach(t=>{i.push(t.value)});const s=document.getElementById("ignore-patterns")?.value||"",o={path:t,depth:"top_level",languages:i,ignore_patterns:s,request_id:`discover_${Date.now()}`};this.socket&&this.socket.emit("code:discover:top_level",o),this.updateStats()}analyzeCode(){this.analyzing||this.autoDiscoverRootLevel()}cancelAnalysis(){this.analyzing=!1,this.hideLoading(),this.socket&&this.socket.emit("code:analysis:cancel"),this.updateBreadcrumb("Analysis cancelled","warning"),this.showNotification("Analysis cancelled","warning"),this.addEventToDisplay("Analysis cancelled","warning")}createEventsDisplay(){let t=document.getElementById("analysis-events");if(!t){const e=document.getElementById("code-tree-container");e&&(t=document.createElement("div"),t.id="analysis-events",t.className="analysis-events",t.style.display="none",e.appendChild(t))}}clearEventsDisplay(){const t=document.getElementById("analysis-events");t&&(t.innerHTML="",t.style.display="block")}addEventToDisplay(t,e="info"){const i=document.getElementById("analysis-events");if(i){const s=document.createElement("div");s.className="analysis-event",s.style.borderLeftColor="warning"===e?"#f59e0b":"error"===e?"#ef4444":"#3b82f6";const o=(new Date).toLocaleTimeString();s.innerHTML=`<span style="color: #718096;">[${o}]</span> ${t}`,i.appendChild(s),i.scrollTop=i.scrollHeight}}setupEventHandlers(){this.socket&&(this.socket.on("code:analysis:accepted",t=>this.onAnalysisAccepted(t)),this.socket.on("code:analysis:queued",t=>this.onAnalysisQueued(t)),this.socket.on("code:analysis:start",t=>this.onAnalysisStart(t)),this.socket.on("code:analysis:complete",t=>this.onAnalysisComplete(t)),this.socket.on("code:analysis:cancelled",t=>this.onAnalysisCancelled(t)),this.socket.on("code:analysis:error",t=>this.onAnalysisError(t)),this.socket.on("code:top_level:discovered",t=>this.onTopLevelDiscovered(t)),this.socket.on("code:directory:discovered",t=>this.onDirectoryDiscovered(t)),this.socket.on("code:file:discovered",t=>this.onFileDiscovered(t)),this.socket.on("code:file:analyzed",t=>this.onFileAnalyzed(t)),this.socket.on("code:node:found",t=>this.onNodeFound(t)),this.socket.on("code:analysis:progress",t=>this.onProgressUpdate(t)),this.socket.on("code:directory:contents",t=>{if(t.path){let e=t.path;const i=this.getWorkingDirectory();i&&e.startsWith(i)&&(e=e.substring(i.length).replace(/^\//,""),e||(e="."));const s=this.findNodeByPath(e);if(s&&t.children){const i=this.findD3NodeByPath(e);if(i&&this.loadingNodes.has(e)&&this.removeLoadingPulse(i),s.children=t.children.map(t=>{let i;if("."===e||""===e)i=t.name||t.path;else{const s=t.name||t.path;i=`${e}/${s}`}return{...t,path:i,loaded:"directory"!==t.type&&void 0,analyzed:"file"!==t.type&&void 0,expanded:!1,children:[]}}),s.loaded=!0,s.expanded=!0,this.root&&this.svg){const t=this.root;this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.preserveExpansionState(t,this.root);const i=this.findD3NodeByPath(e);i&&(i.children=i._children||i.children,i._children=null,i.data.expanded=!0),this.update(this.root)}t.stats&&(this.stats.files+=t.stats.files||0,this.stats.directories+=t.stats.directories||0,this.updateStats()),this.updateBreadcrumb(`Loaded ${t.path}`,"success"),this.hideLoading()}}}),this.socket.on("code:top_level:discovered",t=>{t.items&&Array.isArray(t.items)&&(this.treeData.children=t.items.map(t=>({name:t.name,path:t.path,type:t.type,language:"file"===t.type?this.detectLanguage(t.path):void 0,size:t.size,lines:t.lines,loaded:"directory"!==t.type&&void 0,analyzed:"file"!==t.type&&void 0,expanded:!1,children:[]})),this.treeData.loaded=!0,t.stats&&(this.stats={...this.stats,...t.stats},this.updateStats()),"undefined"!=typeof d3&&(this.clearD3Visualization(),this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.svg&&this.update(this.root)),this.analyzing=!1,this.hideLoading(),this.updateBreadcrumb(`Discovered ${t.items.length} root items`,"success"),this.showNotification(`Found ${t.items.length} items in project root`,"success"))}))}onAnalysisStart(t){this.analyzing=!0;const e=t.message||"Starting code analysis...";this.updateActivityTicker("🚀 Starting analysis...","info"),this.updateBreadcrumb(e,"info"),this.addEventToDisplay(`🚀 ${e}`,"info"),this.treeData&&0!==this.treeData.children.length||this.initializeTreeData(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.updateStats()}onTopLevelDiscovered(t){this.updateActivityTicker(`📁 Discovered ${(t.items||[]).length} top-level items`,"success"),this.addEventToDisplay(`📁 Found ${(t.items||[]).length} top-level items in project root`,"info");const e=this.findNodeByPath(".");console.log('🔎 Looking for root node with path ".", found:',e?{name:e.name,path:e.path,currentChildren:e.children?e.children.length:0}:"NOT FOUND"),e&&t.items?(console.log("🌳 Populating root node with children"),e.children=t.items.map(t=>{const e=t.name;return console.log(` Adding child: ${t.name} with path: ${e}`),{name:t.name,path:e,type:t.type,loaded:"directory"!==t.type&&void 0,analyzed:"file"!==t.type&&void 0,expanded:!1,children:"directory"===t.type?[]:void 0,size:t.size,has_code:t.has_code}}),e.loaded=!0,e.expanded=!0,this.root&&this.svg&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.update(this.root)),this.hideLoading(),this.updateBreadcrumb(`Discovered ${t.items.length} items`,"success"),this.showNotification(`Found ${t.items.length} top-level items`,"success")):(console.error("❌ Could not find root node to populate"),this.showNotification("Failed to populate root directory","error")),this.analyzing=!1}onDirectoryDiscovered(t){this.updateActivityTicker(`📁 Discovered: ${t.name||"directory"}`),this.addEventToDisplay(`📁 Found ${(t.children||[]).length} items in: ${t.name||t.path}`,"info"),console.log("📥 Received directory discovery:",{path:t.path,name:t.name,childrenCount:(t.children||[]).length,children:(t.children||[]).map(t=>({name:t.name,type:t.type})),workingDir:this.getWorkingDirectory()});let e=t.path;const i=this.getWorkingDirectory();i&&e.startsWith(i)&&(e=e.substring(i.length).replace(/^\//,""),e||(e=".")),console.log("🔎 Searching for node with path:",e);const s=this.findNodeByPath(e);if(s&&t.children){s.children=t.children.map(t=>{let i;if("."===e||""===e)i=t.name||t.path;else{const s=t.name||t.path;i=`${e}/${s}`}return{name:t.name,path:i,type:t.type,loaded:"directory"!==t.type&&void 0,analyzed:"file"!==t.type&&void 0,expanded:!1,children:"directory"===t.type?[]:void 0,size:t.size,has_code:t.has_code}}),s.loaded=!0,s.expanded=!0;const i=this.findD3NodeByPath(e);if(i&&this.loadingNodes.has(e)&&this.removeLoadingPulse(i),this.root&&this.svg){const t=this.root;this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.preserveExpansionState(t,this.root);const i=this.findD3NodeByPath(e);i&&i.data.children&&i.data.children.length>0&&(i.children=i._children||i.children,i._children=null,i.data.expanded=!0),this.update(this.root)}this.updateBreadcrumb(`Loaded ${s.children.length} items from ${s.name}`,"success"),this.updateStats()}else if(s){if(s&&!t.children){const e=t.path?t.path.split("/").filter(t=>t):[];if(1===e.length||t.forceAdd){const i={name:t.name||e[e.length-1]||"Unknown",path:t.path,type:"directory",children:[],loaded:!1,expanded:!1,stats:t.stats||{}};this.addNodeToTree(i,t.parent||""),this.updateBreadcrumb(`Discovered: ${t.path}`,"info")}}}else this.logAllPaths(this.treeData)}onFileDiscovered(t){const e=t.name||(t.path?t.path.split("/").pop():"file");this.updateActivityTicker(`📄 Found: ${e}`),this.addEventToDisplay(`📄 Discovered: ${t.path||"Unknown file"}`,"info");const i=t.path?t.path.split("/").filter(t=>t):[],s=i.slice(0,-1).join("/"),o={name:t.name||i[i.length-1]||"Unknown",path:t.path,type:"file",language:t.language||this.detectLanguage(t.path),size:t.size||0,lines:t.lines||0,children:[],analyzed:!1};this.addNodeToTree(o,s),this.stats.files++,this.updateStats(),this.updateBreadcrumb(`Found: ${t.path}`,"info")}onFileAnalyzed(t){const e=this.findD3NodeByPath(t.path);if(e&&this.loadingNodes.has(t.path)&&this.removeLoadingPulse(e),t.path){const e=t.path.split("/").pop();this.updateActivityTicker(`🔍 Analyzed: ${e}`)}const i=this.findNodeByPath(t.path);i&&(i.analyzed=!0,i.complexity=t.complexity||0,i.lines=t.lines||0,t.elements&&Array.isArray(t.elements)&&(i.children=t.elements.map(e=>({name:e.name,type:e.type.toLowerCase(),path:`${t.path}#${e.name}`,line:e.line,complexity:e.complexity||1,docstring:e.docstring||"",children:e.methods?e.methods.map(i=>({name:i.name,type:"method",path:`${t.path}#${e.name}.${i.name}`,line:i.line,complexity:i.complexity||1,docstring:i.docstring||""})):[]}))),t.stats&&(this.stats.classes+=t.stats.classes||0,this.stats.functions+=t.stats.functions||0,this.stats.methods+=t.stats.methods||0,this.stats.lines+=t.stats.lines||0),this.updateStats(),this.root&&this.update(this.root),this.updateBreadcrumb(`Analyzed: ${t.path}`,"success"))}onNodeFound(t){const e="class"===t.type?"🏛️":"function"===t.type?"⚡":"method"===t.type?"🔧":"📦";this.addEventToDisplay(`${e} Found ${t.type||"node"}: ${t.name||"Unknown"}`);const i={name:t.name||"Unknown",type:(t.type||"unknown").toLowerCase(),path:t.path||"",line:t.line||0,complexity:t.complexity||1,docstring:t.docstring||""};i.type={class:"class",function:"function",method:"method",module:"module",file:"file",directory:"directory"}[i.type]||i.type;let s="";if(t.parent_path)s=t.parent_path;else if(t.file_path)s=t.file_path;else if(i.path.includes("/")){const t=i.path.split("/");t.pop(),s=t.join("/")}switch(i.type){case"class":this.stats.classes++;break;case"function":this.stats.functions++;break;case"method":this.stats.methods++;break;case"file":this.stats.files++}this.addNodeToTree(i,s),this.updateStats();const o=i.type.charAt(0).toUpperCase()+i.type.slice(1);this.updateBreadcrumb(`Found ${o}: ${i.name}`,"info")}onProgressUpdate(t){const e=t.progress||0,i=t.message||`Processing... ${e}%`;this.updateBreadcrumb(i,"info");const s=document.querySelector(".code-tree-progress");s&&(s.style.width=`${e}%`)}onAnalysisComplete(t){this.analyzing=!1,this.hideLoading(),this.updateActivityTicker("✅ Ready","success"),this.addEventToDisplay("✅ Analysis complete!","success"),this.root&&this.svg&&this.update(this.root),t.stats&&(this.stats={...this.stats,...t.stats},this.updateStats());const e=t.message||`Analysis complete: ${this.stats.files} files, ${this.stats.classes} classes, ${this.stats.functions} functions`;this.updateBreadcrumb(e,"success"),this.showNotification(e,"success")}onAnalysisError(t){this.analyzing=!1,this.hideLoading();const e=t.message||t.error||"Analysis failed";this.updateBreadcrumb(e,"error"),this.showNotification(e,"error")}onAnalysisAccepted(t){const e=t.message||"Analysis request accepted";this.updateBreadcrumb(e,"info")}onAnalysisQueued(t){const e=`Analysis queued (position ${t.position||0})`;this.updateBreadcrumb(e,"warning"),this.showNotification(e,"info")}onInfoEvent(t){t.type&&t.type.startsWith("discovery.")?"discovery.start"===t.type?this.updateBreadcrumb(t.message,"info"):"discovery.complete"===t.type?(this.updateBreadcrumb(t.message,"success"),t.stats):"discovery.directory"!==t.type&&"discovery.file"!==t.type||this.updateBreadcrumb(t.message,"info"):t.type&&t.type.startsWith("analysis.")?"analysis.start"===t.type?this.updateBreadcrumb(t.message,"info"):"analysis.complete"===t.type?(this.updateBreadcrumb(t.message,"success"),t.stats&&(t.stats.classes,t.stats.functions,t.stats.methods)):("analysis.class"===t.type||"analysis.function"===t.type||"analysis.method"===t.type||"analysis.parse"===t.type)&&this.updateBreadcrumb(t.message,"info"):t.type&&t.type.startsWith("filter.")?(window.debugMode||this.showFilterEvents)&&(console.debug("[FILTER]",t.type,t.path,t.reason),this.showFilterEvents&&this.updateBreadcrumb(t.message,"warning")):t.type&&t.type.startsWith("cache.")&&("cache.hit"===t.type?(console.debug("[CACHE HIT]",t.file),this.showCacheEvents&&this.updateBreadcrumb(t.message,"info")):"cache.miss"===t.type&&console.debug("[CACHE MISS]",t.file)),this.eventLogEnabled&&t.message&&this.addEventToDisplay(t)}addEventToDisplay(t){this.recentEvents||(this.recentEvents=[]),this.recentEvents.unshift({timestamp:t.timestamp||(new Date).toISOString(),type:t.type,message:t.message,data:t}),this.recentEvents.length>100&&this.recentEvents.pop()}onAnalysisCancelled(t){this.analyzing=!1,this.hideLoading();const e=t.message||"Analysis cancelled";this.updateBreadcrumb(e,"warning")}showNotification(t,e="info"){const i=document.createElement("div");i.className=`code-tree-notification ${e}`,i.textContent=t;const s=document.getElementById("code-tree-container");s&&(i.style.position="absolute",i.style.top="10px",i.style.right="10px",i.style.zIndex="1000",s.style.position&&"static"!==s.style.position||(s.style.position="relative"),s.appendChild(i),setTimeout(()=>{i.style.animation="slideOutRight 0.3s ease",setTimeout(()=>i.remove(),300)},3e3))}addNodeToTree(t,e=""){if(t.path&&t.path.startsWith("/"))return void console.error("Absolute path detected in node, skipping:",t.path);if(e&&e.startsWith("/"))return void console.error("Absolute path detected in parent, skipping:",e);let i=this.treeData;if(e&&(i=this.findNodeByPath(e),!i))return console.warn("Parent node not found, skipping node creation:",e),void console.warn("Attempted to add node:",t);const s=i.children?.find(e=>e.path===t.path||e.name===t.name&&e.type===t.type);s?Object.assign(s,t):(i.children||(i.children=[]),t.children||(t.children=[]),i.children.push(t),this.nodes.set(t.path,t),this.root&&this.svg&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,(this.nodes.size<1e3||this.nodes.size%100==0)&&this.update(this.root)))}findNodeByPath(t,e=null){if(e||(e=this.treeData),e.path===t)return e;if(e.children)for(const i of e.children){const e=this.findNodeByPath(t,i);if(e)return e}return e.parent,null}logAllPaths(t,e=""){if(console.log(`${e}${t.path} (${t.name})`),t.children)for(const i of t.children)this.logAllPaths(i,e+" ")}findD3NodeByPath(t){return this.root?this.root.descendants().find(e=>e.data.path===t):null}preserveExpansionState(t,e){if(!t||!e)return;const i=new Map;t.descendants().forEach(t=>{(t.data.expanded||t.children&&!t._children)&&i.set(t.data.path,!0)}),e.descendants().forEach(t=>{i.has(t.data.path)&&(t.children=t._children||t.children,t._children=null,t.data.expanded=!0)})}updateStats(){const t={"file-count":this.stats.files,"class-count":this.stats.classes,"function-count":this.stats.functions,"line-count":this.stats.lines};for(const[i,s]of Object.entries(t)){const t=document.getElementById(i);t&&(t.textContent=s.toLocaleString())}const e=document.getElementById("code-progress-text");if(e){const t=this.analyzing?`Analyzing... ${this.stats.files} files processed`:`Ready - ${this.stats.files} files in tree`;e.textContent=t}}updateBreadcrumb(t,e="info"){const i=document.getElementById("breadcrumb-content");i&&(i.textContent=t,i.className=`breadcrumb-${e}`)}detectLanguage(t){return{py:"python",js:"javascript",ts:"typescript",jsx:"javascript",tsx:"typescript",java:"java",cpp:"cpp",c:"c",cs:"csharp",rb:"ruby",go:"go",rs:"rust",php:"php",swift:"swift",kt:"kotlin",scala:"scala",r:"r",sh:"bash",ps1:"powershell"}[t.split(".").pop().toLowerCase()]||"unknown"}addVisualizationControls(){const t=this.svg.append("g").attr("class","viz-controls").attr("transform","translate(10, 10)").append("g").attr("class","layout-toggle").style("cursor","pointer").on("click",()=>this.toggleLayout());t.append("rect").attr("width",120).attr("height",30).attr("rx",5).attr("fill","#3b82f6").attr("opacity",.8),t.append("text").attr("x",60).attr("y",20).attr("text-anchor","middle").attr("fill","white").style("font-size","12px").text(this.isRadialLayout?"Switch to Linear":"Switch to Radial")}toggleLayout(){this.isRadialLayout=!this.isRadialLayout,this.createVisualization(),this.root&&this.update(this.root),this.showNotification(this.isRadialLayout?"Switched to radial layout":"Switched to linear layout","info")}radialPoint(t,e){return[(e=+e)*Math.cos(t-=Math.PI/2),e*Math.sin(t)]}update(t){if(!this.treeLayout||!this.treeGroup||!t)return;const e=this.treeLayout(this.root),i=e.descendants(),s=e.descendants().slice(1);this.isRadialLayout&&i.forEach(t=>{void 0===t.x0&&(t.x0=t.x,t.y0=t.y)});const o=this.treeGroup.selectAll("g.node").data(i,t=>t.id||(t.id=++this.nodeId)),n=o.enter().append("g").attr("class","node").attr("transform",e=>{if(this.isRadialLayout){const[e,i]=this.radialPoint(t.x0||0,t.y0||0);return`translate(${e},${i})`}return`translate(${t.y0},${t.x0})`}).on("click",(t,e)=>this.onNodeClick(t,e));n.append("circle").attr("class","node-circle").attr("r",1e-6).style("fill",t=>this.getNodeColor(t)).style("stroke",t=>this.getNodeStrokeColor(t)).style("stroke-width",2).on("mouseover",(t,e)=>this.showTooltip(t,e)).on("mouseout",()=>this.hideTooltip()),n.append("text").attr("class","node-label").attr("dy",".35em").attr("x",t=>this.isRadialLayout?0:t.children||t._children?-13:13).attr("text-anchor",t=>this.isRadialLayout?"start":t.children||t._children?"end":"start").text(t=>{const e=t.data.name||"";return e.length>20?e.substring(0,17)+"...":e}).style("fill-opacity",1e-6).style("font-size","12px").style("font-family",'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif').style("text-shadow","1px 1px 2px rgba(255,255,255,0.8), -1px -1px 2px rgba(255,255,255,0.8)"),n.append("text").attr("class","node-icon").attr("dy",".35em").attr("x",0).attr("text-anchor","middle").text(t=>this.getNodeIcon(t)).style("font-size","10px").style("fill","white");const a=n.merge(o);a.transition().duration(this.duration).attr("transform",t=>{if(this.isRadialLayout){const[e,i]=this.radialPoint(t.x,t.y);return`translate(${e},${i})`}return`translate(${t.y},${t.x})`}),a.select("circle.node-circle").attr("r",8).style("fill",t=>this.getNodeColor(t)).style("stroke",t=>this.getNodeStrokeColor(t)).attr("cursor","pointer");const r=this.isRadialLayout;a.select("text.node-label").style("fill-opacity",1).style("fill","#333").each(function(t){const e=d3.select(this);if(r){const i=180*t.x/Math.PI-90;i>90||i<-90?e.attr("transform",`rotate(${i+180})`).attr("x",-15).attr("text-anchor","end").attr("dy",".35em"):e.attr("transform",`rotate(${i})`).attr("x",15).attr("text-anchor","start").attr("dy",".35em")}else e.attr("transform",null).attr("x",t.children||t._children?-13:13).attr("text-anchor",t.children||t._children?"end":"start").attr("dy",".35em")});const d=o.exit().transition().duration(this.duration).attr("transform",e=>{if(this.isRadialLayout){const[e,i]=this.radialPoint(t.x,t.y);return`translate(${e},${i})`}return`translate(${t.y},${t.x})`}).remove();d.select("circle").attr("r",1e-6),d.select("text.node-label").style("fill-opacity",1e-6),d.select("text.node-icon").style("fill-opacity",1e-6);const l=this.treeGroup.selectAll("path.link").data(s,t=>t.id);l.enter().insert("path","g").attr("class","link").attr("d",e=>{const i={x:t.x0,y:t.y0};return this.isRadialLayout?this.radialDiagonal(i,i):this.diagonal(i,i)}).style("fill","none").style("stroke","#ccc").style("stroke-width",2).merge(l).transition().duration(this.duration).attr("d",t=>this.isRadialLayout?this.radialDiagonal(t,t.parent):this.diagonal(t,t.parent)),l.exit().transition().duration(this.duration).attr("d",e=>{const i={x:t.x,y:t.y};return this.isRadialLayout?this.radialDiagonal(i,i):this.diagonal(i,i)}).remove(),i.forEach(t=>{t.x0=t.x,t.y0=t.y})}centerOnNode(t){if(!this.svg||!this.zoom)return;const e=d3.zoomTransform(this.svg.node()),i=e.k<2?2:e.k,s=this.margin.left+100,o=this.height/2,n=s-t.y*i+this.width/2,a=o-t.x*i+this.height/2;this.svg.transition().duration(750).call(this.zoom.transform,d3.zoomIdentity.translate(n,a).scale(i))}centerOnNodeRadial(t){if(!this.svg||!this.zoom)return;const[e,i]=this.radialPoint(t.x,t.y),s=d3.zoomTransform(this.svg.node()),o=s.k<2?2:s.k,n=this.width/2-e*o,a=this.height/2-i*o;this.svg.transition().duration(750).call(this.zoom.transform,d3.zoomIdentity.translate(n,a).scale(o))}highlightActiveNode(t){const e=this.treeGroup.selectAll("circle.node-circle");e.classed("active",!1).classed("parent-context",!1),e.transition().duration(300).attr("r",8).style("stroke",null).style("stroke-width",null).style("opacity",null),this.treeGroup.selectAll("text.node-label").style("font-weight","normal").style("font-size","12px");const i=this.treeGroup.selectAll("g.node").filter(e=>e===t).select("circle.node-circle");i.classed("active",!0),i.transition().duration(300).attr("r",20).style("stroke","#3b82f6").style("stroke-width",5).style("filter","drop-shadow(0 0 15px rgba(59, 130, 246, 0.6))"),this.treeGroup.selectAll("g.node").filter(e=>e===t).select("text.node-label").style("font-weight","bold").style("font-size","14px"),this.activeNode=t}addLoadingPulse(t){const e=this.treeGroup.selectAll("g.node").filter(e=>e===t).select("circle.node-circle");this.loadingNodes.add(t.data.path),e.classed("loading-pulse",!0),e.style("fill","#fb923c");const i=()=>{this.loadingNodes.has(t.data.path)&&e.transition().duration(600).attr("r",14).style("opacity",.6).transition().duration(600).attr("r",10).style("opacity",1).on("end",()=>{this.loadingNodes.has(t.data.path)&&i()})};i()}removeLoadingPulse(t){this.loadingNodes.delete(t.data.path);const e=this.treeGroup.selectAll("g.node").filter(e=>e===t).select("circle.node-circle");e.classed("loading-pulse",!1),e.interrupt().transition().duration(300).attr("r",this.activeNode===t?20:8).style("opacity",1).style("fill",t=>this.getNodeColor(t))}showWithParent(t){if(!t.parent)return;const e=this.treeGroup.selectAll("g.node").filter(e=>e===t.parent).select("circle.node-circle");if(e.classed("parent-context",!0),e.style("stroke","#10b981").style("stroke-width",3).style("opacity",.8),this.isRadialLayout&&t.parent){const e=[t,t.parent];t.children?e.push(...t.children):t._children&&e.push(...t._children);const i=e.map(t=>t.x),s=e.map(t=>t.y),o=Math.min(...i),n=Math.max(...i),a=Math.max(...s),r=n-o,d=Math.min(r>0?2*Math.PI/(2*r):2.5,this.width/(2*a),2.5),l=(o+n)/2,c=a/2,h=c*Math.cos(l-Math.PI/2),p=c*Math.sin(l-Math.PI/2);this.svg.transition().duration(750).call(this.zoom.transform,d3.zoomIdentity.translate(this.width/2-h*d,this.height/2-p*d).scale(d))}}onNodeClick(t,e){if(t)try{"function"==typeof t.stopPropagation&&t.stopPropagation()}catch(n){console.error("[CodeTree] ERROR calling stopPropagation:",n)}if(!e)return void console.error("[CodeTree] ERROR: d is null/undefined, cannot continue");if(!e.data)return void console.error("[CodeTree] ERROR: d.data is null/undefined, cannot continue");try{this.isRadialLayout?"function"==typeof this.centerOnNodeRadial?this.centerOnNodeRadial(e):console.error("[CodeTree] centerOnNodeRadial is not a function!"):"function"==typeof this.centerOnNode?this.centerOnNode(e):console.error("[CodeTree] centerOnNode is not a function!")}catch(n){console.error("[CodeTree] ERROR during centering:",n,n.stack)}try{"function"==typeof this.highlightActiveNode?this.highlightActiveNode(e):console.error("[CodeTree] highlightActiveNode is not a function!")}catch(n){console.error("[CodeTree] ERROR during highlightActiveNode:",n,n.stack)}try{"function"==typeof this.showWithParent?this.showWithParent(e):console.error("[CodeTree] showWithParent is not a function!")}catch(n){console.error("[CodeTree] ERROR during showWithParent:",n,n.stack)}if("directory"===e.data.type&&!e.data.loaded)try{"function"==typeof this.addLoadingPulse?this.addLoadingPulse(e):console.error("[CodeTree] addLoadingPulse is not a function!")}catch(n){console.error("[CodeTree] ERROR during addLoadingPulse:",n,n.stack)}const i=[];document.querySelectorAll(".language-checkbox:checked").forEach(t=>{i.push(t.value)});const s=document.getElementById("ignore-patterns"),o=s?.value||"";if("directory"!==e.data.type||e.data.loaded)if("file"!==e.data.type||e.data.analyzed)if("directory"===e.data.type&&!0===e.data.loaded){if(e.children)e._children=e.children,e.children=null,e.data.expanded=!1;else if(e._children)e.children=e._children,e._children=null,e.data.expanded=!0;else if(e.data.children&&e.data.children.length>0){this.root=d3.hierarchy(this.treeData);const t=this.findD3NodeByPath(e.data.path);t&&(t.children=t._children||t.children,t._children=null,t.data.expanded=!0)}this.update(this.root)}else(e.children||e._children)&&(e.children?(e._children=e.children,e.children=null,e.data.expanded=!1):(e.children=e._children,e._children=null,e.data.expanded=!0),this.update(e));else{const t=this.detectLanguage(e.data.path);if(!i.includes(t)&&"unknown"!==t)return void this.showNotification(`Skipping ${e.data.name} - ${t} not selected`,"warning");this.addLoadingPulse(e),e.data.analyzed="loading";const s=this.ensureFullPath(e.data.path);setTimeout(()=>{this.socket&&(this.socket.emit("code:analyze:file",{path:s}),this.updateBreadcrumb(`Analyzing ${e.data.name}...`,"info"),this.showNotification(`Analyzing: ${e.data.name}`,"info"))},100)}else{e.data.loaded="loading";const t=this.ensureFullPath(e.data.path);setTimeout(()=>{this.socket&&(this.socket.emit("code:discover:directory",{path:t,depth:1,languages:i,ignore_patterns:o}),this.updateBreadcrumb(`Loading ${e.data.name}...`,"info"),this.showNotification(`Loading directory: ${e.data.name}`,"info"))},100)}this.selectedNode=e;try{this.highlightNode(e)}catch(n){console.error("[CodeTree] ERROR during highlightNode:",n)}}ensureFullPath(t){if(console.log("🔗 ensureFullPath called with:",t),!t)return t;if(t.startsWith("/"))return console.log(" → Already absolute, returning:",t),t;const e=this.getWorkingDirectory();if(console.log(" → Working directory:",e),!e)return console.log(" → No working directory, returning original:",t),t;if("."===t)return console.log(" → Root path detected, returning working dir:",e),e;if(t===e)return console.log(" → Path equals working directory, returning:",e),e;const i=`${e}/${t}`.replace(/\/+/g,"/");return console.log(" → Combining with working dir, result:",i),i}highlightNode(t){this.treeGroup.selectAll("circle.node-circle").style("stroke-width",2).classed("selected",!1),this.treeGroup.selectAll("circle.node-circle").filter(e=>e===t).style("stroke-width",4).classed("selected",!0)}diagonal(t,e){return`M ${t.y} ${t.x}\n C ${(t.y+e.y)/2} ${t.x},\n ${(t.y+e.y)/2} ${e.x},\n ${e.y} ${e.x}`}radialDiagonal(t,e){return d3.linkRadial().angle(t=>t.x).radius(t=>t.y)({source:t,target:e})}getNodeColor(t){const e=t.data.type,i=t.data.complexity||1,s={root:"#6B7280",directory:"#3B82F6",file:"#10B981",module:"#8B5CF6",class:"#F59E0B",function:"#EF4444",method:"#EC4899"}[e]||"#6B7280";return i>10?d3.color(s).darker(.5):i>5?d3.color(s).darker(.25):s}getNodeStrokeColor(t){return"loading"===t.data.loaded||"loading"===t.data.analyzed?"#FCD34D":"directory"!==t.data.type||t.data.loaded?"file"!==t.data.type||t.data.analyzed?this.getNodeColor(t):"#CBD5E1":"#94A3B8"}getNodeIcon(t){return{root:"📦",directory:"📁",file:"📄",module:"📦",class:"C",function:"ƒ",method:"m"}[t.data.type]||"•"}showTooltip(t,e){if(!this.tooltip)return;const i=[];i.push(`<strong>${e.data.name}</strong>`),i.push(`Type: ${e.data.type}`),e.data.language&&i.push(`Language: ${e.data.language}`),e.data.complexity&&i.push(`Complexity: ${e.data.complexity}`),e.data.lines&&i.push(`Lines: ${e.data.lines}`),e.data.path&&i.push(`Path: ${e.data.path}`),"directory"!==e.data.type||e.data.loaded?"file"!==e.data.type||e.data.analyzed||i.push("<em>Click to analyze file</em>"):i.push("<em>Click to explore contents</em>"),this.tooltip.transition().duration(200).style("opacity",.9),this.tooltip.html(i.join("<br>")).style("left",t.pageX+10+"px").style("top",t.pageY-28+"px")}hideTooltip(){this.tooltip&&this.tooltip.transition().duration(500).style("opacity",0)}filterTree(){this.root&&(this.root.descendants().forEach(t=>{t.data._hidden=!1,"all"!==this.languageFilter&&"file"===t.data.type&&t.data.language!==this.languageFilter&&(t.data._hidden=!0),this.searchTerm&&(t.data.name.toLowerCase().includes(this.searchTerm)||(t.data._hidden=!0))}),this.update(this.root))}expandAll(){if(!this.root)return;const t=e=>{e._children&&(e.children=e._children,e._children=null),e.children&&e.children.forEach(t)};t(this.root),this.update(this.root),this.showNotification("All nodes expanded","info")}collapseAll(){if(!this.root)return;const t=e=>{e.children&&(e._children=e.children,e.children=null),e._children&&e._children.forEach(t)};this.root.children?.forEach(t),this.update(this.root),this.showNotification("All nodes collapsed","info")}resetZoom(){this.svg&&this.zoom&&(this.svg.transition().duration(750).call(this.zoom.transform,d3.zoomIdentity),this.showNotification("Zoom reset","info"))}focusOnNode(t){if(!this.svg||!this.zoom||!t)return;const e=t.descendants?t.descendants():[t];if(this.isRadialLayout){const t=e.map(t=>t.x),i=e.map(t=>t.y),s=Math.min(...t),o=Math.max(...t),n=Math.min(...i),a=Math.max(...i),r=(s+o)/2,d=(n+a)/2,l=d*Math.cos(r-Math.PI/2),c=d*Math.sin(r-Math.PI/2),h=o-s,p=a-n;let u=1;if(h>0&&p>0){const t=2*Math.PI/h,e=this.radius/p;u=Math.min(t,e,3),u=Math.max(u,1)}this.svg.transition().duration(750).call(this.zoom.transform,d3.zoomIdentity.translate(this.width/2-l*u,this.height/2-c*u).scale(u))}else{const t=e.map(t=>t.x),i=e.map(t=>t.y),s=Math.min(...t),o=Math.max(...t),n=Math.min(...i),a=Math.max(...i),r=(s+o)/2,d=(n+a)/2,l=o-s,c=a-n,h=100;let p=1;if(l>0&&c>0){const t=(this.width-h)/l,e=(this.height-h)/c;p=Math.min(t,e,2.5),p=Math.max(p,.5)}this.svg.transition().duration(750).call(this.zoom.transform,d3.zoomIdentity.translate(this.width/2-r*p,this.height/2-d*p).scale(p))}const i=this.getNodePath(t);this.updateBreadcrumb(`Focused: ${i}`,"info")}getNodePath(t){const e=[];let i=t;for(;i;)i.data&&i.data.name&&e.unshift(i.data.name),i=i.parent;return e.join(" / ")}toggleLegend(){const t=document.getElementById("tree-legend");t&&("none"===t.style.display?t.style.display="block":t.style.display="none")}getWorkingDirectory(){if(window.dashboard&&window.dashboard.workingDirectoryManager)return window.dashboard.workingDirectoryManager.getCurrentWorkingDir();const t=document.getElementById("working-dir-path");if(t){const e=t.textContent.trim();if(e&&"Loading..."!==e&&"Not selected"!==e)return e}return null}showNoWorkingDirectoryMessage(){const t=document.getElementById("code-tree-container");if(!t)return;this.removeNoWorkingDirectoryMessage(),this.hideLoading();const e=document.createElement("div");e.id="no-working-dir-message",e.className="no-working-dir-message",e.innerHTML='\n <div class="message-icon">📁</div>\n <h3>No Working Directory Selected</h3>\n <p>Please select a working directory from the top menu to analyze code.</p>\n <button id="select-working-dir-btn" class="btn btn-primary">\n Select Working Directory\n </button>\n ',e.style.cssText="\n text-align: center;\n padding: 40px;\n color: #666;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n ";const i=e.querySelector(".message-icon");i&&(i.style.cssText="font-size: 48px; margin-bottom: 16px; opacity: 0.5;");const s=e.querySelector("h3");s&&(s.style.cssText="margin: 16px 0; color: #333; font-size: 20px;");const o=e.querySelector("p");o&&(o.style.cssText="margin: 16px 0; color: #666; font-size: 14px;");const n=e.querySelector("button");n&&(n.style.cssText="\n margin-top: 20px;\n padding: 10px 20px;\n background: #3b82f6;\n color: white;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n transition: background 0.2s;\n ",n.addEventListener("mouseenter",()=>{n.style.background="#2563eb"}),n.addEventListener("mouseleave",()=>{n.style.background="#3b82f6"}),n.addEventListener("click",()=>{const t=document.getElementById("change-dir-btn");t?t.click():window.dashboard&&window.dashboard.workingDirectoryManager&&window.dashboard.workingDirectoryManager.showChangeDirDialog()})),t.appendChild(e),this.updateBreadcrumb("Please select a working directory","warning")}removeNoWorkingDirectoryMessage(){const t=document.getElementById("no-working-dir-message");t&&t.remove()}exportTree(){const t={timestamp:(new Date).toISOString(),workingDirectory:this.getWorkingDirectory(),stats:this.stats,tree:this.treeData},e=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),i=URL.createObjectURL(e),s=document.createElement("a");s.href=i,s.download=`code-tree-${Date.now()}.json`,s.click(),URL.revokeObjectURL(i),this.showNotification("Tree exported successfully","success")}updateActivityTicker(t,e="info"){const i=document.getElementById("breadcrumb-content");if(i){const s="info"===e&&t.includes("...")?"⟳ ":"";i.innerHTML=`${s}${t}`,i.className=`breadcrumb-${e}`}}updateTicker(t,e="info"){const i=document.getElementById("code-tree-ticker");i&&(i.textContent=t,i.className=`ticker ticker-${e}`,"error"!==e&&setTimeout(()=>{i.style.opacity="0",setTimeout(()=>{i.style.opacity="1",i.textContent=""},300)},5e3))}}window.CodeTree=t,document.addEventListener("DOMContentLoaded",()=>{document.getElementById("code-tree-container")&&(window.codeTree=new t,document.addEventListener("click",t=>{t.target.matches('[data-tab="code"]')&&setTimeout(()=>{window.codeTree&&!window.codeTree.initialized?window.codeTree.initialize():window.codeTree&&window.codeTree.renderWhenVisible()},100)}))});
2
2
  //# sourceMappingURL=code-tree.js.map