claude-mpm 4.1.10__py3-none-any.whl → 4.1.12__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 (56) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/INSTRUCTIONS.md +8 -0
  3. claude_mpm/cli/__init__.py +11 -0
  4. claude_mpm/cli/commands/analyze.py +2 -1
  5. claude_mpm/cli/commands/configure.py +9 -8
  6. claude_mpm/cli/commands/configure_tui.py +3 -1
  7. claude_mpm/cli/commands/dashboard.py +288 -0
  8. claude_mpm/cli/commands/debug.py +0 -1
  9. claude_mpm/cli/commands/mpm_init.py +442 -0
  10. claude_mpm/cli/commands/mpm_init_handler.py +84 -0
  11. claude_mpm/cli/parsers/base_parser.py +15 -0
  12. claude_mpm/cli/parsers/dashboard_parser.py +113 -0
  13. claude_mpm/cli/parsers/mpm_init_parser.py +128 -0
  14. claude_mpm/constants.py +10 -0
  15. claude_mpm/core/config.py +18 -0
  16. claude_mpm/core/instruction_reinforcement_hook.py +266 -0
  17. claude_mpm/core/pm_hook_interceptor.py +105 -8
  18. claude_mpm/dashboard/analysis_runner.py +52 -25
  19. claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
  20. claude_mpm/dashboard/static/built/components/code-tree.js +2 -0
  21. claude_mpm/dashboard/static/built/components/code-viewer.js +2 -0
  22. claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
  23. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  24. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  25. claude_mpm/dashboard/static/css/code-tree.css +330 -1
  26. claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
  27. claude_mpm/dashboard/static/dist/components/code-tree.js +2593 -2
  28. claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
  29. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  30. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  31. claude_mpm/dashboard/static/js/components/activity-tree.js +212 -13
  32. claude_mpm/dashboard/static/js/components/build-tracker.js +15 -13
  33. claude_mpm/dashboard/static/js/components/code-tree.js +2503 -917
  34. claude_mpm/dashboard/static/js/components/event-viewer.js +58 -19
  35. claude_mpm/dashboard/static/js/dashboard.js +46 -44
  36. claude_mpm/dashboard/static/js/socket-client.js +74 -32
  37. claude_mpm/dashboard/templates/index.html +25 -20
  38. claude_mpm/services/agents/deployment/agent_template_builder.py +11 -7
  39. claude_mpm/services/agents/memory/memory_format_service.py +3 -1
  40. claude_mpm/services/cli/agent_cleanup_service.py +1 -4
  41. claude_mpm/services/cli/socketio_manager.py +39 -8
  42. claude_mpm/services/cli/startup_checker.py +0 -1
  43. claude_mpm/services/core/cache_manager.py +0 -1
  44. claude_mpm/services/infrastructure/monitoring.py +1 -1
  45. claude_mpm/services/socketio/event_normalizer.py +64 -0
  46. claude_mpm/services/socketio/handlers/code_analysis.py +449 -0
  47. claude_mpm/services/socketio/server/connection_manager.py +3 -1
  48. claude_mpm/tools/code_tree_analyzer.py +930 -24
  49. claude_mpm/tools/code_tree_builder.py +0 -1
  50. claude_mpm/tools/code_tree_events.py +113 -15
  51. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.12.dist-info}/METADATA +2 -1
  52. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.12.dist-info}/RECORD +56 -48
  53. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.12.dist-info}/WHEEL +0 -0
  54. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.12.dist-info}/entry_points.txt +0 -0
  55. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.12.dist-info}/licenses/LICENSE +0 -0
  56. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.12.dist-info}/top_level.txt +0 -0
@@ -239,17 +239,30 @@ class CodeAnalysisRunner:
239
239
 
240
240
  # Build command
241
241
  cmd = self._build_command(request)
242
+ self.logger.info(f"Starting analysis subprocess: {' '.join(cmd)}")
242
243
 
243
244
  # Start subprocess
244
- self.current_process = subprocess.Popen(
245
- cmd,
246
- stdout=subprocess.PIPE,
247
- stderr=subprocess.PIPE,
248
- text=True,
249
- bufsize=1,
250
- universal_newlines=True,
251
- env=self._get_subprocess_env(),
252
- )
245
+ try:
246
+ self.current_process = subprocess.Popen(
247
+ cmd,
248
+ stdout=subprocess.PIPE,
249
+ stderr=subprocess.PIPE,
250
+ text=True,
251
+ bufsize=1,
252
+ universal_newlines=True,
253
+ env=self._get_subprocess_env(),
254
+ )
255
+ self.logger.debug(
256
+ f"Subprocess started with PID: {self.current_process.pid}"
257
+ )
258
+ except FileNotFoundError as e:
259
+ raise subprocess.SubprocessError(
260
+ f"Python executable not found: {cmd[0]}"
261
+ ) from e
262
+ except Exception as e:
263
+ raise subprocess.SubprocessError(
264
+ f"Failed to start subprocess: {e}"
265
+ ) from e
253
266
 
254
267
  # Process output
255
268
  self._process_output(request)
@@ -275,20 +288,34 @@ class CodeAnalysisRunner:
275
288
  },
276
289
  )
277
290
  else:
278
- # Failure
291
+ # Failure - capture any remaining stderr
292
+ stderr_output = ""
293
+ if self.current_process.stderr:
294
+ try:
295
+ # Read any remaining stderr output
296
+ stderr_lines = []
297
+ for line in self.current_process.stderr:
298
+ stderr_lines.append(line.strip())
299
+ stderr_output = "\n".join(stderr_lines)
300
+ except Exception as e:
301
+ stderr_output = f"Failed to read stderr: {e}"
302
+
279
303
  self.stats["analyses_failed"] += 1
280
- stderr = (
281
- self.current_process.stderr.read()
282
- if self.current_process.stderr
283
- else ""
284
- )
285
- self._emit_error(
286
- request.request_id,
287
- f"Analysis failed with code {return_code}: {stderr}",
288
- )
304
+ error_msg = f"Analysis failed with code {return_code}"
305
+ if stderr_output:
306
+ error_msg += f": {stderr_output}"
307
+
308
+ self.logger.error(f"Subprocess failed: {error_msg}")
309
+ self._emit_error(request.request_id, error_msg)
289
310
 
311
+ except subprocess.SubprocessError as e:
312
+ self.logger.error(f"Subprocess error for request {request.request_id}: {e}")
313
+ self.stats["analyses_failed"] += 1
314
+ self._emit_error(request.request_id, f"Failed to start analyzer: {e}")
290
315
  except Exception as e:
291
- self.logger.error(f"Error processing request {request.request_id}: {e}")
316
+ self.logger.error(
317
+ f"Error processing request {request.request_id}: {e}", exc_info=True
318
+ )
292
319
  self.stats["analyses_failed"] += 1
293
320
  self._emit_error(request.request_id, str(e))
294
321
 
@@ -308,16 +335,16 @@ class CodeAnalysisRunner:
308
335
  # Get Python executable
309
336
  python_exe = sys.executable
310
337
 
311
- # Build command - use the tools module as a runnable module
338
+ # Build command - use the CLI analyze-code command
312
339
  cmd = [
313
340
  python_exe,
314
341
  "-m",
315
- "claude_mpm.tools",
316
- "--path",
342
+ "claude_mpm",
343
+ "analyze-code",
317
344
  request.path,
318
345
  "--emit-events",
319
- "--output-format",
320
- "json-stream",
346
+ "--output",
347
+ "json",
321
348
  ]
322
349
 
323
350
  # Add optional parameters
