// ========================================== // HELP VIEW // Command guide with categories, workflow diagrams, and CodexLens quick-start // ========================================== // State variables var helpData = { commands: [], grouped: {}, workflows: {}, codexlens: {} }; var activeHelpTab = 'cli'; var helpSearchQuery = ''; var helpSearchTimeout = null; var cytoscapeInstance = null; var activeWorkflowDiagram = 'decision'; // ========== Main Render Function ========== async function renderHelpView() { // Debug: Check if ht function is available console.log('[Help View] ht function available:', typeof ht, typeof window.ht); hideStatsAndCarousel(); var container = document.getElementById('mainContent'); if (!container) return; // Show loading state container.innerHTML = '
'; if (typeof lucide !== 'undefined') lucide.createIcons(); // Load help data await loadHelpData(); // Render layout container.innerHTML = renderHelpLayout(); // Initialize event handlers initializeHelpEventHandlers(); // Render initial tab renderCommandsTab(activeHelpTab); if (typeof lucide !== 'undefined') lucide.createIcons(); } // ========== Data Loading ========== async function loadHelpData() { try { // Load all commands with grouping var commandsResp = await fetch('/api/help/commands'); if (commandsResp.ok) { var data = await commandsResp.json(); helpData.commands = data.commands || []; helpData.grouped = data.grouped || {}; } // Load workflow relationships var workflowsResp = await fetch('/api/help/workflows'); if (workflowsResp.ok) { helpData.workflows = await workflowsResp.json(); } // Load CodexLens data var codexResp = await fetch('/api/help/codexlens'); if (codexResp.ok) { helpData.codexlens = await codexResp.json(); } } catch (err) { console.error('Failed to load help data:', err); } } // ========== Layout Rendering ========== function renderHelpLayout() { return `

${ht('help.title')}

${ht('help.subtitle')}

`; } // ========== Event Handlers ========== function initializeHelpEventHandlers() { // Tab switching var tabs = document.querySelectorAll('.help-main-tab'); tabs.forEach(function(tab) { tab.addEventListener('click', function() { var tabName = this.dataset.tab; switchHelpTab(tabName); }); }); // Update active tab styles updateActiveTab(activeHelpTab); // Search input with debounce var searchInput = document.getElementById('helpSearchInput'); if (searchInput) { searchInput.addEventListener('input', function(e) { clearTimeout(helpSearchTimeout); helpSearchTimeout = setTimeout(function() { helpSearchQuery = e.target.value; performHelpSearch(); }, 300); }); } } function switchHelpTab(tabName) { activeHelpTab = tabName; updateActiveTab(tabName); if (tabName === 'diagrams') { renderWorkflowDiagrams(); } else if (tabName === 'codexlens') { renderCodexLensQuickStart(); } else { renderCommandsTab(tabName); } } function updateActiveTab(activeTab) { var tabs = document.querySelectorAll('.help-main-tab'); tabs.forEach(function(tab) { if (tab.dataset.tab === activeTab) { tab.classList.add('bg-primary', 'text-primary-foreground'); tab.classList.remove('bg-transparent', 'text-muted-foreground', 'hover:bg-muted'); } else { tab.classList.remove('bg-primary', 'text-primary-foreground'); tab.classList.add('bg-transparent', 'text-muted-foreground', 'hover:bg-muted'); } }); } // ========== Command Rendering ========== function renderCommandsTab(category) { var container = document.getElementById('helpTabContent'); if (!container) return; var categoryData = helpData.grouped[category]; if (!categoryData) { container.innerHTML = `

No commands found for this category

`; if (typeof lucide !== 'undefined') lucide.createIcons(); return; } var filteredCommands = helpSearchQuery ? filterCommandsBySearch(categoryData.commands, helpSearchQuery) : categoryData.commands; var html = ''; // Show search results count if (helpSearchQuery) { html += `
Found ${filteredCommands.length} commands matching "${escapeHtml(helpSearchQuery)}"
`; } // Render direct commands if (filteredCommands.length > 0) { html += '
'; filteredCommands.forEach(function(cmd) { html += renderCommandCard(cmd); }); html += '
'; } // Render subcategories as accordions var subcategories = categoryData.subcategories || {}; var subcategoryKeys = Object.keys(subcategories); if (subcategoryKeys.length > 0) { html += '
'; subcategoryKeys.forEach(function(subcat) { var subcatCommands = helpSearchQuery ? filterCommandsBySearch(subcategories[subcat], helpSearchQuery) : subcategories[subcat]; if (subcatCommands.length > 0) { html += renderSubcategoryAccordion(subcat, subcatCommands); } }); html += '
'; } if (filteredCommands.length === 0 && subcategoryKeys.length === 0) { html = `

