(data: ExportData, options: ExportOptions)
| 85 | |
| 86 | // Export as HTML |
| 87 | export const exportAsHTML = (data: ExportData, options: ExportOptions): string => { |
| 88 | const formatTimestamp = (timestamp: string) => { |
| 89 | return new Date(timestamp).toLocaleString(); |
| 90 | }; |
| 91 | |
| 92 | const renderSensorHTML = (sensor: SensorData): string => { |
| 93 | const content = formatSensorContent(sensor, options.includeImages); |
| 94 | const timestamp = formatTimestamp(sensor.timestamp); |
| 95 | |
| 96 | let sensorIcon = ''; |
| 97 | switch (sensor.type) { |
| 98 | case 'screenshot': sensorIcon = '📷'; break; |
| 99 | case 'camera': sensorIcon = '🎥'; break; |
| 100 | case 'ocr': sensorIcon = '📄'; break; |
| 101 | case 'audio': sensorIcon = '🎵'; break; |
| 102 | case 'clipboard': sensorIcon = '📋'; break; |
| 103 | case 'memory': sensorIcon = '🧠'; break; |
| 104 | default: sensorIcon = '📊'; |
| 105 | } |
| 106 | |
| 107 | return ` |
| 108 | <div class="sensor-item"> |
| 109 | <div class="sensor-header"> |
| 110 | <span class="sensor-icon">${sensorIcon}</span> |
| 111 | <strong>${sensor.type}</strong> |
| 112 | <span class="timestamp">${timestamp}</span> |
| 113 | </div> |
| 114 | <div class="sensor-content">${content}</div> |
| 115 | </div> |
| 116 | `; |
| 117 | }; |
| 118 | |
| 119 | const renderToolHTML = (tool: ToolCall): string => { |
| 120 | const timestamp = formatTimestamp(tool.timestamp); |
| 121 | const status = tool.status === 'success' ? '✅' : '❌'; |
| 122 | |
| 123 | return ` |
| 124 | <div class="tool-item ${tool.status}"> |
| 125 | <div class="tool-header"> |
| 126 | <span class="tool-status">${status}</span> |
| 127 | <strong>${tool.name}</strong> |
| 128 | <span class="timestamp">${timestamp}</span> |
| 129 | </div> |
| 130 | ${tool.error ? `<div class="tool-error">Error: ${tool.error}</div>` : ''} |
| 131 | ${tool.params ? `<div class="tool-params">Params: ${JSON.stringify(tool.params, null, 2)}</div>` : ''} |
| 132 | </div> |
| 133 | `; |
| 134 | }; |
| 135 | |
| 136 | const renderIterationHTML = (iteration: IterationData): string => { |
| 137 | const startTime = formatTimestamp(iteration.startTime); |
| 138 | const duration = iteration.duration ? `${iteration.duration.toFixed(2)}s` : 'N/A'; |
| 139 | |
| 140 | return ` |
| 141 | <div class="iteration ${iteration.hasError ? 'error' : ''}"> |
| 142 | <div class="iteration-header"> |
| 143 | <h3>Iteration #${iteration.sessionIterationNumber}</h3> |
| 144 | <div class="iteration-meta"> |
no test coverage detected