@@ -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.events=[],this.todoWriteStack=[],this.activeAgent=null,this.activeAgentStack=[],this.margin={top:20,right:120,bottom:20,left:120},this.width=960-this.margin.left-this.margin.right,this.height=500-this.margin.top-this.margin.bottom,this.nodeId=0,this.duration=750,this.timeRange="30min",this.searchTerm="",this.tooltip=null,this.initialized=!1}initialize(){if(console.log("ActivityTree.initialize() called, initialized:",this.initialized),this.initialized)return void console.log("Activity tree already initialized, skipping");if(this.container=document.getElementById("activity-tree"),!this.container)return void console.error("Activity tree container (#activity-tree) not found in DOM");console.log("Activity tree container found:",this.container);const t=document.getElementById("activity-tab");if(t){if(!t.classList.contains("active"))return console.log("Activity tab not active, initializing but deferring render"),this.setupControls(),this.initializeTreeData(),this.subscribeToEvents(),void(this.initialized=!0);this.setupControls(),this.createVisualization(),this.svg&&this.treeGroup?(this.initializeTreeData(),this.update(this.root),this.subscribeToEvents(),this.initialized=!0,console.log("Activity tree initialization complete")):console.error("Failed to create D3 visualization elements")}else console.error("Activity tab panel (#activity-tab) not found in DOM")}renderWhenVisible(){if(console.log("ActivityTree.renderWhenVisible() called"),!this.initialized)return console.log("Not initialized yet, calling initialize..."),void this.initialize();this.svg||(console.log("Creating deferred visualization..."),this.createVisualization(),this.svg&&this.treeGroup&&this.update(this.root)),this.root&&this.svg&&(console.log("Updating tree with current data..."),this.update(this.root))}setupControls(){const t=document.getElementById("expand-all");t&&t.addEventListener("click",()=>this.expandAll());const e=document.getElementById("collapse-all");e&&e.addEventListener("click",()=>this.collapseAll());const i=document.getElementById("reset-zoom");i&&i.addEventListener("click",()=>this.resetZoom());const n=document.getElementById("time-range");n&&n.addEventListener("change",t=>{this.timeRange=t.target.value,this.filterEventsByTime()});const o=document.getElementById("activity-search");o&&o.addEventListener("input",t=>{this.searchTerm=t.target.value.toLowerCase(),this.highlightSearchResults()})}createVisualization(){if("undefined"==typeof d3)return void console.error("D3.js is not loaded! Cannot create activity tree visualization.");const t=this.container.getBoundingClientRect();this.width=t.width-this.margin.left-this.margin.right,this.height=Math.max(500,t.height-this.margin.top-this.margin.bottom),console.log("Creating D3 visualization with dimensions:",{width:this.width,height:this.height}),d3.select(this.container).select("svg").remove(),this.svg=d3.select(this.container).append("svg").attr("width","100%").attr("height","100%").attr("viewBox",`0 0 ${this.width+this.margin.left+this.margin.right} ${this.height+this.margin.top+this.margin.bottom}`),this.treeGroup=this.svg.append("g").attr("class","tree-group").attr("transform",`translate(${this.margin.left},${this.margin.top})`);const e=d3.zoom().scaleExtent([.1,3]).on("zoom",t=>{this.treeGroup.attr("transform",`translate(${this.margin.left+t.transform.x},${this.margin.top+t.transform.y}) scale(${t.transform.k})`)});this.svg.call(e),this.treeLayout=d3.tree().size([this.height,this.width]),this.tooltip=d3.select("body").append("div").attr("class","activity-tooltip").style("opacity",0)}initializeTreeData(){this.treeData={name:"PM",type:"pm",icon:"🎯",children:[],_children:null},this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0}subscribeToEvents(){if(!window.socketClient)return console.warn("Socket client not available for activity tree"),void setTimeout(()=>this.subscribeToEvents(),1e3);if(window.socketClient.onEventUpdate(t=>{const e=t.length-this.events.length;if(e>0){const i=t.slice(this.events.length);console.log("ActivityTree: Received new events:",i.map(t=>({type:t.type,subtype:t.subtype,hook_event_name:t.hook_event_name,tool_name:t.tool_name,originalEventName:t.originalEventName})));const n=i.filter(t=>t.hook_event_name).length,o=i.filter(t=>"hook"===t.type||"todo"===t.type||"subagent"===t.type).length;console.log(`ActivityTree: ${n}/${e} new events have hook_event_name, ${o} are hook/todo/subagent type`),i.forEach(t=>{t.hook_event_name?this.processEvent(t):"hook"!==t.type&&"todo"!==t.type&&"subagent"!==t.type||console.warn("ActivityTree: Missing hook_event_name for relevant event:",{type:t.type,subtype:t.subtype,tool_name:t.tool_name})}),this.events=[...t]}}),window.socketClient&&window.socketClient.events){console.log(`Processing ${window.socketClient.events.length} existing events for activity tree`);const t=window.socketClient.events.filter(t=>t.hook_event_name).length,e=window.socketClient.events.filter(t=>"hook"===t.type||"todo"===t.type||"subagent"===t.type).length;console.log(`ActivityTree: ${t}/${window.socketClient.events.length} existing events have hook_event_name, ${e} are hook/todo/subagent type`);const i=window.socketClient.events.slice(0,5);console.log("ActivityTree: Sample of existing events:",i.map(t=>({type:t.type,subtype:t.subtype,hook_event_name:t.hook_event_name,tool_name:t.tool_name,originalEventName:t.originalEventName}))),window.socketClient.events.forEach(t=>{t.hook_event_name&&this.processEvent(t)}),this.events=[...window.socketClient.events]}else window.eventViewer&&window.eventViewer.events?(console.log(`Processing ${window.eventViewer.events.length} existing events for activity tree (from eventViewer)`),window.eventViewer.events.forEach(t=>{t.hook_event_name&&this.processEvent(t)}),this.events=[...window.eventViewer.events]):(console.log("No existing events found for activity tree"),this.events=[])}processEvent(t){if(!t||!t.hook_event_name)return void console.log("ActivityTree: Ignoring invalid event",t);console.log(`ActivityTree: Processing event: ${t.hook_event_name}`,t);const e=t.hook_event_name,i=new Date(t.timestamp);if(this.isEventInTimeRange(i)){switch(e){case"TodoWrite":this.processTodoWrite(t);break;case"SubagentStart":this.processSubagentStart(t);break;case"SubagentStop":this.processSubagentStop(t);break;case"PreToolUse":this.processToolUse(t);break;case"PostToolUse":this.updateToolStatus(t,"completed");break;case"Start":this.initializeTreeData(),this.update(this.root)}this.updateStats()}}processTodoWrite(t){const e=t.todos||t.data?.todos||[];if(0===e.length)return;const i=e.find(t=>"in_progress"===t.status);if(!i)return;const n={name:i.activeForm||i.content,type:"todowrite",icon:"📝",content:i.content,status:i.status,timestamp:t.timestamp,children:[],_children:null,eventId:t.id};this.root.data.children||(this.root.data.children=[]),this.root.data.children.push(n),this.todoWriteStack.push({node:n,content:i.content}),this.update(this.root)}processSubagentStart(t){const e=t.agent_name||t.data?.agent_name||t.data?.agent_type||"unknown",i={name:e,type:"agent",icon:this.getAgentIcon(e),timestamp:t.timestamp,children:[],_children:null,eventId:t.id,sessionId:t.session_id||t.data?.session_id};let n=null;if(this.todoWriteStack.length>0){const t=this.todoWriteStack[this.todoWriteStack.length-1];t.content&&t.content.toLowerCase().includes(e.toLowerCase())&&(n=t.node)}n||(n=this.root.data),n.children||(n.children=[]),n.children.push(i),this.activeAgent=i,this.activeAgentStack.push(i),this.update(this.root)}processSubagentStop(t){const e=t.session_id||t.data?.session_id;this.activeAgent&&this.activeAgent.sessionId===e&&(this.activeAgent.status="completed",this.activeAgentStack.pop(),this.activeAgent=this.activeAgentStack.length>0?this.activeAgentStack[this.activeAgentStack.length-1]:null),this.update(this.root)}processToolUse(t){const e=t.tool_name||t.data?.tool_name||"unknown",i=this.getToolIcon(e),n=t.tool_parameters||t.data?.tool_parameters||t.data?.tool_params||{},o={name:e,type:"tool",icon:i,timestamp:t.timestamp,status:"in_progress",children:[],_children:null,eventId:t.id};"Read"===e&&n.file_path?o.children.push({name:n.file_path,type:"file",icon:"📄",timestamp:t.timestamp}):"Edit"===e&&n.file_path?o.children.push({name:n.file_path,type:"file",icon:"✏️",timestamp:t.timestamp}):"Write"===e&&n.file_path?o.children.push({name:n.file_path,type:"file",icon:"💾",timestamp:t.timestamp}):"Bash"===e&&n.command?o.children.push({name:n.command.substring(0,50)+(n.command.length>50?"...":""),type:"command",icon:"⚡",timestamp:t.timestamp}):"WebFetch"===e&&n.url&&o.children.push({name:n.url,type:"url",icon:"🌐",timestamp:t.timestamp});let s=this.activeAgent||this.root.data;s.children||(s.children=[]),s.children.push(o),this.update(this.root)}updateToolStatus(t,e){const i=n=>{if(n.eventId===t.id)return n.status=e,!0;if(n.children)for(let t of n.children)if(i(t))return!0;if(n._children)for(let t of n._children)if(i(t))return!0;return!1};i(this.root.data),this.update(this.root)}getAgentIcon(t){return{engineer:"👷",research:"🔬",qa:"🧪",ops:"⚙️",pm:"📊",architect:"🏗️"}[t.toLowerCase()]||"🤖"}getToolIcon(t){return{read:"👁️",write:"✍️",edit:"✏️",bash:"💻",webfetch:"🌐",grep:"🔍",glob:"📂",todowrite:"📝"}[t.toLowerCase()]||"🔧"}update(t){const e=this.treeLayout(this.root),i=e.descendants(),n=e.links();i.forEach(t=>{t.y=180*t.depth});const o=this.treeGroup.selectAll("g.node").data(i,t=>t.id||(t.id=++this.nodeId)),s=o.enter().append("g").attr("class","node").attr("transform",e=>`translate(${t.y0},${t.x0})`).on("click",(t,e)=>this.click(e));s.append("circle").attr("class",t=>`node-circle ${t.data.type}`).attr("r",1e-6).style("fill",t=>t._children?this.getNodeColor(t.data.type):"#fff").style("stroke",t=>this.getNodeColor(t.data.type)),s.append("text").attr("class","node-icon").attr("dy",".35em").attr("text-anchor","middle").style("font-size","14px").text(t=>t.data.icon||""),s.append("text").attr("class","node-label").attr("dy",".35em").attr("x",t=>t.children||t._children?-25:25).attr("text-anchor",t=>t.children||t._children?"end":"start").text(t=>t.data.name).style("fill-opacity",1e-6),s.on("mouseover",(t,e)=>this.showTooltip(t,e)).on("mouseout",()=>this.hideTooltip());const a=s.merge(o);a.transition().duration(this.duration).attr("transform",t=>`translate(${t.y},${t.x})`),a.select("circle.node-circle").attr("r",10).style("fill",t=>"in_progress"===t.data.status||t._children?this.getNodeColor(t.data.type):"#fff").attr("class",t=>{let e=`node-circle ${t.data.type}`;return"in_progress"===t.data.status&&(e+=" pulsing"),"failed"===t.data.status&&(e+=" failed"),e}),a.select("text.node-label").style("fill-opacity",1);const r=o.exit().transition().duration(this.duration).attr("transform",e=>`translate(${t.y},${t.x})`).remove();r.select("circle").attr("r",1e-6),r.select("text").style("fill-opacity",1e-6);const l=this.treeGroup.selectAll("path.link").data(n,t=>t.target.id);l.enter().insert("path","g").attr("class","link").attr("d",e=>{const i={x:t.x0,y:t.y0};return this.diagonal({source:i,target:i})}).merge(l).transition().duration(this.duration).attr("d",this.diagonal),l.exit().transition().duration(this.duration).attr("d",e=>{const i={x:t.x,y:t.y};return this.diagonal({source:i,target:i})}).remove(),i.forEach(t=>{t.x0=t.x,t.y0=t.y}),this.updateBreadcrumb(t)}diagonal(t){return`M ${t.source.y} ${t.source.x}\n C ${(t.source.y+t.target.y)/2} ${t.source.x},\n ${(t.source.y+t.target.y)/2} ${t.target.x},\n ${t.target.y} ${t.target.x}`}click(t){t.children?(t._children=t.children,t.children=null):(t.children=t._children,t._children=null),this.update(t),this.updateBreadcrumb(t)}getNodeColor(t){return{pm:"#4299e1",todowrite:"#48bb78",agent:"#ed8936",tool:"#9f7aea",file:"#38b2ac",command:"#f56565",url:"#4299e1"}[t]||"#718096"}showTooltip(t,e){const i=`\n <strong>${e.data.name}</strong><br>\n Type: ${e.data.type}<br>\n ${e.data.timestamp?`Time: ${new Date(e.data.timestamp).toLocaleTimeString()}`:""}\n ${e.data.status?`<br>Status: ${e.data.status}`:""}\n `;this.tooltip.transition().duration(200).style("opacity",.9),this.tooltip.html(i).style("left",t.pageX+10+"px").style("top",t.pageY-28+"px")}hideTooltip(){this.tooltip.transition().duration(500).style("opacity",0)}expandAll(){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)}collapseAll(){const t=e=>{e.children&&(e._children=e.children,e._children.forEach(t),e.children=null)};this.root.children?.forEach(t),this.update(this.root)}resetZoom(){if(!this.svg)return void console.warn("Cannot reset zoom: SVG not initialized");const t=d3.zoom().scaleExtent([.1,3]).on("zoom",t=>{this.treeGroup.attr("transform",`translate(${this.margin.left+t.transform.x},${this.margin.top+t.transform.y}) scale(${t.transform.k})`)});this.svg.transition().duration(750).call(t.transform,d3.zoomIdentity),this.treeGroup.transition().duration(750).attr("transform",`translate(${this.margin.left},${this.margin.top})`)}isEventInTimeRange(t){if("all"===this.timeRange)return!0;const e=(new Date-t)/6e4;switch(this.timeRange){case"10min":return e<=10;case"30min":return e<=30;case"hour":return e<=60;default:return!0}}filterEventsByTime(){this.initializeTreeData(),window.eventViewer&&window.eventViewer.events&&window.eventViewer.events.forEach(t=>{this.processEvent(t)})}updateStats(){const t=this.countNodes(this.root),e=this.countActiveNodes(this.root.data),i=this.getTreeDepth(this.root);document.getElementById("node-count").textContent=t,document.getElementById("active-count").textContent=e,document.getElementById("tree-depth").textContent=i}countNodes(t){let e=1;return t.children&&t.children.forEach(t=>{e+=this.countNodes(t)}),t._children&&t._children.forEach(t=>{e+=this.countNodes(t)}),e}countActiveNodes(t){let e="in_progress"===t.status?1:0;return t.children&&t.children.forEach(t=>{e+=this.countActiveNodes(t)}),t._children&&t._children.forEach(t=>{e+=this.countActiveNodes(t)}),e}getTreeDepth(t){if(!t.children&&!t._children)return 0;const e=(t.children||t._children).map(t=>this.getTreeDepth(t));return Math.max(...e)+1}updateBreadcrumb(t){const e=[];let i=t;for(;i;)e.unshift(i.data.name),i=i.parent;const n=document.getElementById("activity-breadcrumb");n&&(n.textContent=e.join(" > "))}highlightSearchResults(){this.treeGroup.selectAll(".node-label").style("font-weight","normal").style("fill","#2d3748"),this.searchTerm&&this.treeGroup.selectAll(".node-label").style("font-weight",t=>t.data.name.toLowerCase().includes(this.searchTerm)?"bold":"normal").style("fill",t=>t.data.name.toLowerCase().includes(this.searchTerm)?"#e53e3e":"#2d3748")}}window.ActivityTree=t;const e=()=>{let e=null;const i=()=>{e||(console.log("Creating new Activity Tree instance..."),e=new t,window.activityTreeInstance=e),setTimeout(()=>{console.log("Attempting to initialize Activity Tree visualization..."),e.initialize()},100)};document.querySelectorAll(".tab-button").forEach(t=>{t.addEventListener("click",t=>{"activity"===t.target.getAttribute("data-tab")&&(console.log("Activity tab button clicked, initializing tree..."),i(),e&&setTimeout(()=>e.renderWhenVisible(),150))})}),document.addEventListener("tabChanged",t=>{t.detail&&"activity"===t.detail.newTab&&(console.log("Tab changed to activity, initializing tree..."),i(),e&&setTimeout(()=>e.renderWhenVisible(),150))});const n=document.querySelector(".tab-button.active");n&&"activity"===n.getAttribute("data-tab")&&i(),window.activityTree=()=>e};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e();
1
+ class t{constructor(){this.container=null,this.svg=null,this.treeData=null,this.root=null,this.treeLayout=null,this.treeGroup=null,this.events=[],this.todoWriteStack=[],this.activeAgent=null,this.activeAgentStack=[],this.margin={top:20,right:120,bottom:20,left:120},this.width=960-this.margin.left-this.margin.right,this.height=500-this.margin.top-this.margin.bottom,this.nodeId=0,this.duration=750,this.timeRange="30min",this.searchTerm="",this.tooltip=null,this.initialized=!1}initialize(){if(console.log("ActivityTree.initialize() called, initialized:",this.initialized),this.initialized)return void console.log("Activity tree already initialized, skipping");if(this.container=document.getElementById("activity-tree-container"),!this.container&&(this.container=document.getElementById("activity-tree"),!this.container))return void console.error("Activity tree container not found in DOM");this.container.textContent&&this.container.textContent.trim()&&(console.log("Clearing existing text content from container:",this.container.textContent),this.container.textContent=""),console.log("Activity tree container found:",this.container);const t=document.getElementById("activity-tab");if(t){if(!t.classList.contains("active"))return console.log("Activity tab not active, initializing but deferring render"),this.container.textContent&&this.container.textContent.trim()&&(this.container.textContent=""),this.setupControls(),this.initializeTreeData(),this.subscribeToEvents(),void(this.initialized=!0);if(this.container.textContent&&this.container.textContent.trim()&&(console.log("Clearing container text before creating visualization"),this.container.textContent=""),this.setupControls(),this.createVisualization(),!this.svg||!this.treeGroup)return console.error("Failed to create D3 visualization elements"),void(this.container&&(this.container.innerHTML='<div style="padding: 20px; text-align: center; color: #e53e3e;">⚠️ Failed to create visualization. Please refresh the page.</div>'));this.initializeTreeData(),this.root?this.update(this.root):console.warn("Root not created, skipping initial update"),this.subscribeToEvents(),this.initialized=!0,console.log("Activity tree initialization complete")}else console.error("Activity tab panel (#activity-tab) not found in DOM")}forceShow(){if(console.log("ActivityTree.forceShow() called"),this.container||(this.container=document.getElementById("activity-tree-container")||document.getElementById("activity-tree"),this.container)){if(this.container.textContent&&this.container.textContent.trim()&&(console.log("Clearing text from container:",this.container.textContent),this.container.innerHTML=""),this.svg||this.createVisualization(),this.root||this.initializeTreeData(),this.root&&this.svg&&this.treeGroup&&this.update(this.root),this.svg){const t=this.svg.node();t&&(t.style.display="block",t.style.visibility="visible")}}else console.error("Cannot find activity tree container")}renderWhenVisible(){if(console.log("ActivityTree.renderWhenVisible() called"),this.container&&this.container.textContent&&this.container.textContent.trim()&&!this.svg&&(console.log("Clearing text content before rendering:",this.container.textContent),this.container.textContent=""),!this.initialized)return console.log("Not initialized yet, calling initialize..."),void this.initialize();this.svg||(console.log("Creating deferred visualization..."),this.createVisualization(),this.svg&&this.treeGroup&&this.root?this.update(this.root):this.root||(console.warn("No root node available, initializing tree data..."),this.initializeTreeData(),this.root&&this.svg&&this.treeGroup&&this.update(this.root))),this.root&&this.svg?(console.log("Updating tree with current data..."),this.update(this.root)):console.warn("Cannot update tree - missing components:",{hasRoot:!!this.root,hasSvg:!!this.svg,hasTreeGroup:!!this.treeGroup})}setupControls(){const t=document.getElementById("expand-all");t&&t.addEventListener("click",()=>this.expandAll());const e=document.getElementById("collapse-all");e&&e.addEventListener("click",()=>this.collapseAll());const i=document.getElementById("reset-zoom");i&&i.addEventListener("click",()=>this.resetZoom());const o=document.getElementById("time-range");o&&o.addEventListener("change",t=>{this.timeRange=t.target.value,this.filterEventsByTime()});const n=document.getElementById("activity-search");n&&n.addEventListener("input",t=>{this.searchTerm=t.target.value.toLowerCase(),this.highlightSearchResults()})}createVisualization(){if("undefined"==typeof d3)return console.error("D3.js is not loaded! Cannot create activity tree visualization."),void(this.container&&(this.container.innerHTML='<div style="padding: 20px; text-align: center; color: #e53e3e;">⚠️ D3.js is not loaded. Cannot create visualization.</div>'));const t=this.container.getBoundingClientRect();this.width=t.width-this.margin.left-this.margin.right,this.height=Math.max(500,t.height-this.margin.top-this.margin.bottom),console.log("Creating D3 visualization with dimensions:",{width:this.width,height:this.height}),d3.select(this.container).selectAll("*").remove(),this.svg=d3.select(this.container).append("svg").attr("width","100%").attr("height","100%").attr("viewBox",`0 0 ${this.width+this.margin.left+this.margin.right} ${this.height+this.margin.top+this.margin.bottom}`),this.treeGroup=this.svg.append("g").attr("class","tree-group").attr("transform",`translate(${this.margin.left},${this.margin.top})`);const e=d3.zoom().scaleExtent([.1,3]).on("zoom",t=>{this.treeGroup.attr("transform",`translate(${this.margin.left+t.transform.x},${this.margin.top+t.transform.y}) scale(${t.transform.k})`)});this.svg.call(e),this.treeLayout=d3.tree().size([this.height,this.width]),console.log("ActivityTree: Tree layout created:",this.treeLayout),this.tooltip=d3.select("body").append("div").attr("class","activity-tooltip").style("opacity",0),console.log("ActivityTree: Visualization complete, svg:",this.svg,"treeGroup:",this.treeGroup)}initializeTreeData(){if(console.log("ActivityTree: Initializing tree data"),this.treeData={name:"PM",type:"pm",icon:"🎯",children:[],_children:null},"undefined"==typeof d3)return console.error("ActivityTree: D3 is not available - cannot create hierarchy!"),void(this.container&&(this.container.innerHTML='<div style="padding: 20px; text-align: center; color: #e53e3e;">⚠️ Waiting for D3.js to load...</div>'));this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,console.log("ActivityTree: Root node created:",this.root),this.updateStats()}subscribeToEvents(){if(!window.socketClient)return console.warn("Socket client not available for activity tree"),void setTimeout(()=>this.subscribeToEvents(),1e3);console.log("ActivityTree: Setting up event subscription"),window.socketClient.onEventUpdate(t=>{console.log(`ActivityTree: onEventUpdate called with ${t.length} total events`);const e=t.length-this.events.length;if(e>0){const i=t.slice(this.events.length);console.log(`ActivityTree: Processing ${e} new events`,i),i.forEach(t=>{this.processEvent(t)}),this.events=[...t]}});const t=window.socketClient?.events||window.eventViewer?.events||[];t.length>0?(console.log(`ActivityTree: Processing ${t.length} existing events`,t),t.forEach(t=>{this.processEvent(t)}),this.events=[...t]):(console.log("ActivityTree: No existing events found"),this.events=[])}processEvent(t){if(!t)return void console.log("ActivityTree: Ignoring null event");let e=null;if(t.hook_event_name)e=t.hook_event_name;else if("hook"===t.type&&t.subtype){e={pre_tool:"PreToolUse",post_tool:"PostToolUse",subagent_start:"SubagentStart",subagent_stop:"SubagentStop",todo_write:"TodoWrite"}[t.subtype]}else"todo"===t.type&&"updated"===t.subtype?e="TodoWrite":"subagent"===t.type?"started"===t.subtype?e="SubagentStart":"stopped"===t.subtype&&(e="SubagentStop"):"start"===t.type&&(e="Start");if(!e)return void("hook"!==t.type&&"todo"!==t.type&&"subagent"!==t.type||console.log("ActivityTree: Cannot determine event type for:",t));console.log(`ActivityTree: Processing event: ${e}`,t);const i=new Date(t.timestamp);if(this.isEventInTimeRange(i)){switch(e){case"TodoWrite":this.processTodoWrite(t);break;case"SubagentStart":this.processSubagentStart(t);break;case"SubagentStop":this.processSubagentStop(t);break;case"PreToolUse":this.processToolUse(t);break;case"PostToolUse":this.updateToolStatus(t,"completed");break;case"Start":this.initializeTreeData(),this.update(this.root)}this.updateStats()}}processTodoWrite(t){console.log("ActivityTree: Processing TodoWrite event:",t);let e=t.todos||t.data?.todos||t.data||[];if(e&&"object"==typeof e&&e.todos&&(e=e.todos),!Array.isArray(e))return void console.log("ActivityTree: Invalid todos format in event:",t);if(0===e.length)return void console.log("ActivityTree: No todos in event");const i=e.find(t=>"in_progress"===t.status);if(!i)return void console.log("ActivityTree: No in-progress todo found");console.log("ActivityTree: Found active todo:",i);const o={name:i.activeForm||i.content,type:"todowrite",icon:"📝",content:i.content,status:i.status,timestamp:t.timestamp,children:[],_children:null,eventId:t.id};this.root?this.root.data?(this.root.data.children||(this.root.data.children=[]),console.log("ActivityTree: Adding TodoWrite node to root"),this.root.data.children.push(o),this.todoWriteStack.push({node:o,content:i.content}),console.log("ActivityTree: Calling update with root:",this.root),this.update(this.root),console.log("ActivityTree: Update complete")):console.error("ActivityTree: Root has no data!"):console.error("ActivityTree: No root node!")}processSubagentStart(t){const e=t.agent_name||t.data?.agent_name||t.data?.agent_type||t.agent_type||t.agent||"unknown",i={name:e,type:"agent",icon:this.getAgentIcon(e),timestamp:t.timestamp,children:[],_children:null,eventId:t.id,sessionId:t.session_id||t.data?.session_id};let o=null;if(this.todoWriteStack.length>0){const t=this.todoWriteStack[this.todoWriteStack.length-1];t.content&&t.content.toLowerCase().includes(e.toLowerCase())&&(o=t.node)}o||(o=this.root.data),o.children||(o.children=[]),o.children.push(i),this.activeAgent=i,this.activeAgentStack.push(i),this.update(this.root)}processSubagentStop(t){const e=t.session_id||t.data?.session_id;this.activeAgent&&this.activeAgent.sessionId===e&&(this.activeAgent.status="completed",this.activeAgentStack.pop(),this.activeAgent=this.activeAgentStack.length>0?this.activeAgentStack[this.activeAgentStack.length-1]:null),this.update(this.root)}processToolUse(t){const e=t.tool_name||t.data?.tool_name||t.tool||t.data?.tool||"unknown",i=this.getToolIcon(e),o=t.tool_parameters||t.data?.tool_parameters||t.parameters||t.data?.parameters||{},n={name:e,type:"tool",icon:i,timestamp:t.timestamp,status:"in_progress",children:[],_children:null,eventId:t.id};"Read"===e&&o.file_path?n.children.push({name:o.file_path,type:"file",icon:"📄",timestamp:t.timestamp}):"Edit"===e&&o.file_path?n.children.push({name:o.file_path,type:"file",icon:"✏️",timestamp:t.timestamp}):"Write"===e&&o.file_path?n.children.push({name:o.file_path,type:"file",icon:"💾",timestamp:t.timestamp}):"Bash"===e&&o.command?n.children.push({name:o.command.substring(0,50)+(o.command.length>50?"...":""),type:"command",icon:"⚡",timestamp:t.timestamp}):"WebFetch"===e&&o.url&&n.children.push({name:o.url,type:"url",icon:"🌐",timestamp:t.timestamp});let s=this.activeAgent||this.root.data;s.children||(s.children=[]),s.children.push(n),this.update(this.root)}updateToolStatus(t,e){const i=o=>{if(o.eventId===t.id)return o.status=e,!0;if(o.children)for(let t of o.children)if(i(t))return!0;if(o._children)for(let t of o._children)if(i(t))return!0;return!1};i(this.root.data),this.update(this.root)}getAgentIcon(t){return{engineer:"👷",research:"🔬",qa:"🧪",ops:"⚙️",pm:"📊",architect:"🏗️"}[t.toLowerCase()]||"🤖"}getToolIcon(t){return{read:"👁️",write:"✍️",edit:"✏️",bash:"💻",webfetch:"🌐",grep:"🔍",glob:"📂",todowrite:"📝"}[t.toLowerCase()]||"🔧"}update(t){if(console.log("ActivityTree: update() called with source:",t),"undefined"==typeof d3)return void console.error("ActivityTree: Cannot update - D3.js not loaded");if(!this.svg||!this.treeGroup){if(console.warn("ActivityTree: Cannot update - SVG not initialized"),!this.container)return;if(console.log("Attempting to create visualization from update()"),this.createVisualization(),!this.svg||!this.treeGroup)return void console.error("Failed to create visualization in update()")}if(!this.treeLayout){if(console.warn("ActivityTree: Cannot update - tree layout not initialized"),"undefined"==typeof d3)return;this.treeLayout=d3.tree().size([this.height,this.width]),console.log("Created tree layout in update()")}if(!t||!t.data)return void console.error("ActivityTree: Invalid source in update()",t);if(!this.root)return void console.error("ActivityTree: No root node available for update");let e;try{e=this.treeLayout(this.root)}catch(c){return void console.error("ActivityTree: Error computing tree layout:",c)}const i=e.descendants(),o=e.links();if(console.log(`ActivityTree: Updating tree with ${i.length} nodes`),1===i.length&&this.container){this.container.querySelector("svg")||console.warn("SVG element not found in container after update")}i.forEach(t=>{t.y=180*t.depth});const n=this.treeGroup.selectAll("g.node").data(i,t=>t.id||(t.id=++this.nodeId)),s=n.enter().append("g").attr("class","node").attr("transform",e=>`translate(${t.y0},${t.x0})`).on("click",(t,e)=>this.click(e));s.append("circle").attr("class",t=>`node-circle ${t.data.type}`).attr("r",1e-6).style("fill",t=>t._children?this.getNodeColor(t.data.type):"#fff").style("stroke",t=>this.getNodeColor(t.data.type)),s.append("text").attr("class","node-icon").attr("dy",".35em").attr("text-anchor","middle").style("font-size","14px").text(t=>t.data.icon||""),s.append("text").attr("class","node-label").attr("dy",".35em").attr("x",t=>t.children||t._children?-25:25).attr("text-anchor",t=>t.children||t._children?"end":"start").text(t=>t.data.name).style("fill-opacity",1e-6),s.on("mouseover",(t,e)=>this.showTooltip(t,e)).on("mouseout",()=>this.hideTooltip());const r=s.merge(n);r.transition().duration(this.duration).attr("transform",t=>`translate(${t.y},${t.x})`),r.select("circle.node-circle").attr("r",10).style("fill",t=>"in_progress"===t.data.status||t._children?this.getNodeColor(t.data.type):"#fff").attr("class",t=>{let e=`node-circle ${t.data.type}`;return"in_progress"===t.data.status&&(e+=" pulsing"),"failed"===t.data.status&&(e+=" failed"),e}),r.select("text.node-label").style("fill-opacity",1);const a=n.exit().transition().duration(this.duration).attr("transform",e=>`translate(${t.y},${t.x})`).remove();a.select("circle").attr("r",1e-6),a.select("text").style("fill-opacity",1e-6);const l=this.treeGroup.selectAll("path.link").data(o,t=>t.target.id);l.enter().insert("path","g").attr("class","link").attr("d",e=>{const i={x:t.x0,y:t.y0};return this.diagonal({source:i,target:i})}).merge(l).transition().duration(this.duration).attr("d",this.diagonal),l.exit().transition().duration(this.duration).attr("d",e=>{const i={x:t.x,y:t.y};return this.diagonal({source:i,target:i})}).remove(),i.forEach(t=>{t.x0=t.x,t.y0=t.y}),this.updateBreadcrumb(t)}diagonal(t){return`M ${t.source.y} ${t.source.x}\n C ${(t.source.y+t.target.y)/2} ${t.source.x},\n ${(t.source.y+t.target.y)/2} ${t.target.x},\n ${t.target.y} ${t.target.x}`}click(t){t.children?(t._children=t.children,t.children=null):(t.children=t._children,t._children=null),this.update(t),this.updateBreadcrumb(t)}getNodeColor(t){return{pm:"#4299e1",todowrite:"#48bb78",agent:"#ed8936",tool:"#9f7aea",file:"#38b2ac",command:"#f56565",url:"#4299e1"}[t]||"#718096"}showTooltip(t,e){const i=`\n <strong>${e.data.name}</strong><br>\n Type: ${e.data.type}<br>\n ${e.data.timestamp?`Time: ${new Date(e.data.timestamp).toLocaleTimeString()}`:""}\n ${e.data.status?`<br>Status: ${e.data.status}`:""}\n `;this.tooltip.transition().duration(200).style("opacity",.9),this.tooltip.html(i).style("left",t.pageX+10+"px").style("top",t.pageY-28+"px")}hideTooltip(){this.tooltip.transition().duration(500).style("opacity",0)}expandAll(){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)}collapseAll(){const t=e=>{e.children&&(e._children=e.children,e._children.forEach(t),e.children=null)};this.root.children?.forEach(t),this.update(this.root)}resetZoom(){if(!this.svg)return void console.warn("Cannot reset zoom: SVG not initialized");const t=d3.zoom().scaleExtent([.1,3]).on("zoom",t=>{this.treeGroup.attr("transform",`translate(${this.margin.left+t.transform.x},${this.margin.top+t.transform.y}) scale(${t.transform.k})`)});this.svg.transition().duration(750).call(t.transform,d3.zoomIdentity),this.treeGroup.transition().duration(750).attr("transform",`translate(${this.margin.left},${this.margin.top})`)}isEventInTimeRange(t){if("all"===this.timeRange)return!0;const e=(new Date-t)/6e4;switch(this.timeRange){case"10min":return e<=10;case"30min":return e<=30;case"hour":return e<=60;default:return!0}}filterEventsByTime(){this.initializeTreeData(),window.eventViewer&&window.eventViewer.events&&window.eventViewer.events.forEach(t=>{this.processEvent(t)})}updateStats(){if(!this.root||!this.root.data){console.warn("ActivityTree: Cannot update stats - root not initialized");const t=document.getElementById("node-count"),e=document.getElementById("active-count"),i=document.getElementById("tree-depth");return t&&(t.textContent="1"),e&&(e.textContent="0"),void(i&&(i.textContent="0"))}const t=this.countNodes(this.root),e=this.countActiveNodes(this.root.data),i=this.getTreeDepth(this.root),o=document.getElementById("node-count"),n=document.getElementById("active-count"),s=document.getElementById("tree-depth");o&&(o.textContent=t),n&&(n.textContent=e),s&&(s.textContent=i),console.log(`ActivityTree: Stats updated - Nodes: ${t}, Active: ${e}, Depth: ${i}`)}countNodes(t){let e=1;return t.children&&t.children.forEach(t=>{e+=this.countNodes(t)}),t._children&&t._children.forEach(t=>{e+=this.countNodes(t)}),e}countActiveNodes(t){let e="in_progress"===t.status?1:0;return t.children&&t.children.forEach(t=>{e+=this.countActiveNodes(t)}),t._children&&t._children.forEach(t=>{e+=this.countActiveNodes(t)}),e}getTreeDepth(t){if(!t.children&&!t._children)return 0;const e=(t.children||t._children).map(t=>this.getTreeDepth(t));return Math.max(...e)+1}updateBreadcrumb(t){const e=[];let i=t;for(;i;)e.unshift(i.data.name),i=i.parent;const o=document.getElementById("activity-breadcrumb");o&&(o.textContent=e.join(" > "))}highlightSearchResults(){this.treeGroup.selectAll(".node-label").style("font-weight","normal").style("fill","#2d3748"),this.searchTerm&&this.treeGroup.selectAll(".node-label").style("font-weight",t=>t.data.name.toLowerCase().includes(this.searchTerm)?"bold":"normal").style("fill",t=>t.data.name.toLowerCase().includes(this.searchTerm)?"#e53e3e":"#2d3748")}}window.ActivityTree=t;const e=()=>{let e=null;const i=()=>{e||(console.log("Creating new Activity Tree instance..."),e=new t,window.activityTreeInstance=e);const i=document.getElementById("activity-tree-container")||document.getElementById("activity-tree");i&&i.textContent&&i.textContent.trim()&&(console.log("Clearing text from activity tree container before init:",i.textContent),i.textContent=""),setTimeout(()=>{console.log("Attempting to initialize Activity Tree visualization..."),e.initialize()},100)};document.querySelectorAll(".tab-button").forEach(t=>{t.addEventListener("click",t=>{"activity"===t.target.getAttribute("data-tab")&&(console.log("Activity tab button clicked, initializing tree..."),i(),e&&setTimeout(()=>{e.renderWhenVisible(),e.forceShow()},150))})}),document.addEventListener("tabChanged",t=>{t.detail&&"activity"===t.detail.newTab&&(console.log("Tab changed to activity, initializing tree..."),i(),e&&setTimeout(()=>{e.renderWhenVisible(),e.forceShow()},150))});const o=document.querySelector(".tab-button.active");o&&"activity"===o.getAttribute("data-tab")&&(console.log("Activity tab is active on load, initializing tree..."),i());const n=document.getElementById("activity-tab");n&&n.classList.contains("active")&&(console.log("Activity panel is active on load, initializing tree..."),e||i()),window.activityTree=()=>e};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e();
2
2
  //# sourceMappingURL=activity-tree.js.map