No commands found matching your search

`; } container.innerHTML = html; if (typeof lucide !== 'undefined') lucide.createIcons(); // Initialize accordion handlers initializeAccordions(); } function renderCommandCard(cmd) { var difficultyColor = { 'Beginner': 'bg-success-light text-success', 'Intermediate': 'bg-warning-light text-warning', 'Advanced': 'bg-error-light text-error' }[cmd.difficulty] || 'bg-muted text-muted-foreground'; return `
${escapeHtml(cmd.command)} ${escapeHtml(cmd.difficulty)}

${escapeHtml(cmd.description)}

${cmd.arguments ? `
Arguments: ${escapeHtml(cmd.arguments)}
` : ''}
`; } function renderSubcategoryAccordion(subcatName, commands) { var accordionId = 'accordion-' + subcatName.replace(/\s+/g, '-').toLowerCase(); return `
`; } function initializeAccordions() { var headers = document.querySelectorAll('.accordion-header'); headers.forEach(function(header) { header.addEventListener('click', function() { var content = this.nextElementSibling; var icon = this.querySelector('.accordion-icon'); if (content.classList.contains('hidden')) { content.classList.remove('hidden'); icon.style.transform = 'rotate(90deg)'; } else { content.classList.add('hidden'); icon.style.transform = 'rotate(0deg)'; } }); }); } // ========== Search Functions ========== function filterCommandsBySearch(commands, query) { if (!query) return commands; var lowerQuery = query.toLowerCase(); return commands.filter(function(cmd) { return (cmd.name && cmd.name.toLowerCase().includes(lowerQuery)) || (cmd.command && cmd.command.toLowerCase().includes(lowerQuery)) || (cmd.description && cmd.description.toLowerCase().includes(lowerQuery)) || (cmd.category && cmd.category.toLowerCase().includes(lowerQuery)); }); } async function performHelpSearch() { // Reload data with search query try { var url = '/api/help/commands' + (helpSearchQuery ? '?q=' + encodeURIComponent(helpSearchQuery) : ''); var resp = await fetch(url); if (resp.ok) { var data = await resp.json(); helpData.commands = data.commands || []; helpData.grouped = data.grouped || {}; } } catch (err) { console.error('Search failed:', err); } // Re-render current tab if (activeHelpTab !== 'diagrams' && activeHelpTab !== 'codexlens') { renderCommandsTab(activeHelpTab); } } // ========== Workflow Diagrams ========== function renderWorkflowDiagrams() { var container = document.getElementById('helpTabContent'); if (!container) return; container.innerHTML = `

${ht('help.diagrams.title')}

${ht('help.diagrams.legend')}

