Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4232,6 +4232,24 @@ ipcMain.handle(IPC.GET_LINE_TIMESTAMP, async (_, lineNumber: number) => {
}
});

// Batch timestamp fetch for Time Align
ipcMain.handle(IPC.GET_LINE_TIMESTAMPS, async (_, lineNumbers: number[]) => {
const handler = getFileHandler();
if (!handler) return [];
const results: Array<{ lineNumber: number; epochMs: number }> = [];
try {
for (const ln of lineNumbers) {
const lines = handler.getLines(ln, 1);
if (lines.length === 0) continue;
const parsed = parseTimestampFast(lines[0].text);
if (parsed) {
results.push({ lineNumber: ln, epochMs: parsed.date.getTime() });
}
}
} catch { /* ignore */ }
return results;
});

ipcMain.handle('detect-time-gaps', async (_, options: TimeGapOptions) => {
const handler = getFileHandler();
if (!handler || !currentFilePath) {
Expand Down
5 changes: 5 additions & 0 deletions src/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ const IPC = {
CONTEXT_SEARCH_PROGRESS: 'context-search-progress',
// Traceback
TRACEBACK: 'traceback',
// Time Align
GET_LINE_TIMESTAMPS: 'get-line-timestamps',
// Tabbed terminal
TERMINAL_CREATE_LOCAL: 'terminal-create-local',
TERMINAL_CREATE_SSH: 'terminal-create-ssh',
Expand Down Expand Up @@ -432,6 +434,9 @@ const api = {
getLineTimestamp: (lineNumber: number): Promise<{ epochMs: number | null; timestampStr: string | null }> =>
ipcRenderer.invoke(IPC.GET_LINE_TIMESTAMP, lineNumber),

getLineTimestamps: (lineNumbers: number[]): Promise<Array<{ lineNumber: number; epochMs: number }>> =>
ipcRenderer.invoke(IPC.GET_LINE_TIMESTAMPS, lineNumbers),

// MCP navigation
onNavigateToLine: (callback: (lineNumber: number) => void): (() => void) => {
const handler = (_: any, lineNumber: number) => callback(lineNumber);
Expand Down
14 changes: 14 additions & 0 deletions src/renderer/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ <h2>LOGAN</h2>
<button class="bottom-tab-btn" data-bottom-tab="video" data-help="Sync a video recording with log timestamps.&#10;Set a sync point to correlate video playback with log lines.">Video</button>
<button class="bottom-tab-btn" data-bottom-tab="image" data-help="View images referenced in log files.&#10;Drag and drop or open image files for side-by-side analysis.">Image</button>
<button class="bottom-tab-btn" data-bottom-tab="live" data-help="Connect to live log sources: Serial ports, ADB logcat, or SSH.&#10;Up to 4 parallel connections with real-time streaming.">Live</button>
<button class="bottom-tab-btn" data-bottom-tab="time-align" data-help="Visually align search config results by timestamp.&#10;Each enabled config becomes a draggable timeline lane.&#10;Drag lanes left/right to apply time offsets and correlate events.">Time Align</button>
<button class="bottom-tab-btn" data-bottom-tab="traceback" data-help="Reverse timeline from any error line.&#10;Right-click a line → Traceback from here.&#10;Shows what led to the error: same component, warnings, escalations.">Traceback</button>
<button class="bottom-tab-btn" data-bottom-tab="chat" data-help="Chat with an AI agent connected via MCP or HTTP API.&#10;The agent can search, navigate, analyze, and bookmark for you.">Agent Chat</button>
<button class="bottom-tab-btn" data-bottom-tab="notes" data-help="Freeform notes saved per file as .logan/filename.notes.txt.&#10;Use Save Snippet to append selected log lines to notes.">Notes</button>
Expand Down Expand Up @@ -525,6 +526,19 @@ <h2>LOGAN</h2>
</div>
</div>
</div>
<!-- Time Align tab -->
<div class="bottom-tab-view" data-bottom-tab="time-align">
<div class="ta-panel-body">
<div class="ta-toolbar">
<button id="ta-refresh-btn" class="ctx-toolbar-btn" title="Refresh timestamps">Refresh</button>
<button id="ta-reset-btn" class="ctx-toolbar-btn" title="Reset all offsets">Reset Offsets</button>
<span id="ta-summary" class="ctx-results-summary"></span>
</div>
<div id="ta-axis" class="ta-axis"></div>
<div id="ta-lanes" class="ta-lanes"></div>
<p id="ta-placeholder" class="placeholder">Run Search Configs first, then open this tab to align timelines</p>
</div>
</div>
<!-- Traceback tab -->
<div class="bottom-tab-view" data-bottom-tab="traceback">
<div class="traceback-panel-body">
Expand Down
Loading