@@ -0,0 +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)}))});
2
+ //# sourceMappingURL=code-tree.js.map
@@ -0,0 +1,2 @@
1
+ const e=new class{constructor(){this.modal=null,this.currentNode=null,this.socket=null,this.initialized=!1,this.codeCache=new Map}initialize(){this.initialized||(this.createModal(),this.setupEventHandlers(),this.subscribeToEvents(),this.initialized=!0,console.log("Code viewer initialized"))}createModal(){document.body.insertAdjacentHTML("beforeend",'\n <div class="code-viewer-modal" id="code-viewer-modal">\n <div class="code-viewer-content">\n <div class="code-viewer-header">\n <div class="code-viewer-title" id="code-viewer-title">\n Loading...\n </div>\n <div class="code-viewer-info">\n <span id="code-viewer-type">Type: --</span>\n <span id="code-viewer-lines">Lines: --</span>\n <span id="code-viewer-complexity">Complexity: --</span>\n </div>\n <button class="code-viewer-close" id="code-viewer-close">×</button>\n </div>\n <div class="code-viewer-body">\n <pre class="code-viewer-code line-numbers" id="code-viewer-code">\n <code class="language-python" id="code-viewer-code-content"></code>\n </pre>\n </div>\n <div class="code-viewer-navigation">\n <div class="nav-group">\n <button class="code-nav-button" id="code-nav-parent" disabled>\n ⬆️ Parent\n </button>\n <button class="code-nav-button" id="code-nav-prev" disabled>\n ⬅️ Previous\n </button>\n <button class="code-nav-button" id="code-nav-next" disabled>\n ➡️ Next\n </button>\n </div>\n <div class="nav-info">\n <span id="code-nav-position">-- / --</span>\n </div>\n <div class="nav-actions">\n <button class="code-nav-button" id="code-copy">\n 📋 Copy\n </button>\n <button class="code-nav-button" id="code-open-file">\n 📂 Open File\n </button>\n </div>\n </div>\n </div>\n </div>\n '),this.modal=document.getElementById("code-viewer-modal")}setupEventHandlers(){document.getElementById("code-viewer-close").addEventListener("click",()=>{this.hide()}),this.modal.addEventListener("click",e=>{e.target===this.modal&&this.hide()}),document.addEventListener("keydown",e=>{"Escape"===e.key&&this.modal.classList.contains("show")&&this.hide()}),document.getElementById("code-nav-parent").addEventListener("click",()=>{this.navigateToParent()}),document.getElementById("code-nav-prev").addEventListener("click",()=>{this.navigateToPrevious()}),document.getElementById("code-nav-next").addEventListener("click",()=>{this.navigateToNext()}),document.getElementById("code-copy").addEventListener("click",()=>{this.copyCode()}),document.getElementById("code-open-file").addEventListener("click",()=>{this.openInEditor()})}subscribeToEvents(){window.socket&&(this.socket=window.socket,this.socket.on("code:content:response",e=>{this.handleCodeContent(e)}))}show(e){this.initialized||this.initialize(),this.currentNode=e,this.modal.classList.add("show"),this.updateHeader(e),this.loadCode(e),this.updateNavigation(e)}hide(){this.modal.classList.remove("show"),this.currentNode=null}updateHeader(e){document.getElementById("code-viewer-title").textContent=`${e.name} (${e.path||"Unknown"})`,document.getElementById("code-viewer-type").textContent=`Type: ${e.type}`,document.getElementById("code-viewer-lines").textContent=`Lines: ${e.lines||"--"}`,document.getElementById("code-viewer-complexity").textContent=`Complexity: ${e.complexity||"--"}`}loadCode(e){const t=document.getElementById("code-viewer-code-content"),n=`${e.path}:${e.line}`;this.codeCache.has(n)?this.displayCode(this.codeCache.get(n)):(t.textContent="Loading code...",this.socket?this.socket.emit("code:content:request",{path:e.path,line:e.line,type:e.type,name:e.name}):this.displayMockCode(e))}handleCodeContent(e){if(!e.success)return void this.displayError(e.error||"Failed to load code");const t=`${e.path}:${e.line}`;this.codeCache.set(t,e.content),this.displayCode(e.content)}displayCode(e){const t=document.getElementById("code-viewer-code-content"),n=document.getElementById("code-viewer-code");t.textContent=e;const i=this.detectLanguage(this.currentNode.path);t.className=`language-${i}`,window.Prism&&(Prism.highlightElement(t),Prism.plugins&&Prism.plugins.lineNumbers&&Prism.plugins.lineNumbers.resize(n))}displayMockCode(e){let t="";switch(e.type){case"class":t=`class ${e.name}:\n """\n ${e.docstring||"A sample class implementation."}\n """\n \n def __init__(self):\n """Initialize the ${e.name} class."""\n self._data = {}\n self._initialized = False\n \n def process(self, input_data):\n """Process the input data."""\n if not self._initialized:\n self._initialize()\n return self._transform(input_data)\n \n def _initialize(self):\n """Initialize internal state."""\n self._initialized = True\n \n def _transform(self, data):\n """Transform the data."""\n return data`;break;case"function":t=`def ${e.name}(${e.params?e.params.join(", "):""}):\n """\n ${e.docstring||"A sample function implementation."}\n \n Args:\n ${e.params?e.params.map(e=>`${e}: Description of ${e}`).join("\n "):"None"}\n \n Returns:\n ${e.returns||"None"}: Return value description\n """\n # Implementation here\n result = None\n \n # Process logic\n for item in range(10):\n result = process_item(item)\n \n return result`;break;case"method":t=` def ${e.name}(self${e.params?", "+e.params.join(", "):""}):\n """\n ${e.docstring||"A sample method implementation."}\n """\n # Method implementation\n self._validate()\n result = self._process()\n return result`;break;default:t=`# ${e.name}\n# Type: ${e.type}\n# Path: ${e.path||"Unknown"}\n# Line: ${e.line||"Unknown"}\n\n# Code content would appear here\n# This is a placeholder for demonstration purposes`}this.displayCode(t)}displayError(e){const t=document.getElementById("code-viewer-code-content");t.textContent=`# Error loading code\n# ${e}`,t.className="language-python"}detectLanguage(e){if(!e)return"python";return{py:"python",js:"javascript",ts:"typescript",jsx:"jsx",tsx:"tsx",css:"css",html:"html",json:"json",yaml:"yaml",yml:"yaml",md:"markdown",sh:"bash",bash:"bash",sql:"sql",go:"go",rs:"rust",cpp:"cpp",c:"c",h:"c",hpp:"cpp",java:"java",rb:"ruby",php:"php"}[e.split(".").pop().toLowerCase()]||"plaintext"}updateNavigation(e){document.getElementById("code-nav-parent").disabled=!0,document.getElementById("code-nav-prev").disabled=!0,document.getElementById("code-nav-next").disabled=!0,document.getElementById("code-nav-position").textContent="1 / 1"}navigateToParent(){console.log("Navigate to parent node")}navigateToPrevious(){console.log("Navigate to previous sibling")}navigateToNext(){console.log("Navigate to next sibling")}async copyCode(){const e=document.getElementById("code-viewer-code-content").textContent;try{await navigator.clipboard.writeText(e);const t=document.getElementById("code-copy"),n=t.textContent;t.textContent="✅ Copied!",setTimeout(()=>{t.textContent=n},2e3)}catch(t){console.error("Failed to copy code:",t),alert("Failed to copy code to clipboard")}}openInEditor(){this.currentNode&&this.currentNode.path?(this.socket&&this.socket.emit("file:open",{path:this.currentNode.path,line:this.currentNode.line}),console.log("Opening file in editor:",this.currentNode.path)):alert("File path not available")}};"undefined"!=typeof window&&(window.CodeViewer=e,document.addEventListener("DOMContentLoaded",()=>{e.initialize()}));
2
+ //# sourceMappingURL=code-viewer.js.map
@@ -1,2 +1,2 @@
1
- class e{constructor(e,t){this.container=document.getElementById(e),this.socketClient=t,this.events=[],this.filteredEvents=[],this.selectedEventIndex=-1,this.filteredEventElements=[],this.autoScroll=!0,this.searchFilter="",this.typeFilter="",this.sessionFilter="",this.eventTypeCount={},this.availableEventTypes=new Set,this.errorCount=0,this.eventsThisMinute=0,this.lastMinute=(new Date).getMinutes(),this.init()}init(){this.setupEventHandlers(),this.setupKeyboardNavigation(),this.socketClient.onEventUpdate((e,t)=>{console.log("EventViewer received event update:",e?.length||0,"events"),this.events=Array.isArray(e)?e:[],this.updateDisplay()})}setupEventHandlers(){const e=document.getElementById("events-search-input");e&&e.addEventListener("input",e=>{this.searchFilter=e.target.value.toLowerCase(),this.applyFilters()});const t=document.getElementById("events-type-filter");t&&t.addEventListener("change",e=>{this.typeFilter=e.target.value,this.applyFilters()})}setupKeyboardNavigation(){console.log("EventViewer: Keyboard navigation handled by unified Dashboard system")}handleArrowNavigation(e){if(0===this.filteredEventElements.length)return;let t=this.selectedEventIndex+e;t>=this.filteredEventElements.length?t=0:t<0&&(t=this.filteredEventElements.length-1),this.showEventDetails(t)}applyFilters(){this.events&&Array.isArray(this.events)||(console.warn("EventViewer: events array is not initialized, using empty array"),this.events=[]),this.filteredEvents=this.events.filter(e=>{if(this.searchFilter){if(![e.type||"",e.subtype||"",JSON.stringify(e.data||{})].join(" ").toLowerCase().includes(this.searchFilter))return!1}if(this.typeFilter){const t=e.type&&""!==e.type.trim()?e.type:"";if((e.subtype&&t?`${t}.${e.subtype}`:t)!==this.typeFilter)return!1}return!(this.sessionFilter&&""!==this.sessionFilter&&(!e.data||e.data.session_id!==this.sessionFilter))}),this.renderEvents(),this.updateMetrics()}updateEventTypeDropdown(){const e=document.getElementById("events-type-filter");if(!e)return;const t=new Set;this.events&&Array.isArray(this.events)||(console.warn("EventViewer: events array is not initialized in updateEventTypeDropdown"),this.events=[]),this.events.forEach(e=>{if(e.type&&""!==e.type.trim()){const n=e.subtype?`${e.type}.${e.subtype}`:e.type;t.add(n)}});const n=Array.from(t).sort(),s=Array.from(this.availableEventTypes).sort();if(JSON.stringify(n)===JSON.stringify(s))return;this.availableEventTypes=t;const i=e.value;e.innerHTML='<option value="">All Events</option>';Array.from(t).sort().forEach(t=>{const n=document.createElement("option");n.value=t,n.textContent=t,e.appendChild(n)}),i&&t.has(i)?e.value=i:i&&!t.has(i)&&(e.value="",this.typeFilter="")}updateDisplay(){console.log("EventViewer updating display with",this.events?.length||0,"events"),this.updateEventTypeDropdown(),this.applyFilters()}renderEvents(){const e=document.getElementById("events-list");if(!e)return;if(0===this.filteredEvents.length)return e.innerHTML=`\n <div class="no-events">\n ${0===this.events.length?"Connect to Socket.IO server to see events...":"No events match current filters..."}\n </div>\n `,void(this.filteredEventElements=[]);const t=this.filteredEvents.map((e,t)=>{const n=new Date(e.timestamp).toLocaleTimeString();return`\n <div class="event-item single-row ${e.type?`event-${e.type}`:"event-default"} ${t===this.selectedEventIndex?"selected":""}"\n onclick="eventViewer.showEventDetails(${t})"\n data-index="${t}">\n <span class="event-single-row-content">\n <span class="event-content-main">${this.formatSingleRowEventContent(e)}</span>\n <span class="event-timestamp">${n}</span>\n </span>\n ${this.createInlineEditDiffViewer(e,t)}\n </div>\n `}).join("");e.innerHTML=t,this.filteredEventElements=Array.from(e.querySelectorAll(".event-item")),window.dashboard&&"events"===window.dashboard.currentTab&&window.dashboard.tabNavigation&&window.dashboard.tabNavigation.events&&(window.dashboard.tabNavigation.events.items=this.filteredEventElements),this.autoScroll&&this.filteredEvents.length>0&&(e.scrollTop=e.scrollHeight)}formatEventType(e){return e.type&&e.subtype?e.type===e.subtype||"generic"===e.subtype?e.type:`${e.type}.${e.subtype}`:e.type?e.type:e.originalEventName?e.originalEventName:"unknown"}formatEventData(e){if(!e.data)return"No data";switch(e.type){case"session":return this.formatSessionEvent(e);case"claude":return this.formatClaudeEvent(e);case"agent":return this.formatAgentEvent(e);case"hook":return this.formatHookEvent(e);case"todo":return this.formatTodoEvent(e);case"memory":return this.formatMemoryEvent(e);case"log":return this.formatLogEvent(e);default:return this.formatGenericEvent(e)}}formatSessionEvent(e){const t=e.data;return"started"===e.subtype?`<strong>Session started:</strong> ${t.session_id||"Unknown"}`:"ended"===e.subtype?`<strong>Session ended:</strong> ${t.session_id||"Unknown"}`:`<strong>Session:</strong> ${JSON.stringify(t)}`}formatClaudeEvent(e){const t=e.data;if("request"===e.subtype){const e=t.prompt||t.message||"";return`<strong>Request:</strong> ${e.length>100?e.substring(0,100)+"...":e}`}if("response"===e.subtype){const e=t.response||t.content||"";return`<strong>Response:</strong> ${e.length>100?e.substring(0,100)+"...":e}`}return`<strong>Claude:</strong> ${JSON.stringify(t)}`}formatAgentEvent(e){const t=e.data;return"loaded"===e.subtype?`<strong>Agent loaded:</strong> ${t.agent_type||t.name||"Unknown"}`:"executed"===e.subtype?`<strong>Agent executed:</strong> ${t.agent_type||t.name||"Unknown"}`:`<strong>Agent:</strong> ${JSON.stringify(t)}`}formatHookEvent(e){const t=e.data,n=t.event_type||e.subtype||"unknown";switch(n){case"user_prompt":const s=t.prompt_text||t.prompt_preview||"";return`<strong>User Prompt:</strong> ${(s.length>80?s.substring(0,80)+"...":s)||"No prompt text"}`;case"pre_tool":const i=t.tool_name||"Unknown tool";return`<strong>Pre-Tool (${t.operation_type||"operation"}):</strong> ${i}`;case"post_tool":const o=t.tool_name||"Unknown tool";return`<strong>Post-Tool (${t.success?"success":t.status||"failed"}):</strong> ${o}${t.duration_ms?` (${t.duration_ms}ms)`:""}`;case"notification":return`<strong>Notification (${t.notification_type||"notification"}):</strong> ${t.message_preview||t.message||"No message"}`;case"stop":const r=t.reason||"unknown";return`<strong>Stop (${t.stop_type||"normal"}):</strong> ${r}`;case"subagent_start":const a=t.agent_type||t.agent||t.subagent_type||"Unknown",l=t.prompt||t.description||t.task||"No description",c=l.length>60?l.substring(0,60)+"...":l;return`<strong>Subagent Start (${this.formatAgentType(a)}):</strong> ${c}`;case"subagent_stop":const d=t.agent_type||t.agent||t.subagent_type||"Unknown",p=t.reason||t.stop_reason||"completed",g=this.formatAgentType(d),u=t.structured_response?.task_completed;return`<strong>Subagent Stop (${g})${void 0!==u?u?" ✓":" ✗":""}:</strong> ${p}`;default:const h=t.hook_name||t.name||t.event_type||"Unknown";return`<strong>Hook ${e.subtype||n}:</strong> ${h}`}}formatTodoEvent(e){const t=e.data;if(t.todos&&Array.isArray(t.todos)){const e=t.todos.length;return`<strong>Todo updated:</strong> ${e} item${1!==e?"s":""}`}return`<strong>Todo:</strong> ${JSON.stringify(t)}`}formatMemoryEvent(e){const t=e.data;return`<strong>Memory ${t.operation||"unknown"}:</strong> ${t.key||"Unknown key"}`}formatLogEvent(e){const t=e.data,n=t.level||"info",s=t.message||"",i=s.length>80?s.substring(0,80)+"...":s;return`<strong>[${n.toUpperCase()}]</strong> ${i}`}formatGenericEvent(e){const t=e.data;return"string"==typeof t?t.length>100?t.substring(0,100)+"...":t:JSON.stringify(t)}formatAgentType(e){const t={research:"Research",architect:"Architect",engineer:"Engineer",qa:"QA",pm:"PM",project_manager:"PM",research_agent:"Research",architect_agent:"Architect",engineer_agent:"Engineer",qa_agent:"QA",unknown:"Unknown"},n=(e||"unknown").toLowerCase();if(t[n])return t[n];const s=e.match(/^(\w+)(?:_agent|Agent)?$/i);return s&&s[1]?s[1].charAt(0).toUpperCase()+s[1].slice(1).toLowerCase():e.charAt(0).toUpperCase()+e.slice(1)}formatSingleRowEventContent(e){const t=this.formatEventType(e),n=e.data||{},s=e.source&&"system"!==e.source?`[${e.source}] `:"";let i="";switch(e.type){case"hook":const t=e.tool_name||n.tool_name||"Unknown",s=e.subtype||"Unknown";if("pre_tool"===s||"post_tool"===s){const e=n.operation_type||"",o="post_tool"===s&&void 0!==n.success?n.success?"✓":"✗":"";i=`${t}${e?` (${e})`:""}${o?` ${o}`:""}`}else if("user_prompt"===s){const e=n.prompt_text||n.prompt_preview||"";i=(e.length>60?e.substring(0,60)+"...":e)||"No prompt text"}else if("subagent_start"===s){const e=n.agent_type||n.agent||n.subagent_type||"Unknown",t=this.formatAgentType(e),s=n.prompt||n.description||n.task||"",o=s.length>40?s.substring(0,40)+"...":s;i=o?`${t} - ${o}`:t}else if("subagent_stop"===s){const e=n.agent_type||n.agent||n.subagent_type||"Unknown",t=this.formatAgentType(e),s=n.reason||n.stop_reason||"completed",o=n.structured_response?.task_completed,r=void 0!==o?o?"✓":"✗":"";i=`${t}${r?" "+r:""} - ${s}`}else if("stop"===s){const e=n.reason||"completed";i=`${n.stop_type||"normal"} - ${e}`}else i=t;break;case"agent":const o=e.subagent_type||n.subagent_type||"PM",r=n.status||"";i=`${o}${r?` - ${r}`:""}`;break;case"todo":if(n.todos&&Array.isArray(n.todos)){i=`${n.todos.length} items (${n.todos.filter(e=>"completed"===e.status).length} completed, ${n.todos.filter(e=>"in_progress"===e.status).length} in progress)`}else i="Todo update";break;case"memory":i=`${n.operation||"unknown"}: ${n.key||"unknown"}${n.value?` = ${JSON.stringify(n.value).substring(0,30)}...`:""}`;break;case"session":i=`ID: ${n.session_id||"unknown"}`;break;case"claude":if("request"===e.subtype){const e=n.prompt||n.message||"";i=(e.length>60?e.substring(0,60)+"...":e)||"Empty request"}else if("response"===e.subtype){const e=n.response||n.content||"";i=(e.length>60?e.substring(0,60)+"...":e)||"Empty response"}else i=n.message||"Claude interaction";break;case"log":const a=n.level||"info",l=n.message||"",c=l.length>60?l.substring(0,60)+"...":l;i=`[${a.toUpperCase()}] ${c}`;break;case"test":i=n.test_name||n.name||"Test";break;default:if("string"==typeof n)i=n.length>60?n.substring(0,60)+"...":n;else if(n.message)i=n.message.length>60?n.message.substring(0,60)+"...":n.message;else if(n.name)i=n.name;else if(Object.keys(n).length>0){const e=Object.keys(n).find(e=>!["timestamp","id"].includes(e));if(e){const t=n[e];i=`${e}: ${"object"==typeof t?JSON.stringify(t).substring(0,40)+"...":t}`}}}const o=`${s}${t}`;return i?`${o} - ${i}`:o}getHookDisplayName(e,t){const n={pre_tool:"Pre-Tool",post_tool:"Post-Tool",user_prompt:"User-Prompt",stop:"Stop",subagent_start:"Subagent-Start",subagent_stop:"Subagent-Stop",notification:"Notification"};if(n[e])return n[e];return String(e||"unknown").replace(/_/g," ")}getEventCategory(e){const t=e.data||{},n=e.tool_name||t.tool_name||"";return["Read","Write","Edit","MultiEdit"].includes(n)?"file_operations":["Bash","grep","Glob"].includes(n)?"system_operations":"TodoWrite"===n?"task_management":"Task"===n||"subagent_start"===e.subtype||"subagent_stop"===e.subtype?"agent_delegation":"stop"===e.subtype?"session_control":"general"}showEventDetails(e){if(!this.filteredEvents||!Array.isArray(this.filteredEvents))return void console.warn("EventViewer: filteredEvents array is not initialized");if(e<0||e>=this.filteredEvents.length)return;this.selectedEventIndex=e;const t=this.filteredEvents[e];window.dashboard&&(window.dashboard.tabNavigation&&window.dashboard.tabNavigation.events&&(window.dashboard.tabNavigation.events.selectedIndex=e),window.dashboard.selectCard&&window.dashboard.selectCard("events",e,"event",t)),this.filteredEventElements.forEach((t,n)=>{t.classList.toggle("selected",n===e)}),document.dispatchEvent(new CustomEvent("eventSelected",{detail:{event:t,index:e}}));const n=this.filteredEventElements[e];n&&n.scrollIntoView({behavior:"smooth",block:"nearest"})}clearSelection(){this.selectedEventIndex=-1,this.filteredEventElements.forEach(e=>{e.classList.remove("selected")}),window.dashboard&&(window.dashboard.tabNavigation&&window.dashboard.tabNavigation.events&&(window.dashboard.tabNavigation.events.selectedIndex=-1),window.dashboard.clearCardSelection&&window.dashboard.clearCardSelection()),document.dispatchEvent(new CustomEvent("eventSelectionCleared"))}updateMetrics(){this.eventTypeCount={},this.errorCount=0,this.events&&Array.isArray(this.events)||(console.warn("EventViewer: events array is not initialized in updateMetrics"),this.events=[]),this.events.forEach(e=>{const t=e.type||"unknown";this.eventTypeCount[t]=(this.eventTypeCount[t]||0)+1,"log"===e.type&&e.data&&["error","critical"].includes(e.data.level)&&this.errorCount++});const e=(new Date).getMinutes();e!==this.lastMinute&&(this.lastMinute=e,this.eventsThisMinute=0);const t=new Date(Date.now()-6e4);this.eventsThisMinute=this.events.filter(e=>new Date(e.timestamp)>t).length,this.updateMetricsUI()}updateMetricsUI(){const e=document.getElementById("total-events"),t=document.getElementById("events-per-minute"),n=document.getElementById("unique-types"),s=document.getElementById("error-count");e&&(e.textContent=this.events.length),t&&(t.textContent=this.eventsThisMinute),n&&(n.textContent=Object.keys(this.eventTypeCount).length),s&&(s.textContent=this.errorCount)}exportEvents(){const e=JSON.stringify(this.filteredEvents,null,2),t=new Blob([e],{type:"application/json"}),n=URL.createObjectURL(t),s=document.createElement("a");s.href=n,s.download=`claude-mpm-events-${(new Date).toISOString().split("T")[0]}.json`,s.click(),URL.revokeObjectURL(n)}clearEvents(){this.socketClient.clearEvents(),this.selectedEventIndex=-1,this.updateDisplay()}setSessionFilter(e){this.sessionFilter=e,this.applyFilters()}getFilters(){return{search:this.searchFilter,type:this.typeFilter,session:this.sessionFilter}}getFilteredEvents(){return this.filteredEvents}getAllEvents(){return this.events}createInlineEditDiffViewer(e,t){const n=e.data||{},s=e.tool_name||n.tool_name||"";if(!["Edit","MultiEdit"].includes(s))return"";let i=[];if("Edit"===s){const t=e.tool_parameters||n.tool_parameters||{};t.old_string&&t.new_string&&i.push({old_string:t.old_string,new_string:t.new_string,file_path:t.file_path||"unknown"})}else if("MultiEdit"===s){const t=e.tool_parameters||n.tool_parameters||{};t.edits&&Array.isArray(t.edits)&&(i=t.edits.map(e=>({...e,file_path:t.file_path||"unknown"})))}if(0===i.length)return"";const o=`edit-diff-${t}`,r=i.length>1;let a="";return i.forEach((e,t)=>{const n=this.createDiffHtml(e.old_string,e.new_string);a+=`\n <div class="edit-diff-section">\n ${r?`<div class="edit-diff-header">Edit ${t+1}</div>`:""}\n <div class="diff-content">${n}</div>\n </div>\n `}),`\n <div class="inline-edit-diff-viewer">\n <div class="diff-toggle-header" onclick="eventViewer.toggleEditDiff('${o}', event)">\n <span class="diff-toggle-icon">📋</span>\n <span class="diff-toggle-text">Show ${r?i.length+" edits":"edit"}</span>\n <span class="diff-toggle-arrow">▼</span>\n </div>\n <div id="${o}" class="diff-content-container" style="display: none;">\n ${a}\n </div>\n </div>\n `}createDiffHtml(e,t){const n=e.split("\n"),s=t.split("\n");let i="",o=0,r=0;for(;o<n.length||r<s.length;){const e=o<n.length?n[o]:null,t=r<s.length?s[r]:null;null===e?(i+=`<div class="diff-line diff-added">+ ${this.escapeHtml(t)}</div>`,r++):null===t?(i+=`<div class="diff-line diff-removed">- ${this.escapeHtml(e)}</div>`,o++):e===t?(i+=`<div class="diff-line diff-unchanged"> ${this.escapeHtml(e)}</div>`,o++,r++):(i+=`<div class="diff-line diff-removed">- ${this.escapeHtml(e)}</div>`,i+=`<div class="diff-line diff-added">+ ${this.escapeHtml(t)}</div>`,o++,r++)}return`<div class="diff-container">${i}</div>`}toggleEditDiff(e,t){t.stopPropagation();const n=document.getElementById(e),s=t.currentTarget.querySelector(".diff-toggle-arrow");if(n){const e="none"!==n.style.display;n.style.display=e?"none":"block",s&&(s.textContent=e?"▼":"▲")}}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}}window.EventViewer=e;class t{constructor(e,t){this.eventViewer=e,this.agentInference=t,this.agentEvents=[],this.filteredAgentEvents=[],this.filteredToolEvents=[],this.filteredFileEvents=[],this.selectedSessionId=null,this.fileTrackingCache=new Map,this.trackingCheckTimeout=3e4,console.log("Event processor initialized")}getFilteredEventsForTab(e){const t=this.eventViewer.events;console.log(`getFilteredEventsForTab(${e}) - using RAW events: ${t.length} total`);const n=window.sessionManager;if(n&&n.selectedSessionId){const e=n.getEventsForSession(n.selectedSessionId);return console.log(`Filtering by session ${n.selectedSessionId}: ${e.length} events`),e}return t}applyAgentsFilters(e){const t=document.getElementById("agents-search-input"),n=document.getElementById("agents-type-filter"),s=t?t.value.toLowerCase():"",i=n?n.value:"";return e.filter(e=>{if(s){if(![e.agentName||"",e.type||"",e.isImplied?"implied":"explicit"].join(" ").toLowerCase().includes(s))return!1}if(i){if(!(e.agentName||"unknown").toLowerCase().includes(i.toLowerCase()))return!1}return!0})}applyToolsFilters(e){const t=document.getElementById("tools-search-input"),n=document.getElementById("tools-type-filter"),s=t?t.value.toLowerCase():"",i=n?n.value:"";return e.filter(e=>{if(s){if(![e.tool_name||"",e.agent_type||"",e.type||"",e.subtype||""].join(" ").toLowerCase().includes(s))return!1}if(i){if((e.tool_name||"")!==i)return!1}return!0})}applyToolCallFilters(e){const t=document.getElementById("tools-search-input"),n=document.getElementById("tools-type-filter"),s=t?t.value.toLowerCase():"",i=n?n.value:"";return e.filter(([e,t])=>{if(s){if(![t.tool_name||"",t.agent_type||"","tool_call"].join(" ").toLowerCase().includes(s))return!1}if(i){if((t.tool_name||"")!==i)return!1}return!0})}applyFilesFilters(e){const t=document.getElementById("files-search-input"),n=document.getElementById("files-type-filter"),s=t?t.value.toLowerCase():"",i=n?n.value:"";return e.filter(([e,t])=>{if(this.selectedSessionId){const e=t.operations.filter(e=>e.sessionId===this.selectedSessionId);if(0===e.length)return!1;t={...t,operations:e,lastOperation:e[e.length-1]?.timestamp||t.lastOperation}}if(s){if(![e,...t.operations.map(e=>e.operation),...t.operations.map(e=>e.agent)].join(" ").toLowerCase().includes(s))return!1}if(i){if(!t.operations.map(e=>e.operation).includes(i))return!1}return!0})}extractOperation(e){if(!e)return"unknown";const t=e.toLowerCase();return t.includes("read")?"read":t.includes("write")?"write":t.includes("edit")?"edit":t.includes("create")?"create":t.includes("delete")?"delete":t.includes("move")||t.includes("rename")?"move":"other"}extractToolFromHook(e){if(!e)return"";const t=e.match(/^(?:Pre|Post)(.+)Use$/);return t?t[1]:""}extractToolFromSubtype(e){if(!e)return"";if(e.includes("_")){return e.split("_")[0]||""}return e}extractToolTarget(e,t,n){const s=t||n||{};switch(e?.toLowerCase()){case"read":case"write":case"edit":return s.file_path||s.path||"";case"bash":return s.command||"";case"grep":return s.pattern||"";case"task":return s.subagent_type||s.agent_type||"";default:const e=Object.keys(s),t=["path","file_path","command","pattern","query","target"];for(const n of t)if(s[n])return s[n];return e.length>0?`${e[0]}: ${s[e[0]]}`:""}}generateAgentHTML(e){const t=this.agentInference.getUniqueAgentInstances();return this.applyAgentsFilters(t).map((e,t)=>{const n=e.agentName,s=this.formatTimestamp(e.firstTimestamp||e.timestamp),i=e.isImplied?"implied":"explicit",o=e.totalEventCount||e.eventCount||0;return`\n <div class="event-item single-row event-agent" onclick="${`dashboard.selectCard('agents', ${t}, 'agent_instance', '${e.id}'); dashboard.showAgentInstanceDetails('${e.id}');`}">\n <span class="event-single-row-content">\n <span class="event-content-main">${`${n} (${i}, ${o} events)`}</span>\n <span class="event-timestamp">${s}</span>\n </span>\n </div>\n `}).join("")}generateToolHTML(e){return this.applyToolCallFilters(e).map(([e,t],n)=>{const s=t.tool_name||"Unknown",i=t.agent_type||"Unknown",o=this.formatTimestamp(t.timestamp);return`\n <div class="event-item single-row event-tool ${"completed"===(t.post_event?"completed":"pending")?"status-success":"status-pending"}" onclick="dashboard.selectCard('tools', ${n}, 'toolCall', '${e}'); dashboard.showToolCallDetails('${e}')">\n <span class="event-single-row-content">\n <span class="event-content-main">${`${s} (${"pm"===i.toLowerCase()?"pm":i})`}</span>\n <span class="event-timestamp">${o}</span>\n </span>\n </div>\n `}).join("")}generateFileHTML(e){return this.applyFilesFilters(e).map(([e,t],n)=>{const s=t.operations.map(e=>e.operation),i=this.formatTimestamp(t.lastOperation),o={};s.forEach(e=>{o[e]=(o[e]||0)+1});const r=Object.entries(o).map(([e,t])=>`${e}(${t})`).join(", "),a=[...new Set(t.operations.map(e=>e.agent))],l=a.length>1?`by ${a.length} agents`:`by ${a[0]||"unknown"}`;return`\n <div class="event-item single-row file-item" onclick="dashboard.selectCard('files', ${n}, 'file', '${e}'); dashboard.showFileDetails('${e}')">\n <span class="event-single-row-content">\n <span class="event-content-main">${`${this.getRelativeFilePath(e)} ${r} ${l}`}</span>\n <span class="event-timestamp">${i}</span>\n </span>\n </div>\n `}).join("")}getFileOperationIcon(e){return e.includes("write")||e.includes("create")?"📝":e.includes("edit")?"✏️":e.includes("read")?"👁️":e.includes("delete")?"🗑️":e.includes("move")?"📦":"📄"}getRelativeFilePath(e){if(!e)return"";const t=e.split("/");return t.length>3?".../"+t.slice(-2).join("/"):e}formatTimestamp(e){if(!e)return"";return new Date(e).toLocaleTimeString()}setSelectedSessionId(e){this.selectedSessionId=e}getSelectedSessionId(){return this.selectedSessionId}getUniqueToolInstances(e){return this.applyToolCallFilters(e)}getUniqueFileInstances(e){return this.applyFilesFilters(e)}async isFileTracked(e,t){const n=`${t}:${e}`,s=Date.now(),i=this.fileTrackingCache.get(n);if(i&&s-i.timestamp<this.trackingCheckTimeout)return i.is_tracked;try{const i=window.socket;return i?new Promise(o=>{const r=t=>{if(t.file_path===e){const e=t.success&&t.is_tracked;this.fileTrackingCache.set(n,{is_tracked:e,timestamp:s}),i.off("file_tracked_response",r),o(e)}};i.on("file_tracked_response",r),i.emit("check_file_tracked",{file_path:e,working_dir:t}),setTimeout(()=>{i.off("file_tracked_response",r),o(!1)},5e3)}):(console.warn("No socket connection available for git tracking check"),!1)}catch(o){return console.error("Error checking file tracking status:",o),!1}}generateGitDiffIcon(e,t,n){const s=`git-icon-${e.replace(/[^a-zA-Z0-9]/g,"-")}-${t}`,i=`\n <span id="${s}" class="git-diff-icon"\n onclick="event.stopPropagation(); showGitDiffModal('${e}', '${t}')"\n title="View git diff for this file operation"\n style="margin-left: 8px; cursor: pointer; font-size: 16px;">\n 📋\n </span>\n `;return this.isFileTracked(e,n).then(e=>{const t=document.getElementById(s);t&&(e?(t.innerHTML="📋",t.title="View git diff for this file operation",t.classList.add("tracked-file")):(t.innerHTML="📋❌",t.title="File not tracked by git - click to see details",t.classList.add("untracked-file")))}).catch(e=>{console.error("Error updating git diff icon:",e)}),i}showAgentInstanceDetails(e){const t=this.agentInference.getPMDelegations().get(e);if(!t)return void console.error("Agent instance not found:",e);console.log("Showing agent instance details for:",e,t);const n=`\n <div class="agent-instance-details">\n <h3>Agent Instance: ${t.agentName}</h3>\n <p><strong>Type:</strong> ${t.isImplied?"Implied PM Delegation":"Explicit PM Delegation"}</p>\n <p><strong>Start Time:</strong> ${this.formatTimestamp(t.timestamp)}</p>\n <p><strong>Event Count:</strong> ${t.agentEvents.length}</p>\n <p><strong>Session:</strong> ${t.sessionId}</p>\n ${t.pmCall?`<p><strong>PM Call:</strong> Task delegation to ${t.agentName}</p>`:"<p><strong>Note:</strong> Implied delegation (no explicit PM call found)</p>"}\n </div>\n `;console.log("Agent instance details HTML:",n)}}export{e as E,t as a};
1
+ class e{constructor(e,t){this.container=document.getElementById(e),this.socketClient=t,this.events=[],this.filteredEvents=[],this.selectedEventIndex=-1,this.filteredEventElements=[],this.autoScroll=!0,this.searchFilter="",this.typeFilter="",this.sessionFilter="",this.eventTypeCount={},this.availableEventTypes=new Set,this.errorCount=0,this.eventsThisMinute=0,this.lastMinute=(new Date).getMinutes(),this.init()}init(){this.setupEventHandlers(),this.setupKeyboardNavigation(),this.socketClient.onEventUpdate((e,t)=>{this.events=Array.isArray(e)?e:[],this.updateDisplay()})}setupEventHandlers(){const e=document.getElementById("events-search-input");e&&e.addEventListener("input",e=>{this.searchFilter=e.target.value.toLowerCase(),this.applyFilters()});const t=document.getElementById("events-type-filter");t&&t.addEventListener("change",e=>{this.typeFilter=e.target.value,this.applyFilters()})}setupKeyboardNavigation(){}handleArrowNavigation(e){if(0===this.filteredEventElements.length)return;let t=this.selectedEventIndex+e;t>=this.filteredEventElements.length?t=0:t<0&&(t=this.filteredEventElements.length-1),this.showEventDetails(t)}applyFilters(){this.events&&Array.isArray(this.events)||(console.warn("EventViewer: events array is not initialized, using empty array"),this.events=[]),this.filteredEvents=this.events.filter(e=>{if(this.searchFilter){if(![e.type||"",e.subtype||"",JSON.stringify(e.data||{})].join(" ").toLowerCase().includes(this.searchFilter))return!1}if(this.typeFilter){const t=e.type&&""!==e.type.trim()?e.type:"";if((e.subtype&&t?`${t}.${e.subtype}`:t)!==this.typeFilter)return!1}return!(this.sessionFilter&&""!==this.sessionFilter&&(!e.data||e.data.session_id!==this.sessionFilter))}),this.renderEvents(),this.updateMetrics()}updateEventTypeDropdown(){const e=document.getElementById("events-type-filter");if(!e)return;const t=new Set;this.events&&Array.isArray(this.events)||(console.warn("EventViewer: events array is not initialized in updateEventTypeDropdown"),this.events=[]),this.events.forEach(e=>{if(e.type&&""!==e.type.trim()){const n=e.subtype?`${e.type}.${e.subtype}`:e.type;t.add(n)}});const n=Array.from(t).sort(),s=Array.from(this.availableEventTypes).sort();if(JSON.stringify(n)===JSON.stringify(s))return;this.availableEventTypes=t;const i=e.value;e.innerHTML='<option value="">All Events</option>';Array.from(t).sort().forEach(t=>{const n=document.createElement("option");n.value=t,n.textContent=t,e.appendChild(n)}),i&&t.has(i)?e.value=i:i&&!t.has(i)&&(e.value="",this.typeFilter="")}updateDisplay(){this.updateEventTypeDropdown(),this.applyFilters()}renderEvents(){const e=document.getElementById("events-list");if(!e)return;const t=e.scrollTop+e.clientHeight>=e.scrollHeight-10;if(0===this.filteredEvents.length)return e.innerHTML=`\n <div class="no-events">\n ${0===this.events.length?"Connect to Socket.IO server to see events...":"No events match current filters..."}\n </div>\n `,void(this.filteredEventElements=[]);const n=this.filteredEvents.map((e,t)=>{const n=new Date(e.timestamp).toLocaleTimeString();return`\n <div class="event-item single-row ${e.type?`event-${e.type}`:"event-default"} ${t===this.selectedEventIndex?"selected":""}"\n onclick="eventViewer.showEventDetails(${t})"\n data-index="${t}">\n <span class="event-single-row-content">\n <span class="event-content-main">${this.formatSingleRowEventContent(e)}</span>\n <span class="event-timestamp">${n}</span>\n </span>\n ${this.createInlineEditDiffViewer(e,t)}\n </div>\n `}).join("");e.innerHTML=n,this.filteredEventElements=Array.from(e.querySelectorAll(".event-item")),window.dashboard&&"events"===window.dashboard.currentTab&&window.dashboard.tabNavigation&&window.dashboard.tabNavigation.events&&(window.dashboard.tabNavigation.events.items=this.filteredEventElements),this.filteredEvents.length>0&&t&&this.autoScroll&&requestAnimationFrame(()=>{e.scrollTop=e.scrollHeight})}formatEventType(e){return e.type&&e.subtype?e.type===e.subtype||"generic"===e.subtype?e.type:`${e.type}.${e.subtype}`:e.type?e.type:e.originalEventName?e.originalEventName:"unknown"}formatEventData(e){if(!e.data)return"No data";switch(e.type){case"session":return this.formatSessionEvent(e);case"claude":return this.formatClaudeEvent(e);case"agent":return this.formatAgentEvent(e);case"hook":return this.formatHookEvent(e);case"todo":return this.formatTodoEvent(e);case"memory":return this.formatMemoryEvent(e);case"log":return this.formatLogEvent(e);case"code":return this.formatCodeEvent(e);default:return this.formatGenericEvent(e)}}formatSessionEvent(e){const t=e.data;return"started"===e.subtype?`<strong>Session started:</strong> ${t.session_id||"Unknown"}`:"ended"===e.subtype?`<strong>Session ended:</strong> ${t.session_id||"Unknown"}`:`<strong>Session:</strong> ${JSON.stringify(t)}`}formatClaudeEvent(e){const t=e.data;if("request"===e.subtype){const e=t.prompt||t.message||"";return`<strong>Request:</strong> ${e.length>100?e.substring(0,100)+"...":e}`}if("response"===e.subtype){const e=t.response||t.content||"";return`<strong>Response:</strong> ${e.length>100?e.substring(0,100)+"...":e}`}return`<strong>Claude:</strong> ${JSON.stringify(t)}`}formatAgentEvent(e){const t=e.data;return"loaded"===e.subtype?`<strong>Agent loaded:</strong> ${t.agent_type||t.name||"Unknown"}`:"executed"===e.subtype?`<strong>Agent executed:</strong> ${t.agent_type||t.name||"Unknown"}`:`<strong>Agent:</strong> ${JSON.stringify(t)}`}formatHookEvent(e){const t=e.data,n=t.event_type||e.subtype||"unknown";switch(n){case"user_prompt":const s=t.prompt_text||t.prompt_preview||"";return`<strong>User Prompt:</strong> ${(s.length>80?s.substring(0,80)+"...":s)||"No prompt text"}`;case"pre_tool":const i=t.tool_name||"Unknown tool";return`<strong>Pre-Tool (${t.operation_type||"operation"}):</strong> ${i}`;case"post_tool":const o=t.tool_name||"Unknown tool";return`<strong>Post-Tool (${t.success?"success":t.status||"failed"}):</strong> ${o}${t.duration_ms?` (${t.duration_ms}ms)`:""}`;case"notification":return`<strong>Notification (${t.notification_type||"notification"}):</strong> ${t.message_preview||t.message||"No message"}`;case"stop":const r=t.reason||"unknown";return`<strong>Stop (${t.stop_type||"normal"}):</strong> ${r}`;case"subagent_start":const a=t.agent_type||t.agent||t.subagent_type||"Unknown",l=t.prompt||t.description||t.task||"No description",c=l.length>60?l.substring(0,60)+"...":l;return`<strong>Subagent Start (${this.formatAgentType(a)}):</strong> ${c}`;case"subagent_stop":const d=t.agent_type||t.agent||t.subagent_type||"Unknown",p=t.reason||t.stop_reason||"completed",g=this.formatAgentType(d),u=t.structured_response?.task_completed;return`<strong>Subagent Stop (${g})${void 0!==u?u?" ✓":" ✗":""}:</strong> ${p}`;default:const h=t.hook_name||t.name||t.event_type||"Unknown";return`<strong>Hook ${e.subtype||n}:</strong> ${h}`}}formatTodoEvent(e){const t=e.data;if(t.todos&&Array.isArray(t.todos)){const e=t.todos.length;return`<strong>Todo updated:</strong> ${e} item${1!==e?"s":""}`}return`<strong>Todo:</strong> ${JSON.stringify(t)}`}formatMemoryEvent(e){const t=e.data;return`<strong>Memory ${t.operation||"unknown"}:</strong> ${t.key||"Unknown key"}`}formatLogEvent(e){const t=e.data,n=t.level||"info",s=t.message||"",i=s.length>80?s.substring(0,80)+"...":s;return`<strong>[${n.toUpperCase()}]</strong> ${i}`}formatCodeEvent(e){const t=e.data||{};if("progress"===e.subtype){const e=t.message||"Processing...",n=t.percentage;return void 0!==n?`<strong>Progress:</strong> ${e} (${Math.round(n)}%)`:`<strong>Progress:</strong> ${e}`}if("analysis:queued"===e.subtype)return`<strong>Queued:</strong> Analysis for ${t.path||"Unknown path"}`;if("analysis:start"===e.subtype)return`<strong>Started:</strong> Analyzing ${t.path||"Unknown path"}`;if("analysis:complete"===e.subtype){return`<strong>Complete:</strong> Analysis finished${t.duration?` (${t.duration.toFixed(2)}s)`:""}`}if("analysis:error"===e.subtype)return`<strong>Error:</strong> ${t.message||"Analysis failed"}`;if("analysis:cancelled"===e.subtype)return`<strong>Cancelled:</strong> Analysis stopped for ${t.path||"Unknown path"}`;if("file:start"===e.subtype)return`<strong>File:</strong> Processing ${t.file||"Unknown file"}`;if("file:complete"===e.subtype){const e=void 0!==t.nodes_count?` (${t.nodes_count} nodes)`:"";return`<strong>File done:</strong> ${t.file||"Unknown file"}${e}`}if("node:found"===e.subtype)return`<strong>Node:</strong> Found ${t.node_type||"element"} "${t.name||"unnamed"}"`;if("error"===e.subtype)return`<strong>Error:</strong> ${t.error||"Unknown error"} in ${t.file||"file"}`;const n=JSON.stringify(t);return`<strong>Code:</strong> ${n.length>100?n.substring(0,100)+"...":n}`}formatGenericEvent(e){const t=e.data;return"string"==typeof t?t.length>100?t.substring(0,100)+"...":t:JSON.stringify(t)}formatAgentType(e){const t={research:"Research",architect:"Architect",engineer:"Engineer",qa:"QA",pm:"PM",project_manager:"PM",research_agent:"Research",architect_agent:"Architect",engineer_agent:"Engineer",qa_agent:"QA",unknown:"Unknown"},n=(e||"unknown").toLowerCase();if(t[n])return t[n];const s=e.match(/^(\w+)(?:_agent|Agent)?$/i);return s&&s[1]?s[1].charAt(0).toUpperCase()+s[1].slice(1).toLowerCase():e.charAt(0).toUpperCase()+e.slice(1)}formatSingleRowEventContent(e){const t=this.formatEventType(e),n=e.data||{},s=e.source&&"system"!==e.source?`[${e.source}] `:"";let i="";switch(e.type){case"hook":const t=e.tool_name||n.tool_name||"Unknown",s=e.subtype||"Unknown";if("pre_tool"===s||"post_tool"===s){const e=n.operation_type||"",o="post_tool"===s&&void 0!==n.success?n.success?"✓":"✗":"";i=`${t}${e?` (${e})`:""}${o?` ${o}`:""}`}else if("user_prompt"===s){const e=n.prompt_text||n.prompt_preview||"";i=(e.length>60?e.substring(0,60)+"...":e)||"No prompt text"}else if("subagent_start"===s){const e=n.agent_type||n.agent||n.subagent_type||"Unknown",t=this.formatAgentType(e),s=n.prompt||n.description||n.task||"",o=s.length>40?s.substring(0,40)+"...":s;i=o?`${t} - ${o}`:t}else if("subagent_stop"===s){const e=n.agent_type||n.agent||n.subagent_type||"Unknown",t=this.formatAgentType(e),s=n.reason||n.stop_reason||"completed",o=n.structured_response?.task_completed,r=void 0!==o?o?"✓":"✗":"";i=`${t}${r?" "+r:""} - ${s}`}else if("stop"===s){const e=n.reason||"completed";i=`${n.stop_type||"normal"} - ${e}`}else i=t;break;case"agent":const o=e.subagent_type||n.subagent_type||"PM",r=n.status||"";i=`${o}${r?` - ${r}`:""}`;break;case"todo":if(n.todos&&Array.isArray(n.todos)){i=`${n.todos.length} items (${n.todos.filter(e=>"completed"===e.status).length} completed, ${n.todos.filter(e=>"in_progress"===e.status).length} in progress)`}else i="Todo update";break;case"memory":i=`${n.operation||"unknown"}: ${n.key||"unknown"}${n.value?` = ${JSON.stringify(n.value).substring(0,30)}...`:""}`;break;case"session":i=`ID: ${n.session_id||"unknown"}`;break;case"claude":if("request"===e.subtype){const e=n.prompt||n.message||"";i=(e.length>60?e.substring(0,60)+"...":e)||"Empty request"}else if("response"===e.subtype){const e=n.response||n.content||"";i=(e.length>60?e.substring(0,60)+"...":e)||"Empty response"}else i=n.message||"Claude interaction";break;case"log":const a=n.level||"info",l=n.message||"",c=l.length>60?l.substring(0,60)+"...":l;i=`[${a.toUpperCase()}] ${c}`;break;case"test":i=n.test_name||n.name||"Test";break;default:if("string"==typeof n)i=n.length>60?n.substring(0,60)+"...":n;else if(n.message)i=n.message.length>60?n.message.substring(0,60)+"...":n.message;else if(n.name)i=n.name;else if(Object.keys(n).length>0){const e=Object.keys(n).find(e=>!["timestamp","id"].includes(e));if(e){const t=n[e];i=`${e}: ${"object"==typeof t?JSON.stringify(t).substring(0,40)+"...":t}`}}}const o=`${s}${t}`;return i?`${o} - ${i}`:o}getHookDisplayName(e,t){const n={pre_tool:"Pre-Tool",post_tool:"Post-Tool",user_prompt:"User-Prompt",stop:"Stop",subagent_start:"Subagent-Start",subagent_stop:"Subagent-Stop",notification:"Notification"};if(n[e])return n[e];return String(e||"unknown").replace(/_/g," ")}getEventCategory(e){const t=e.data||{},n=e.tool_name||t.tool_name||"";return["Read","Write","Edit","MultiEdit"].includes(n)?"file_operations":["Bash","grep","Glob"].includes(n)?"system_operations":"TodoWrite"===n?"task_management":"Task"===n||"subagent_start"===e.subtype||"subagent_stop"===e.subtype?"agent_delegation":"stop"===e.subtype?"session_control":"general"}showEventDetails(e){if(!this.filteredEvents||!Array.isArray(this.filteredEvents))return void console.warn("EventViewer: filteredEvents array is not initialized");if(e<0||e>=this.filteredEvents.length)return;this.selectedEventIndex=e;const t=this.filteredEvents[e];window.dashboard&&(window.dashboard.tabNavigation&&window.dashboard.tabNavigation.events&&(window.dashboard.tabNavigation.events.selectedIndex=e),window.dashboard.selectCard&&window.dashboard.selectCard("events",e,"event",t)),this.filteredEventElements.forEach((t,n)=>{t.classList.toggle("selected",n===e)}),document.dispatchEvent(new CustomEvent("eventSelected",{detail:{event:t,index:e}}));const n=this.filteredEventElements[e];n&&n.scrollIntoView({behavior:"smooth",block:"nearest"})}clearSelection(){this.selectedEventIndex=-1,this.filteredEventElements.forEach(e=>{e.classList.remove("selected")}),window.dashboard&&(window.dashboard.tabNavigation&&window.dashboard.tabNavigation.events&&(window.dashboard.tabNavigation.events.selectedIndex=-1),window.dashboard.clearCardSelection&&window.dashboard.clearCardSelection()),document.dispatchEvent(new CustomEvent("eventSelectionCleared"))}updateMetrics(){this.eventTypeCount={},this.errorCount=0,this.events&&Array.isArray(this.events)||(console.warn("EventViewer: events array is not initialized in updateMetrics"),this.events=[]),this.events.forEach(e=>{const t=e.type||"unknown";this.eventTypeCount[t]=(this.eventTypeCount[t]||0)+1,"log"===e.type&&e.data&&["error","critical"].includes(e.data.level)&&this.errorCount++});const e=(new Date).getMinutes();e!==this.lastMinute&&(this.lastMinute=e,this.eventsThisMinute=0);const t=new Date(Date.now()-6e4);this.eventsThisMinute=this.events.filter(e=>new Date(e.timestamp)>t).length,this.updateMetricsUI()}updateMetricsUI(){const e=document.getElementById("total-events"),t=document.getElementById("events-per-minute"),n=document.getElementById("unique-types"),s=document.getElementById("error-count");e&&(e.textContent=this.events.length),t&&(t.textContent=this.eventsThisMinute),n&&(n.textContent=Object.keys(this.eventTypeCount).length),s&&(s.textContent=this.errorCount)}exportEvents(){const e=JSON.stringify(this.filteredEvents,null,2),t=new Blob([e],{type:"application/json"}),n=URL.createObjectURL(t),s=document.createElement("a");s.href=n,s.download=`claude-mpm-events-${(new Date).toISOString().split("T")[0]}.json`,s.click(),URL.revokeObjectURL(n)}clearEvents(){this.socketClient.clearEvents(),this.selectedEventIndex=-1,this.updateDisplay()}setSessionFilter(e){this.sessionFilter=e,this.applyFilters()}getFilters(){return{search:this.searchFilter,type:this.typeFilter,session:this.sessionFilter}}getFilteredEvents(){return this.filteredEvents}getAllEvents(){return this.events}createInlineEditDiffViewer(e,t){const n=e.data||{},s=e.tool_name||n.tool_name||"";if(!["Edit","MultiEdit"].includes(s))return"";let i=[];if("Edit"===s){const t=e.tool_parameters||n.tool_parameters||{};t.old_string&&t.new_string&&i.push({old_string:t.old_string,new_string:t.new_string,file_path:t.file_path||"unknown"})}else if("MultiEdit"===s){const t=e.tool_parameters||n.tool_parameters||{};t.edits&&Array.isArray(t.edits)&&(i=t.edits.map(e=>({...e,file_path:t.file_path||"unknown"})))}if(0===i.length)return"";const o=`edit-diff-${t}`,r=i.length>1;let a="";return i.forEach((e,t)=>{const n=this.createDiffHtml(e.old_string,e.new_string);a+=`\n <div class="edit-diff-section">\n ${r?`<div class="edit-diff-header">Edit ${t+1}</div>`:""}\n <div class="diff-content">${n}</div>\n </div>\n `}),`\n <div class="inline-edit-diff-viewer">\n <div class="diff-toggle-header" onclick="eventViewer.toggleEditDiff('${o}', event)">\n <span class="diff-toggle-icon">📋</span>\n <span class="diff-toggle-text">Show ${r?i.length+" edits":"edit"}</span>\n <span class="diff-toggle-arrow">▼</span>\n </div>\n <div id="${o}" class="diff-content-container" style="display: none;">\n ${a}\n </div>\n </div>\n `}createDiffHtml(e,t){const n=e.split("\n"),s=t.split("\n");let i="",o=0,r=0;for(;o<n.length||r<s.length;){const e=o<n.length?n[o]:null,t=r<s.length?s[r]:null;null===e?(i+=`<div class="diff-line diff-added">+ ${this.escapeHtml(t)}</div>`,r++):null===t?(i+=`<div class="diff-line diff-removed">- ${this.escapeHtml(e)}</div>`,o++):e===t?(i+=`<div class="diff-line diff-unchanged"> ${this.escapeHtml(e)}</div>`,o++,r++):(i+=`<div class="diff-line diff-removed">- ${this.escapeHtml(e)}</div>`,i+=`<div class="diff-line diff-added">+ ${this.escapeHtml(t)}</div>`,o++,r++)}return`<div class="diff-container">${i}</div>`}toggleEditDiff(e,t){t.stopPropagation();const n=document.getElementById(e),s=t.currentTarget.querySelector(".diff-toggle-arrow");if(n){const e="none"!==n.style.display;n.style.display=e?"none":"block",s&&(s.textContent=e?"▼":"▲")}}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}}window.EventViewer=e;class t{constructor(e,t){this.eventViewer=e,this.agentInference=t,this.agentEvents=[],this.filteredAgentEvents=[],this.filteredToolEvents=[],this.filteredFileEvents=[],this.selectedSessionId=null,this.fileTrackingCache=new Map,this.trackingCheckTimeout=3e4,console.log("Event processor initialized")}getFilteredEventsForTab(e){const t=this.eventViewer.events;console.log(`getFilteredEventsForTab(${e}) - using RAW events: ${t.length} total`);const n=window.sessionManager;if(n&&n.selectedSessionId){const e=n.getEventsForSession(n.selectedSessionId);return console.log(`Filtering by session ${n.selectedSessionId}: ${e.length} events`),e}return t}applyAgentsFilters(e){const t=document.getElementById("agents-search-input"),n=document.getElementById("agents-type-filter"),s=t?t.value.toLowerCase():"",i=n?n.value:"";return e.filter(e=>{if(s){if(![e.agentName||"",e.type||"",e.isImplied?"implied":"explicit"].join(" ").toLowerCase().includes(s))return!1}if(i){if(!(e.agentName||"unknown").toLowerCase().includes(i.toLowerCase()))return!1}return!0})}applyToolsFilters(e){const t=document.getElementById("tools-search-input"),n=document.getElementById("tools-type-filter"),s=t?t.value.toLowerCase():"",i=n?n.value:"";return e.filter(e=>{if(s){if(![e.tool_name||"",e.agent_type||"",e.type||"",e.subtype||""].join(" ").toLowerCase().includes(s))return!1}if(i){if((e.tool_name||"")!==i)return!1}return!0})}applyToolCallFilters(e){const t=document.getElementById("tools-search-input"),n=document.getElementById("tools-type-filter"),s=t?t.value.toLowerCase():"",i=n?n.value:"";return e.filter(([e,t])=>{if(s){if(![t.tool_name||"",t.agent_type||"","tool_call"].join(" ").toLowerCase().includes(s))return!1}if(i){if((t.tool_name||"")!==i)return!1}return!0})}applyFilesFilters(e){const t=document.getElementById("files-search-input"),n=document.getElementById("files-type-filter"),s=t?t.value.toLowerCase():"",i=n?n.value:"";return e.filter(([e,t])=>{if(this.selectedSessionId){const e=t.operations.filter(e=>e.sessionId===this.selectedSessionId);if(0===e.length)return!1;t={...t,operations:e,lastOperation:e[e.length-1]?.timestamp||t.lastOperation}}if(s){if(![e,...t.operations.map(e=>e.operation),...t.operations.map(e=>e.agent)].join(" ").toLowerCase().includes(s))return!1}if(i){if(!t.operations.map(e=>e.operation).includes(i))return!1}return!0})}extractOperation(e){if(!e)return"unknown";const t=e.toLowerCase();return t.includes("read")?"read":t.includes("write")?"write":t.includes("edit")?"edit":t.includes("create")?"create":t.includes("delete")?"delete":t.includes("move")||t.includes("rename")?"move":"other"}extractToolFromHook(e){if(!e)return"";const t=e.match(/^(?:Pre|Post)(.+)Use$/);return t?t[1]:""}extractToolFromSubtype(e){if(!e)return"";if(e.includes("_")){return e.split("_")[0]||""}return e}extractToolTarget(e,t,n){const s=t||n||{};switch(e?.toLowerCase()){case"read":case"write":case"edit":return s.file_path||s.path||"";case"bash":return s.command||"";case"grep":return s.pattern||"";case"task":return s.subagent_type||s.agent_type||"";default:const e=Object.keys(s),t=["path","file_path","command","pattern","query","target"];for(const n of t)if(s[n])return s[n];return e.length>0?`${e[0]}: ${s[e[0]]}`:""}}generateAgentHTML(e){const t=this.agentInference.getUniqueAgentInstances();return this.applyAgentsFilters(t).map((e,t)=>{const n=e.agentName,s=this.formatTimestamp(e.firstTimestamp||e.timestamp),i=e.isImplied?"implied":"explicit",o=e.totalEventCount||e.eventCount||0;return`\n <div class="event-item single-row event-agent" onclick="${`dashboard.selectCard('agents', ${t}, 'agent_instance', '${e.id}'); dashboard.showAgentInstanceDetails('${e.id}');`}">\n <span class="event-single-row-content">\n <span class="event-content-main">${`${n} (${i}, ${o} events)`}</span>\n <span class="event-timestamp">${s}</span>\n </span>\n </div>\n `}).join("")}generateToolHTML(e){return this.applyToolCallFilters(e).map(([e,t],n)=>{const s=t.tool_name||"Unknown",i=t.agent_type||"Unknown",o=this.formatTimestamp(t.timestamp);return`\n <div class="event-item single-row event-tool ${"completed"===(t.post_event?"completed":"pending")?"status-success":"status-pending"}" onclick="dashboard.selectCard('tools', ${n}, 'toolCall', '${e}'); dashboard.showToolCallDetails('${e}')">\n <span class="event-single-row-content">\n <span class="event-content-main">${`${s} (${"pm"===i.toLowerCase()?"pm":i})`}</span>\n <span class="event-timestamp">${o}</span>\n </span>\n </div>\n `}).join("")}generateFileHTML(e){return this.applyFilesFilters(e).map(([e,t],n)=>{const s=t.operations.map(e=>e.operation),i=this.formatTimestamp(t.lastOperation),o={};s.forEach(e=>{o[e]=(o[e]||0)+1});const r=Object.entries(o).map(([e,t])=>`${e}(${t})`).join(", "),a=[...new Set(t.operations.map(e=>e.agent))],l=a.length>1?`by ${a.length} agents`:`by ${a[0]||"unknown"}`;return`\n <div class="event-item single-row file-item" onclick="dashboard.selectCard('files', ${n}, 'file', '${e}'); dashboard.showFileDetails('${e}')">\n <span class="event-single-row-content">\n <span class="event-content-main">${`${this.getRelativeFilePath(e)} ${r} ${l}`}</span>\n <span class="event-timestamp">${i}</span>\n </span>\n </div>\n `}).join("")}getFileOperationIcon(e){return e.includes("write")||e.includes("create")?"📝":e.includes("edit")?"✏️":e.includes("read")?"👁️":e.includes("delete")?"🗑️":e.includes("move")?"📦":"📄"}getRelativeFilePath(e){if(!e)return"";const t=e.split("/");return t.length>3?".../"+t.slice(-2).join("/"):e}formatTimestamp(e){if(!e)return"";return new Date(e).toLocaleTimeString()}setSelectedSessionId(e){this.selectedSessionId=e}getSelectedSessionId(){return this.selectedSessionId}getUniqueToolInstances(e){return this.applyToolCallFilters(e)}getUniqueFileInstances(e){return this.applyFilesFilters(e)}async isFileTracked(e,t){const n=`${t}:${e}`,s=Date.now(),i=this.fileTrackingCache.get(n);if(i&&s-i.timestamp<this.trackingCheckTimeout)return i.is_tracked;try{const i=window.socket;return i?new Promise(o=>{const r=t=>{if(t.file_path===e){const e=t.success&&t.is_tracked;this.fileTrackingCache.set(n,{is_tracked:e,timestamp:s}),i.off("file_tracked_response",r),o(e)}};i.on("file_tracked_response",r),i.emit("check_file_tracked",{file_path:e,working_dir:t}),setTimeout(()=>{i.off("file_tracked_response",r),o(!1)},5e3)}):(console.warn("No socket connection available for git tracking check"),!1)}catch(o){return console.error("Error checking file tracking status:",o),!1}}generateGitDiffIcon(e,t,n){const s=`git-icon-${e.replace(/[^a-zA-Z0-9]/g,"-")}-${t}`,i=`\n <span id="${s}" class="git-diff-icon"\n onclick="event.stopPropagation(); showGitDiffModal('${e}', '${t}')"\n title="View git diff for this file operation"\n style="margin-left: 8px; cursor: pointer; font-size: 16px;">\n 📋\n </span>\n `;return this.isFileTracked(e,n).then(e=>{const t=document.getElementById(s);t&&(e?(t.innerHTML="📋",t.title="View git diff for this file operation",t.classList.add("tracked-file")):(t.innerHTML="📋❌",t.title="File not tracked by git - click to see details",t.classList.add("untracked-file")))}).catch(e=>{console.error("Error updating git diff icon:",e)}),i}showAgentInstanceDetails(e){const t=this.agentInference.getPMDelegations().get(e);if(!t)return void console.error("Agent instance not found:",e);console.log("Showing agent instance details for:",e,t);const n=`\n <div class="agent-instance-details">\n <h3>Agent Instance: ${t.agentName}</h3>\n <p><strong>Type:</strong> ${t.isImplied?"Implied PM Delegation":"Explicit PM Delegation"}</p>\n <p><strong>Start Time:</strong> ${this.formatTimestamp(t.timestamp)}</p>\n <p><strong>Event Count:</strong> ${t.agentEvents.length}</p>\n <p><strong>Session:</strong> ${t.sessionId}</p>\n ${t.pmCall?`<p><strong>PM Call:</strong> Task delegation to ${t.agentName}</p>`:"<p><strong>Note:</strong> Implied delegation (no explicit PM call found)</p>"}\n </div>\n `;console.log("Agent instance details HTML:",n)}}export{e as E,t as a};
2
2
  //# sourceMappingURL=event-viewer.js.map