${ht('help.diagrams.legend.prerequisites')}
${ht('help.diagrams.legend.nextSteps')}
${ht('help.diagrams.legend.alternatives')}
`; if (typeof lucide !== 'undefined') lucide.createIcons(); // Initialize workflow diagram buttons var diagramBtns = document.querySelectorAll('.workflow-diagram-btn'); diagramBtns.forEach(function(btn) { btn.addEventListener('click', function() { activeWorkflowDiagram = this.dataset.workflow; updateActiveWorkflowBtn(activeWorkflowDiagram); initializeCytoscapeDiagram(activeWorkflowDiagram); }); }); // Initialize control buttons var fitBtn = document.getElementById('fitDiagramBtn'); if (fitBtn) { fitBtn.addEventListener('click', function() { if (cytoscapeInstance) cytoscapeInstance.fit(); }); } var zoomInBtn = document.getElementById('zoomInBtn'); if (zoomInBtn) { zoomInBtn.addEventListener('click', function() { if (cytoscapeInstance) cytoscapeInstance.zoom(cytoscapeInstance.zoom() * 1.2); }); } var zoomOutBtn = document.getElementById('zoomOutBtn'); if (zoomOutBtn) { zoomOutBtn.addEventListener('click', function() { if (cytoscapeInstance) cytoscapeInstance.zoom(cytoscapeInstance.zoom() * 0.8); }); } // Update active button updateActiveWorkflowBtn(activeWorkflowDiagram); // Initialize Cytoscape diagram setTimeout(function() { initializeCytoscapeDiagram(activeWorkflowDiagram); }, 100); } function updateActiveWorkflowBtn(workflow) { var btns = document.querySelectorAll('.workflow-diagram-btn'); btns.forEach(function(btn) { if (btn.dataset.workflow === workflow) { btn.classList.add('bg-primary', 'text-primary-foreground'); btn.classList.remove('bg-muted', 'text-muted-foreground'); } else { btn.classList.remove('bg-primary', 'text-primary-foreground'); btn.classList.add('bg-muted', 'text-muted-foreground'); } }); } function initializeCytoscapeDiagram(workflow) { var container = document.getElementById('cytoscapeContainer'); if (!container) return; // Destroy previous instance if (cytoscapeInstance) { cytoscapeInstance.destroy(); cytoscapeInstance = null; } // Get workflow data var graphData = getWorkflowGraphData(workflow); // Check if cytoscape is available if (typeof cytoscape === 'undefined') { container.innerHTML = '
' + ht('help.diagrams.notLoaded') + '
'; return; } // Get computed CSS variable values var rootStyles = getComputedStyle(document.documentElement); var primaryColor = rootStyles.getPropertyValue('--primary').trim(); var foregroundColor = rootStyles.getPropertyValue('--foreground').trim(); var mutedColor = rootStyles.getPropertyValue('--muted-foreground').trim(); // Convert HSL values to usable format var primaryHsl = primaryColor ? 'hsl(' + primaryColor + ')' : '#3B82F6'; var foregroundHsl = foregroundColor ? 'hsl(' + foregroundColor + ')' : '#1F2937'; var mutedHsl = mutedColor ? 'hsl(' + mutedColor + ')' : '#6B7280'; // Initialize Cytoscape cytoscapeInstance = cytoscape({ container: container, elements: graphData, style: [ { selector: 'node', style: { 'shape': 'roundrectangle', 'background-color': primaryHsl, 'background-opacity': 0.9, 'border-width': 2, 'border-color': primaryHsl, 'border-opacity': 1, 'label': 'data(label)', 'color': '#FFFFFF', 'text-valign': 'center', 'text-halign': 'center', 'font-size': '14px', 'font-weight': '600', 'width': '140px', 'height': '60px', 'text-wrap': 'wrap', 'text-max-width': '130px', 'padding': '8px', 'shadow-blur': 10, 'shadow-color': '#000000', 'shadow-opacity': 0.2, 'shadow-offset-x': 0, 'shadow-offset-y': 2 } }, { selector: 'edge', style: { 'width': 3, 'line-color': mutedHsl, 'target-arrow-color': mutedHsl, 'target-arrow-shape': 'triangle', 'target-arrow-fill': 'filled', 'arrow-scale': 1.5, 'curve-style': 'bezier', 'label': 'data(label)', 'font-size': '12px', 'font-weight': '500', 'color': foregroundHsl, 'text-background-color': '#FFFFFF', 'text-background-opacity': 0.9, 'text-background-padding': '4px', 'text-background-shape': 'roundrectangle', 'text-border-width': 1, 'text-border-color': mutedHsl, 'text-border-opacity': 0.3 } }, { selector: 'edge.prerequisite', style: { 'line-color': primaryHsl, 'target-arrow-color': primaryHsl, 'width': 3 } }, { selector: 'edge.next-step', style: { 'line-color': '#10B981', 'target-arrow-color': '#10B981', 'width': 3, 'line-style': 'solid' } }, { selector: 'edge.alternative', style: { 'line-color': '#F59E0B', 'target-arrow-color': '#F59E0B', 'line-style': 'dashed', 'line-dash-pattern': [10, 5], 'width': 2.5 } } ], layout: { name: 'breadthfirst', directed: true, padding: 80, spacingFactor: 2, avoidOverlap: true, nodeDimensionsIncludeLabels: true, animate: false } }); // Add click handler for nodes cytoscapeInstance.on('tap', 'node', function(evt) { var node = evt.target; var commandName = node.data('id'); showCommandTooltip(commandName, node); }); // Fit to viewport cytoscapeInstance.fit(); } function getWorkflowGraphData(workflow) { var workflows = { 'decision': { nodes: [ { data: { id: 'start', label: ht('help.workflows.decision.start') } }, { data: { id: 'cli-analyze', label: ht('help.workflows.decision.cliAnalyze') } }, { data: { id: 'understand', label: ht('help.workflows.decision.understand') } }, { data: { id: 'simple', label: ht('help.workflows.decision.simple') } }, { data: { id: 'medium', label: ht('help.workflows.decision.medium') } }, { data: { id: 'complex', label: ht('help.workflows.decision.complex') } }, { data: { id: 'claude-exec', label: ht('help.workflows.decision.claudeExec') } }, { data: { id: 'cli-exec', label: ht('help.workflows.decision.cliExec') } }, { data: { id: 'claude-plan', label: ht('help.workflows.decision.claudePlan') } }, { data: { id: 'lite-plan', label: '/workflow:lite-plan' } }, { data: { id: 'full-plan', label: '/workflow:plan' } } ], edges: [ { data: { source: 'start', target: 'cli-analyze' }, classes: 'next-step' }, { data: { source: 'cli-analyze', target: 'understand' }, classes: 'next-step' }, { data: { source: 'understand', target: 'simple' }, classes: 'alternative' }, { data: { source: 'understand', target: 'medium' }, classes: 'alternative' }, { data: { source: 'understand', target: 'complex' }, classes: 'alternative' }, { data: { source: 'simple', target: 'claude-exec', label: '优先' }, classes: 'next-step' }, { data: { source: 'simple', target: 'cli-exec' }, classes: 'alternative' }, { data: { source: 'medium', target: 'claude-plan' }, classes: 'next-step' }, { data: { source: 'medium', target: 'lite-plan' }, classes: 'alternative' }, { data: { source: 'complex', target: 'full-plan' }, classes: 'next-step' } ] }, 'brainstorm': { nodes: [ { data: { id: 'start', label: ht('help.workflows.brainstorm.start') } }, { data: { id: 'question', label: ht('help.workflows.brainstorm.question') } }, { data: { id: 'product', label: ht('help.workflows.brainstorm.product') } }, { data: { id: 'design', label: ht('help.workflows.brainstorm.design') } }, { data: { id: 'brainstorm-product', label: '/workflow:brainstorm:auto-parallel' } }, { data: { id: 'brainstorm-design', label: '/workflow:brainstorm:auto-parallel' } }, { data: { id: 'next', label: ht('help.workflows.brainstorm.next') } } ], edges: [ { data: { source: 'start', target: 'question' }, classes: 'next-step' }, { data: { source: 'question', target: 'product' }, classes: 'alternative' }, { data: { source: 'question', target: 'design' }, classes: 'alternative' }, { data: { source: 'product', target: 'brainstorm-product' }, classes: 'next-step' }, { data: { source: 'design', target: 'brainstorm-design' }, classes: 'next-step' }, { data: { source: 'brainstorm-product', target: 'next' }, classes: 'next-step' }, { data: { source: 'brainstorm-design', target: 'next' }, classes: 'next-step' } ] }, 'cli-resume': { nodes: [ { data: { id: 'first-exec', label: ht('help.workflows.cliResume.firstExec') } }, { data: { id: 'save-context', label: ht('help.workflows.cliResume.saveContext') } }, { data: { id: 'resume-cmd', label: ht('help.workflows.cliResume.resumeCmd') } }, { data: { id: 'merge', label: ht('help.workflows.cliResume.merge') } }, { data: { id: 'continue', label: ht('help.workflows.cliResume.continue') } }, { data: { id: 'split-output', label: ht('help.workflows.cliResume.splitOutput') } }, { data: { id: 'complete', label: ht('help.workflows.cliResume.complete') } } ], edges: [ { data: { source: 'first-exec', target: 'save-context' }, classes: 'next-step' }, { data: { source: 'save-context', target: 'resume-cmd' }, classes: 'next-step' }, { data: { source: 'resume-cmd', target: 'merge' }, classes: 'next-step' }, { data: { source: 'merge', target: 'continue' }, classes: 'next-step' }, { data: { source: 'continue', target: 'split-output' }, classes: 'next-step' }, { data: { source: 'split-output', target: 'complete' }, classes: 'next-step' } ] }, 'bug-fix': { nodes: [ { data: { id: 'start', label: ht('help.workflows.bugFix.start') } }, { data: { id: 'cli-analyze', label: ht('help.workflows.bugFix.cliAnalyze') } }, { data: { id: 'lite-fix', label: '/workflow:lite-fix' } }, { data: { id: 'diagnosis', label: ht('help.workflows.bugFix.diagnosis') } }, { data: { id: 'impact', label: ht('help.workflows.bugFix.impact') } }, { data: { id: 'strategy', label: ht('help.workflows.bugFix.strategy') } }, { data: { id: 'execute', label: ht('help.workflows.bugFix.execute') } }, { data: { id: 'complete', label: ht('help.workflows.bugFix.complete') } } ], edges: [ { data: { source: 'start', target: 'cli-analyze' }, classes: 'next-step' }, { data: { source: 'cli-analyze', target: 'lite-fix' }, classes: 'next-step' }, { data: { source: 'lite-fix', target: 'diagnosis' }, classes: 'next-step' }, { data: { source: 'diagnosis', target: 'impact' }, classes: 'next-step' }, { data: { source: 'impact', target: 'strategy' }, classes: 'next-step' }, { data: { source: 'strategy', target: 'execute' }, classes: 'next-step' }, { data: { source: 'execute', target: 'complete' }, classes: 'next-step' } ] }, 'plan-full': { nodes: [ { data: { id: 'start', label: ht('help.workflows.planFull.start') } }, { data: { id: 'cli-analyze', label: ht('help.workflows.planFull.cliAnalyze') } }, { data: { id: 'plan', label: '/workflow:plan' } }, { data: { id: 'verify', label: '/workflow:plan-verify' } }, { data: { id: 'execute', label: '/workflow:execute' } }, { data: { id: 'test', label: '/workflow:test-gen' } }, { data: { id: 'review', label: '/workflow:review' } }, { data: { id: 'complete', label: '/workflow:session:complete' } } ], edges: [ { data: { source: 'start', target: 'cli-analyze' }, classes: 'next-step' }, { data: { source: 'cli-analyze', target: 'plan' }, classes: 'next-step' }, { data: { source: 'plan', target: 'verify' }, classes: 'next-step' }, { data: { source: 'verify', target: 'execute' }, classes: 'next-step' }, { data: { source: 'execute', target: 'test' }, classes: 'next-step' }, { data: { source: 'test', target: 'review' }, classes: 'next-step' }, { data: { source: 'review', target: 'complete' }, classes: 'next-step' } ] }, 'lite': { nodes: [ { data: { id: 'start', label: ht('help.workflows.lite.start') } }, { data: { id: 'lite-plan', label: '/workflow:lite-plan' } }, { data: { id: 'confirm', label: ht('help.workflows.lite.confirm') } }, { data: { id: 'lite-execute', label: '/workflow:lite-execute' } }, { data: { id: 'complete', label: ht('help.workflows.lite.complete') } } ], edges: [ { data: { source: 'start', target: 'lite-plan' }, classes: 'next-step' }, { data: { source: 'lite-plan', target: 'confirm' }, classes: 'next-step' }, { data: { source: 'confirm', target: 'lite-execute' }, classes: 'next-step' }, { data: { source: 'lite-execute', target: 'complete' }, classes: 'next-step' } ] }, 'tdd': { nodes: [ { data: { id: 'start', label: ht('help.workflows.tdd.start') } }, { data: { id: 'tdd-plan', label: '/workflow:tdd-plan' } }, { data: { id: 'red', label: ht('help.workflows.tdd.red') } }, { data: { id: 'green', label: ht('help.workflows.tdd.green') } }, { data: { id: 'refactor', label: ht('help.workflows.tdd.refactor') } }, { data: { id: 'verify', label: '/workflow:tdd-verify' } }, { data: { id: 'complete', label: ht('help.workflows.tdd.complete') } } ], edges: [ { data: { source: 'start', target: 'tdd-plan' }, classes: 'next-step' }, { data: { source: 'tdd-plan', target: 'red' }, classes: 'next-step' }, { data: { source: 'red', target: 'green' }, classes: 'next-step' }, { data: { source: 'green', target: 'refactor' }, classes: 'next-step' }, { data: { source: 'refactor', target: 'verify' }, classes: 'next-step' }, { data: { source: 'verify', target: 'complete' }, classes: 'next-step' } ] } }; var workflowData = workflows[workflow] || workflows['decision']; console.log('Building workflow diagram for:', workflow); console.log('Generated graph:', workflowData.nodes.length, 'nodes,', workflowData.edges.length, 'edges'); return workflowData.nodes.concat(workflowData.edges); } function showCommandTooltip(commandName, node) { // Find command in helpData var command = helpData.commands.find(function(cmd) { return cmd.command === '/' + commandName; }); if (command) { alert(command.command + '\n\n' + command.description); } } // ========== CodexLens Quick Start ========== function renderCodexLensQuickStart() { var container = document.getElementById('helpTabContent'); if (!container) return; var data = helpData.codexlens; var html = `

${ht('help.codexlens.title')}

${ht('help.codexlens.subtitle')}

${data.sections ? data.sections.map(function(section) { return `

${escapeHtml(section.title)}

${section.items.map(function(item) { return `
${item.name ? `
${escapeHtml(item.name)}
` : ''}

${escapeHtml(item.description)}

${item.command ? `
${escapeHtml(item.command)}
` : ''}
`; }).join('')}
`; }).join('') : ''} ${data.links && data.links.length > 0 ? `

Additional Resources

${data.links.map(function(link) { return ` ${escapeHtml(link.text)} `; }).join('')}
` : ''}
`; container.innerHTML = html; if (typeof lucide !== 'undefined') lucide.createIcons(); }