diff --git a/loop/webui/src/timeline/charts.ts b/loop/webui/src/timeline/charts.ts
new file mode 100644
index 0000000..0ed56e8
--- /dev/null
+++ b/loop/webui/src/timeline/charts.ts
@@ -0,0 +1,468 @@
+import type { TimelineMessage } from "./types";
+import vegaEmbed from "vega-embed";
+import { TopLevelSpec } from "vega-lite";
+
+/**
+ * ChartManager handles all chart-related functionality for the timeline.
+ * This includes rendering charts, calculating data, and managing chart state.
+ */
+export class ChartManager {
+  private chartData: { timestamp: Date; cost: number }[] = [];
+
+  /**
+   * Create a new ChartManager instance
+   */
+  constructor() {
+    this.chartData = [];
+  }
+
+  /**
+   * Calculate cumulative cost data from messages
+   */
+  public calculateCumulativeCostData(
+    messages: TimelineMessage[],
+  ): { timestamp: Date; cost: number }[] {
+    if (!messages || messages.length === 0) {
+      return [];
+    }
+
+    let cumulativeCost = 0;
+    const data: { timestamp: Date; cost: number }[] = [];
+
+    for (const message of messages) {
+      if (message.timestamp && message.usage && message.usage.cost_usd) {
+        const timestamp = new Date(message.timestamp);
+        cumulativeCost += message.usage.cost_usd;
+
+        data.push({
+          timestamp,
+          cost: cumulativeCost,
+        });
+      }
+    }
+
+    return data;
+  }
+
+  /**
+   * Get the current chart data
+   */
+  public getChartData(): { timestamp: Date; cost: number }[] {
+    return this.chartData;
+  }
+
+  /**
+   * Set chart data
+   */
+  public setChartData(data: { timestamp: Date; cost: number }[]): void {
+    this.chartData = data;
+  }
+
+  /**
+   * Fetch all messages to generate chart data
+   */
+  public async fetchAllMessages(): Promise<void> {
+    try {
+      // Fetch all messages in a single request
+      const response = await fetch("messages");
+      if (!response.ok) {
+        throw new Error(`Failed to fetch messages: ${response.status}`);
+      }
+
+      const allMessages = await response.json();
+      if (Array.isArray(allMessages)) {
+        // Sort messages chronologically
+        allMessages.sort((a, b) => {
+          const dateA = a.timestamp ? new Date(a.timestamp).getTime() : 0;
+          const dateB = b.timestamp ? new Date(b.timestamp).getTime() : 0;
+          return dateA - dateB;
+        });
+
+        // Calculate cumulative cost data
+        this.chartData = this.calculateCumulativeCostData(allMessages);
+      }
+    } catch (error) {
+      console.error("Error fetching messages for chart:", error);
+      this.chartData = [];
+    }
+  }
+
+  /**
+   * Render all charts in the chart view
+   */
+  public async renderCharts(): Promise<void> {
+    const chartContainer = document.getElementById("chartContainer");
+    if (!chartContainer) return;
+
+    try {
+      // Show loading state
+      chartContainer.innerHTML = "<div class='loader'></div>";
+
+      // Fetch messages if necessary
+      if (this.chartData.length === 0) {
+        await this.fetchAllMessages();
+      }
+
+      // Clear the container for multiple charts
+      chartContainer.innerHTML = "";
+
+      // Create cost chart container
+      const costChartDiv = document.createElement("div");
+      costChartDiv.className = "chart-section";
+      costChartDiv.innerHTML =
+        "<h3>Dollar Usage Over Time</h3><div id='costChart'></div>";
+      chartContainer.appendChild(costChartDiv);
+
+      // Create messages chart container
+      const messagesChartDiv = document.createElement("div");
+      messagesChartDiv.className = "chart-section";
+      messagesChartDiv.innerHTML =
+        "<h3>Message Timeline</h3><div id='messagesChart'></div>";
+      chartContainer.appendChild(messagesChartDiv);
+
+      // Render both charts
+      await this.renderDollarUsageChart();
+      await this.renderMessagesChart();
+    } catch (error) {
+      console.error("Error rendering charts:", error);
+      chartContainer.innerHTML = `<p>Error rendering charts: ${error instanceof Error ? error.message : "Unknown error"}</p>`;
+    }
+  }
+
+  /**
+   * Render the dollar usage chart using Vega-Lite
+   */
+  private async renderDollarUsageChart(): Promise<void> {
+    const costChartContainer = document.getElementById("costChart");
+    if (!costChartContainer) return;
+
+    try {
+      // Display cost chart using Vega-Lite
+      if (this.chartData.length === 0) {
+        costChartContainer.innerHTML =
+          "<p>No cost data available to display.</p>";
+        return;
+      }
+
+      // Create a Vega-Lite spec for the line chart
+      // eslint-disable-next-line @typescript-eslint/no-explicit-any
+      const costSpec: any = {
+        $schema: "https://vega.github.io/schema/vega-lite/v5.json",
+        description: "Cumulative cost over time",
+        width: "container",
+        height: 300,
+        data: {
+          values: this.chartData.map((d) => ({
+            timestamp: d.timestamp.toISOString(),
+            cost: d.cost,
+          })),
+        },
+        mark: {
+          type: "line",
+          point: true,
+        },
+        encoding: {
+          x: {
+            field: "timestamp",
+            type: "temporal",
+            title: "Time",
+            axis: {
+              format: "%H:%M:%S",
+              title: "Time",
+              labelAngle: -45,
+            },
+          },
+          y: {
+            field: "cost",
+            type: "quantitative",
+            title: "Cumulative Cost (USD)",
+            axis: {
+              format: "$,.4f",
+            },
+          },
+          tooltip: [
+            {
+              field: "timestamp",
+              type: "temporal",
+              title: "Time",
+              format: "%Y-%m-%d %H:%M:%S",
+            },
+            {
+              field: "cost",
+              type: "quantitative",
+              title: "Cumulative Cost",
+              format: "$,.4f",
+            },
+          ],
+        },
+      };
+
+      // Render the cost chart
+      await vegaEmbed(costChartContainer, costSpec, {
+        actions: true,
+        renderer: "svg",
+      });
+    } catch (error) {
+      console.error("Error rendering dollar usage chart:", error);
+      costChartContainer.innerHTML = `<p>Error rendering dollar usage chart: ${error instanceof Error ? error.message : "Unknown error"}</p>`;
+    }
+  }
+
+  /**
+   * Render the messages timeline chart using Vega-Lite
+   */
+  private async renderMessagesChart(): Promise<void> {
+    const messagesChartContainer = document.getElementById("messagesChart");
+    if (!messagesChartContainer) return;
+
+    try {
+      // Get all messages
+      const response = await fetch("messages");
+      if (!response.ok) {
+        throw new Error(`Failed to fetch messages: ${response.status}`);
+      }
+
+      const allMessages = await response.json();
+      if (!Array.isArray(allMessages) || allMessages.length === 0) {
+        messagesChartContainer.innerHTML =
+          "<p>No messages available to display.</p>";
+        return;
+      }
+
+      // Sort messages chronologically
+      allMessages.sort((a, b) => {
+        const dateA = a.timestamp ? new Date(a.timestamp).getTime() : 0;
+        const dateB = b.timestamp ? new Date(b.timestamp).getTime() : 0;
+        return dateA - dateB;
+      });
+
+      // Create unique indexes for all messages
+      const messageIndexMap = new Map<string, number>();
+      allMessages.forEach((msg, index) => {
+        // Create a unique ID for each message to track its position
+        const msgId = msg.timestamp ? msg.timestamp.toString() : `msg-${index}`;
+        messageIndexMap.set(msgId, index);
+      });
+
+      // Prepare data for messages with start_time and end_time (bar marks)
+      const barData = allMessages
+        .filter((msg) => msg.start_time && msg.end_time) // Only include messages with explicit start and end times
+        .map((msg) => {
+          // Parse start and end times
+          const startTime = new Date(msg.start_time!);
+          const endTime = new Date(msg.end_time!);
+
+          // Get the index for this message
+          const msgId = msg.timestamp ? msg.timestamp.toString() : "";
+          const index = messageIndexMap.get(msgId) || 0;
+
+          // Truncate content for tooltip readability
+          const displayContent = msg.content
+            ? msg.content.length > 100
+              ? msg.content.substring(0, 100) + "..."
+              : msg.content
+            : "No content";
+
+          // Prepare tool input and output for tooltip if applicable
+          const toolInput = msg.input
+            ? msg.input.length > 100
+              ? msg.input.substring(0, 100) + "..."
+              : msg.input
+            : "";
+
+          const toolResult = msg.tool_result
+            ? msg.tool_result.length > 100
+              ? msg.tool_result.substring(0, 100) + "..."
+              : msg.tool_result
+            : "";
+
+          return {
+            index: index,
+            message_type: msg.type,
+            content: displayContent,
+            tool_name: msg.tool_name || "",
+            tool_input: toolInput,
+            tool_result: toolResult,
+            start_time: startTime.toISOString(),
+            end_time: endTime.toISOString(),
+            message: JSON.stringify(msg, null, 2), // Full message for detailed inspection
+          };
+        });
+
+      // Prepare data for messages with timestamps only (point marks)
+      const pointData = allMessages
+        .filter((msg) => msg.timestamp && !(msg.start_time && msg.end_time)) // Only messages with timestamp but without start/end times
+        .map((msg) => {
+          // Get the timestamp
+          const timestamp = new Date(msg.timestamp!);
+
+          // Get the index for this message
+          const msgId = msg.timestamp ? msg.timestamp.toString() : "";
+          const index = messageIndexMap.get(msgId) || 0;
+
+          // Truncate content for tooltip readability
+          const displayContent = msg.content
+            ? msg.content.length > 100
+              ? msg.content.substring(0, 100) + "..."
+              : msg.content
+            : "No content";
+
+          // Prepare tool input and output for tooltip if applicable
+          const toolInput = msg.input
+            ? msg.input.length > 100
+              ? msg.input.substring(0, 100) + "..."
+              : msg.input
+            : "";
+
+          const toolResult = msg.tool_result
+            ? msg.tool_result.length > 100
+              ? msg.tool_result.substring(0, 100) + "..."
+              : msg.tool_result
+            : "";
+
+          return {
+            index: index,
+            message_type: msg.type,
+            content: displayContent,
+            tool_name: msg.tool_name || "",
+            tool_input: toolInput,
+            tool_result: toolResult,
+            time: timestamp.toISOString(),
+            message: JSON.stringify(msg, null, 2), // Full message for detailed inspection
+          };
+        });
+
+      // Check if we have any data to display
+      if (barData.length === 0 && pointData.length === 0) {
+        messagesChartContainer.innerHTML =
+          "<p>No message timing data available to display.</p>";
+        return;
+      }
+
+      // Calculate height based on number of unique messages
+      const chartHeight = 20 * Math.min(allMessages.length, 25); // Max 25 visible at once
+
+      // Create a layered Vega-Lite spec combining bars and points
+      const messagesSpec: TopLevelSpec = {
+        $schema: "https://vega.github.io/schema/vega-lite/v5.json",
+        description: "Message Timeline",
+        width: "container",
+        height: chartHeight,
+        layer: [],
+      };
+
+      // Add bar layer if we have bar data
+      if (barData.length > 0) {
+        messagesSpec.layer.push({
+          data: { values: barData },
+          mark: {
+            type: "bar",
+            height: 16,
+          },
+          encoding: {
+            x: {
+              field: "start_time",
+              type: "temporal",
+              title: "Time",
+              axis: {
+                format: "%H:%M:%S",
+                title: "Time",
+                labelAngle: -45,
+              },
+            },
+            x2: { field: "end_time" },
+            y: {
+              field: "index",
+              type: "ordinal",
+              title: "Message Index",
+              axis: {
+                grid: true,
+              },
+            },
+            color: {
+              field: "message_type",
+              type: "nominal",
+              title: "Message Type",
+              legend: {},
+            },
+            tooltip: [
+              { field: "message_type", type: "nominal", title: "Type" },
+              { field: "tool_name", type: "nominal", title: "Tool" },
+              {
+                field: "start_time",
+                type: "temporal",
+                title: "Start Time",
+                format: "%H:%M:%S.%L",
+              },
+              {
+                field: "end_time",
+                type: "temporal",
+                title: "End Time",
+                format: "%H:%M:%S.%L",
+              },
+              { field: "content", type: "nominal", title: "Content" },
+              { field: "tool_input", type: "nominal", title: "Tool Input" },
+              { field: "tool_result", type: "nominal", title: "Tool Result" },
+            ],
+          },
+        });
+      }
+
+      // Add point layer if we have point data
+      if (pointData.length > 0) {
+        messagesSpec.layer.push({
+          data: { values: pointData },
+          mark: {
+            type: "point",
+            size: 100,
+            filled: true,
+          },
+          encoding: {
+            x: {
+              field: "time",
+              type: "temporal",
+              title: "Time",
+              axis: {
+                format: "%H:%M:%S",
+                title: "Time",
+                labelAngle: -45,
+              },
+            },
+            y: {
+              field: "index",
+              type: "ordinal",
+              title: "Message Index",
+            },
+            color: {
+              field: "message_type",
+              type: "nominal",
+              title: "Message Type",
+            },
+            tooltip: [
+              { field: "message_type", type: "nominal", title: "Type" },
+              { field: "tool_name", type: "nominal", title: "Tool" },
+              {
+                field: "time",
+                type: "temporal",
+                title: "Timestamp",
+                format: "%H:%M:%S.%L",
+              },
+              { field: "content", type: "nominal", title: "Content" },
+              { field: "tool_input", type: "nominal", title: "Tool Input" },
+              { field: "tool_result", type: "nominal", title: "Tool Result" },
+            ],
+          },
+        });
+      }
+
+      // Render the messages timeline chart
+      await vegaEmbed(messagesChartContainer, messagesSpec, {
+        actions: true,
+        renderer: "svg",
+      });
+    } catch (error) {
+      console.error("Error rendering messages chart:", error);
+      messagesChartContainer.innerHTML = `<p>Error rendering messages chart: ${error instanceof Error ? error.message : "Unknown error"}</p>`;
+    }
+  }
+}
diff --git a/loop/webui/src/timeline/commits.ts b/loop/webui/src/timeline/commits.ts
new file mode 100644
index 0000000..f4303f2
--- /dev/null
+++ b/loop/webui/src/timeline/commits.ts
@@ -0,0 +1,90 @@
+/**
+ * Utility functions for rendering commit messages in the timeline
+ */
+
+import { escapeHTML } from "./utils";
+
+interface Commit {
+  hash: string;
+  subject: string;
+  body: string;
+  pushed_branch?: string;
+}
+
+/**
+ * Create HTML elements to display commits in the timeline
+ * @param commits List of commit information to display
+ * @param diffViewerCallback Callback function to show commit diff when requested
+ * @returns The created HTML container element with commit information
+ */
+export function createCommitsContainer(
+  commits: Commit[],
+  diffViewerCallback: (commitHash: string) => void
+): HTMLElement {
+  const commitsContainer = document.createElement("div");
+  commitsContainer.className = "commits-container";
+
+  // Create a header for commits
+  const commitsHeaderRow = document.createElement("div");
+  commitsHeaderRow.className = "commits-header";
+  commitsHeaderRow.textContent = `${commits.length} new commit${commits.length > 1 ? "s" : ""} detected`;
+  commitsContainer.appendChild(commitsHeaderRow);
+
+  // Create a row for commit boxes
+  const commitBoxesRow = document.createElement("div");
+  commitBoxesRow.className = "commit-boxes-row";
+
+  // Add each commit as a box
+  commits.forEach((commit) => {
+    // Create the commit box
+    const commitBox = document.createElement("div");
+    commitBox.className = "commit-box";
+
+    // Show commit hash and subject line as the preview
+    const commitPreview = document.createElement("div");
+    commitPreview.className = "commit-preview";
+
+    // Include pushed branch information if available
+    let previewHTML = `<span class="commit-hash">${commit.hash.substring(0, 8)}</span> ${escapeHTML(commit.subject)}`;
+    if (commit.pushed_branch) {
+      previewHTML += ` <span class="pushed-branch">→ pushed to ${escapeHTML(commit.pushed_branch)}</span>`;
+    }
+
+    commitPreview.innerHTML = previewHTML;
+    commitBox.appendChild(commitPreview);
+
+    // Create expandable view for commit details
+    const expandedView = document.createElement("div");
+    expandedView.className = "commit-details is-hidden";
+    expandedView.innerHTML = `<pre>${escapeHTML(commit.body)}</pre>`;
+    commitBox.appendChild(expandedView);
+
+    // Toggle visibility of expanded view when clicking the preview
+    commitPreview.addEventListener("click", (event) => {
+      // If holding Ctrl/Cmd key, show diff for this commit
+      if (event.ctrlKey || event.metaKey) {
+        // Call the diff viewer callback with the commit hash
+        diffViewerCallback(commit.hash);
+      } else {
+        // Normal behavior - toggle expanded view
+        expandedView.classList.toggle("is-hidden");
+      }
+    });
+    
+    // Add a diff button to view commit changes
+    const diffButton = document.createElement("button");
+    diffButton.className = "commit-diff-button";
+    diffButton.textContent = "View Changes";
+    diffButton.addEventListener("click", (event) => {
+      event.stopPropagation(); // Prevent triggering the parent click event
+      diffViewerCallback(commit.hash);
+    });
+    // Add the button directly to the commit box
+    commitBox.appendChild(diffButton);
+
+    commitBoxesRow.appendChild(commitBox);
+  });
+
+  commitsContainer.appendChild(commitBoxesRow);
+  return commitsContainer;
+}
diff --git a/loop/webui/src/timeline/components/collapsible.ts b/loop/webui/src/timeline/components/collapsible.ts
new file mode 100644
index 0000000..12f90ec
--- /dev/null
+++ b/loop/webui/src/timeline/components/collapsible.ts
@@ -0,0 +1,37 @@
+import { TimelineMessage } from "../types";
+
+/**
+ * Adds collapsible functionality to long content elements.
+ * This creates a toggle button that allows users to expand/collapse long text content.
+ *
+ * @param message - The timeline message containing the content
+ * @param textEl - The DOM element containing the text content
+ * @param containerEl - The container element for the text and copy button
+ * @param contentEl - The outer content element that will contain everything
+ */
+export function addCollapsibleFunctionality(
+  message: TimelineMessage,
+  textEl: HTMLElement,
+  containerEl: HTMLElement,
+  contentEl: HTMLElement
+): void {
+  // Don't collapse end_of_turn messages (final output) regardless of length
+  if (message.content.length > 1000 && !message.end_of_turn) {
+    textEl.classList.add("collapsed");
+
+    const toggleButton = document.createElement("button");
+    toggleButton.className = "collapsible";
+    toggleButton.textContent = "Show more...";
+    toggleButton.addEventListener("click", () => {
+      textEl.classList.toggle("collapsed");
+      toggleButton.textContent = textEl.classList.contains("collapsed")
+        ? "Show more..."
+        : "Show less";
+    });
+
+    contentEl.appendChild(containerEl);
+    contentEl.appendChild(toggleButton);
+  } else {
+    contentEl.appendChild(containerEl);
+  }
+}
diff --git a/loop/webui/src/timeline/copybutton.ts b/loop/webui/src/timeline/copybutton.ts
new file mode 100644
index 0000000..d9b994b
--- /dev/null
+++ b/loop/webui/src/timeline/copybutton.ts
@@ -0,0 +1,44 @@
+/**
+ * Creates a copy button container with a functioning copy button
+ */
+export function createCopyButton(textToCopy: string): {
+  container: HTMLDivElement;
+  button: HTMLButtonElement;
+} {
+  // Create container for the copy button
+  const copyButtonContainer = document.createElement("div");
+  copyButtonContainer.className = "message-actions";
+
+  // Create the copy button itself
+  const copyButton = document.createElement("button");
+  copyButton.className = "copy-button";
+  copyButton.textContent = "Copy";
+  copyButton.title = "Copy text to clipboard";
+  
+  // Add click event listener to handle copying
+  copyButton.addEventListener("click", (e) => {
+    e.stopPropagation();
+    navigator.clipboard
+      .writeText(textToCopy)
+      .then(() => {
+        copyButton.textContent = "Copied!";
+        setTimeout(() => {
+          copyButton.textContent = "Copy";
+        }, 2000);
+      })
+      .catch((err) => {
+        console.error("Failed to copy text: ", err);
+        copyButton.textContent = "Failed";
+        setTimeout(() => {
+          copyButton.textContent = "Copy";
+        }, 2000);
+      });
+  });
+
+  copyButtonContainer.appendChild(copyButton);
+  
+  return {
+    container: copyButtonContainer,
+    button: copyButton
+  };
+}
diff --git a/loop/webui/src/timeline/data.ts b/loop/webui/src/timeline/data.ts
new file mode 100644
index 0000000..2130c21
--- /dev/null
+++ b/loop/webui/src/timeline/data.ts
@@ -0,0 +1,379 @@
+import { TimelineMessage } from "./types";
+import { formatNumber } from "./utils";
+
+/**
+ * Event types for data manager
+ */
+export type DataManagerEventType = 'dataChanged' | 'connectionStatusChanged';
+
+/**
+ * Connection status types
+ */
+export type ConnectionStatus = 'connected' | 'disconnected' | 'disabled';
+
+/**
+ * State interface
+ */
+export interface TimelineState {
+  hostname?: string;
+  working_dir?: string;
+  initial_commit?: string;
+  message_count?: number;
+  title?: string;
+  total_usage?: {
+    input_tokens: number;
+    output_tokens: number;
+    cache_read_input_tokens: number;
+    cache_creation_input_tokens: number;
+    total_cost_usd: number;
+  };
+}
+
+/**
+ * DataManager - Class to manage timeline data, fetching, and polling
+ */
+export class DataManager {
+  // State variables
+  private lastMessageCount: number = 0;
+  private nextFetchIndex: number = 0;
+  private currentFetchStartIndex: number = 0;
+  private currentPollController: AbortController | null = null;
+  private isFetchingMessages: boolean = false;
+  private isPollingEnabled: boolean = true;
+  private isFirstLoad: boolean = true;
+  private connectionStatus: ConnectionStatus = "disabled";
+  private messages: TimelineMessage[] = [];
+  private timelineState: TimelineState | null = null;
+  
+  // Event listeners
+  private eventListeners: Map<DataManagerEventType, Array<(...args: any[]) => void>> = new Map();
+
+  constructor() {
+    // Initialize empty arrays for each event type
+    this.eventListeners.set('dataChanged', []);
+    this.eventListeners.set('connectionStatusChanged', []);
+  }
+
+  /**
+   * Initialize the data manager and fetch initial data
+   */
+  public async initialize(): Promise<void> {
+    try {
+      // Initial data fetch
+      await this.fetchData();
+      // Start polling for updates only if initial fetch succeeds
+      this.startPolling();
+    } catch (error) {
+      console.error("Initial data fetch failed, will retry via polling", error);
+      // Still start polling to recover
+      this.startPolling();
+    }
+  }
+
+  /**
+   * Get all messages
+   */
+  public getMessages(): TimelineMessage[] {
+    return this.messages;
+  }
+
+  /**
+   * Get the current state
+   */
+  public getState(): TimelineState | null {
+    return this.timelineState;
+  }
+
+  /**
+   * Get the connection status
+   */
+  public getConnectionStatus(): ConnectionStatus {
+    return this.connectionStatus;
+  }
+
+  /**
+   * Get the isFirstLoad flag
+   */
+  public getIsFirstLoad(): boolean {
+    return this.isFirstLoad;
+  }
+
+  /**
+   * Get the currentFetchStartIndex
+   */
+  public getCurrentFetchStartIndex(): number {
+    return this.currentFetchStartIndex;
+  }
+
+  /**
+   * Add an event listener
+   */
+  public addEventListener(event: DataManagerEventType, callback: (...args: any[]) => void): void {
+    const listeners = this.eventListeners.get(event) || [];
+    listeners.push(callback);
+    this.eventListeners.set(event, listeners);
+  }
+
+  /**
+   * Remove an event listener
+   */
+  public removeEventListener(event: DataManagerEventType, callback: (...args: any[]) => void): void {
+    const listeners = this.eventListeners.get(event) || [];
+    const index = listeners.indexOf(callback);
+    if (index !== -1) {
+      listeners.splice(index, 1);
+      this.eventListeners.set(event, listeners);
+    }
+  }
+
+  /**
+   * Emit an event
+   */
+  private emitEvent(event: DataManagerEventType, ...args: any[]): void {
+    const listeners = this.eventListeners.get(event) || [];
+    listeners.forEach(callback => callback(...args));
+  }
+
+  /**
+   * Set polling enabled/disabled state
+   */
+  public setPollingEnabled(enabled: boolean): void {
+    this.isPollingEnabled = enabled;
+    
+    if (enabled) {
+      this.startPolling();
+    } else {
+      this.stopPolling();
+    }
+  }
+
+  /**
+   * Start polling for updates
+   */
+  public startPolling(): void {
+    this.stopPolling(); // Stop any existing polling
+    
+    // Start long polling
+    this.longPoll();
+  }
+
+  /**
+   * Stop polling for updates
+   */
+  public stopPolling(): void {
+    // Abort any ongoing long poll request
+    if (this.currentPollController) {
+      this.currentPollController.abort();
+      this.currentPollController = null;
+    }
+    
+    // If polling is disabled by user, set connection status to disabled
+    if (!this.isPollingEnabled) {
+      this.updateConnectionStatus("disabled");
+    }
+  }
+
+  /**
+   * Update the connection status
+   */
+  private updateConnectionStatus(status: ConnectionStatus): void {
+    if (this.connectionStatus !== status) {
+      this.connectionStatus = status;
+      this.emitEvent('connectionStatusChanged', status);
+    }
+  }
+
+  /**
+   * Long poll for updates
+   */
+  private async longPoll(): Promise<void> {
+    // Abort any existing poll request
+    if (this.currentPollController) {
+      this.currentPollController.abort();
+      this.currentPollController = null;
+    }
+
+    // If polling is disabled, don't start a new poll
+    if (!this.isPollingEnabled) {
+      return;
+    }
+
+    let timeoutId: number | undefined;
+
+    try {
+      // Create a new abort controller for this request
+      this.currentPollController = new AbortController();
+      const signal = this.currentPollController.signal;
+
+      // Get the URL with the current message count
+      const pollUrl = `state?poll=true&seen=${this.lastMessageCount}`;
+
+      // Make the long poll request
+      // Use explicit timeout to handle stalled connections (120s)
+      const controller = new AbortController();
+      timeoutId = window.setTimeout(() => controller.abort(), 120000);
+
+      interface CustomFetchOptions extends RequestInit {
+        [Symbol.toStringTag]?: unknown;
+      }
+
+      const fetchOptions: CustomFetchOptions = {
+        signal: controller.signal,
+        // Use the original signal to allow manual cancellation too
+        get [Symbol.toStringTag]() {
+          if (signal.aborted) controller.abort();
+          return "";
+        },
+      };
+
+      try {
+        const response = await fetch(pollUrl, fetchOptions);
+        // Clear the timeout since we got a response
+        clearTimeout(timeoutId);
+
+        // Parse the JSON response
+        const _data = await response.json();
+
+        // If we got here, data has changed, so fetch the latest data
+        await this.fetchData();
+
+        // Start a new long poll (if polling is still enabled)
+        if (this.isPollingEnabled) {
+          this.longPoll();
+        }
+      } catch (error) {
+        // Handle fetch errors inside the inner try block
+        clearTimeout(timeoutId);
+        throw error; // Re-throw to be caught by the outer catch block
+      }
+    } catch (error: unknown) {
+      // Clean up timeout if we're handling an error
+      if (timeoutId) clearTimeout(timeoutId);
+
+      // Don't log or treat manual cancellations as errors
+      const isErrorWithName = (
+        err: unknown,
+      ): err is { name: string; message?: string } =>
+        typeof err === "object" && err !== null && "name" in err;
+
+      if (
+        isErrorWithName(error) &&
+        error.name === "AbortError" &&
+        this.currentPollController?.signal.aborted
+      ) {
+        console.log("Polling cancelled by user");
+        return;
+      }
+
+      // Handle different types of errors with specific messages
+      let errorMessage = "Not connected";
+
+      if (isErrorWithName(error)) {
+        if (error.name === "AbortError") {
+          // This was our timeout abort
+          errorMessage = "Connection timeout - not connected";
+          console.error("Long polling timeout");
+        } else if (error.name === "SyntaxError") {
+          // JSON parsing error
+          errorMessage = "Invalid response from server - not connected";
+          console.error("JSON parsing error:", error);
+        } else if (
+          error.name === "TypeError" &&
+          error.message?.includes("NetworkError")
+        ) {
+          // Network connectivity issues
+          errorMessage = "Network connection lost - not connected";
+          console.error("Network error during polling:", error);
+        } else {
+          // Generic error
+          console.error("Long polling error:", error);
+        }
+      }
+
+      // Disable polling on error
+      this.isPollingEnabled = false;
+
+      // Update connection status to disconnected
+      this.updateConnectionStatus("disconnected");
+
+      // Emit an event that we're disconnected with the error message
+      this.emitEvent('connectionStatusChanged', this.connectionStatus, errorMessage);
+    }
+  }
+
+  /**
+   * Fetch timeline data
+   */
+  public async fetchData(): Promise<void> {    
+    // If we're already fetching messages, don't start another fetch
+    if (this.isFetchingMessages) {
+      console.log("Already fetching messages, skipping request");
+      return;
+    }
+
+    this.isFetchingMessages = true;
+
+    try {
+      // Fetch state first
+      const stateResponse = await fetch("state");
+      const state = await stateResponse.json();
+      this.timelineState = state;
+
+      // Check if new messages are available
+      if (
+        state.message_count === this.lastMessageCount &&
+        this.lastMessageCount > 0
+      ) {
+        // No new messages, early return
+        this.isFetchingMessages = false;
+        this.emitEvent('dataChanged', { state, newMessages: [] });
+        return;
+      }
+
+      // Fetch messages with a start parameter
+      this.currentFetchStartIndex = this.nextFetchIndex;
+      const messagesResponse = await fetch(
+        `messages?start=${this.nextFetchIndex}`,
+      );
+      const newMessages = await messagesResponse.json() || [];
+
+      // Store messages in our array
+      if (this.nextFetchIndex === 0) {
+        // If this is the first fetch, replace the entire array
+        this.messages = [...newMessages];
+      } else {
+        // Otherwise append the new messages
+        this.messages = [...this.messages, ...newMessages];
+      }
+
+      // Update connection status to connected
+      this.updateConnectionStatus("connected");
+
+      // Update the last message index for next fetch
+      if (newMessages && newMessages.length > 0) {
+        this.nextFetchIndex += newMessages.length;
+      }
+
+      // Update the message count
+      this.lastMessageCount = state?.message_count ?? 0;
+
+      // Mark that we've completed first load
+      if (this.isFirstLoad) {
+        this.isFirstLoad = false;
+      }
+
+      // Emit an event that data has changed
+      this.emitEvent('dataChanged', { state, newMessages, isFirstFetch: this.nextFetchIndex === newMessages.length });
+    } catch (error) {
+      console.error("Error fetching data:", error);
+
+      // Update connection status to disconnected
+      this.updateConnectionStatus("disconnected");
+
+      // Emit an event that we're disconnected
+      this.emitEvent('connectionStatusChanged', this.connectionStatus, "Not connected");
+    } finally {
+      this.isFetchingMessages = false;
+    }
+  }
+}
diff --git a/loop/webui/src/timeline/diffviewer.ts b/loop/webui/src/timeline/diffviewer.ts
new file mode 100644
index 0000000..1460dc3
--- /dev/null
+++ b/loop/webui/src/timeline/diffviewer.ts
@@ -0,0 +1,384 @@
+import * as Diff2Html from "diff2html";
+
+/**
+ * Class to handle diff and commit viewing functionality in the timeline UI.
+ */
+export class DiffViewer {
+  // Current commit hash being viewed
+  private currentCommitHash: string = "";
+  // Selected line in the diff for commenting
+  private selectedDiffLine: string | null = null;
+  // Current view mode (needed for integration with TimelineManager)
+  private viewMode: string = "chat";
+
+  /**
+   * Constructor for DiffViewer
+   */
+  constructor() {}
+
+  /**
+   * Sets the current view mode
+   * @param mode The current view mode
+   */
+  public setViewMode(mode: string): void {
+    this.viewMode = mode;
+  }
+
+  /**
+   * Gets the current commit hash
+   * @returns The current commit hash
+   */
+  public getCurrentCommitHash(): string {
+    return this.currentCommitHash;
+  }
+
+  /**
+   * Sets the current commit hash
+   * @param hash The commit hash to set
+   */
+  public setCurrentCommitHash(hash: string): void {
+    this.currentCommitHash = hash;
+  }
+
+  /**
+   * Clears the current commit hash
+   */
+  public clearCurrentCommitHash(): void {
+    this.currentCommitHash = "";
+  }
+
+  /**
+   * Loads diff content and renders it using diff2html
+   * @param commitHash Optional commit hash to load diff for
+   */
+  public async loadDiff2HtmlContent(commitHash?: string): Promise<void> {
+    const diff2htmlContent = document.getElementById("diff2htmlContent");
+    const container = document.querySelector(".timeline-container");
+    if (!diff2htmlContent || !container) return;
+
+    try {
+      // Show loading state
+      diff2htmlContent.innerHTML = "Loading enhanced diff...";
+
+      // Add classes to container to allow full-width rendering
+      container.classList.add("diff2-active");
+      container.classList.add("diff-active");
+      
+      // Use currentCommitHash if provided or passed from parameter
+      const hash = commitHash || this.currentCommitHash;
+      
+      // Build the diff URL - include commit hash if specified
+      const diffUrl = hash ? `diff?commit=${hash}` : "diff";
+      
+      // Fetch the diff from the server
+      const response = await fetch(diffUrl);
+
+      if (!response.ok) {
+        throw new Error(
+          `Server returned ${response.status}: ${response.statusText}`,
+        );
+      }
+
+      const diffText = await response.text();
+
+      if (!diffText || diffText.trim() === "") {
+        diff2htmlContent.innerHTML =
+          "<span style='color: #666; font-style: italic;'>No changes detected since conversation started.</span>";
+        return;
+      }
+
+      // Get the selected view format
+      const formatRadios = document.getElementsByName("diffViewFormat") as NodeListOf<HTMLInputElement>;
+      let outputFormat = "side-by-side"; // default
+      
+      // Convert NodeListOf to Array to ensure [Symbol.iterator]() is available
+      Array.from(formatRadios).forEach(radio => {
+        if (radio.checked) {
+          outputFormat = radio.value as "side-by-side" | "line-by-line";
+        }
+      })
+      
+      // Render the diff using diff2html
+      const diffHtml = Diff2Html.html(diffText, {
+        outputFormat: outputFormat as "side-by-side" | "line-by-line",
+        drawFileList: true,
+        matching: "lines",
+        // Make sure no unnecessary scrollbars in the nested containers
+        renderNothingWhenEmpty: false,
+        colorScheme: "light" as any, // Force light mode to match the rest of the UI
+      });
+
+      // Insert the generated HTML
+      diff2htmlContent.innerHTML = diffHtml;
+
+      // Add CSS styles to ensure we don't have double scrollbars
+      const d2hFiles = diff2htmlContent.querySelectorAll(".d2h-file-wrapper");
+      d2hFiles.forEach((file) => {
+        const contentElem = file.querySelector(".d2h-files-diff");
+        if (contentElem) {
+          // Remove internal scrollbar - the outer container will handle scrolling
+          (contentElem as HTMLElement).style.overflow = "visible";
+          (contentElem as HTMLElement).style.maxHeight = "none";
+        }
+      });
+
+      // Add click event handlers to each code line for commenting
+      this.setupDiff2LineComments();
+      
+      // Setup event listeners for diff view format radio buttons
+      this.setupDiffViewFormatListeners();
+    } catch (error) {
+      console.error("Error loading diff2html content:", error);
+      const errorMessage =
+        error instanceof Error ? error.message : "Unknown error";
+      diff2htmlContent.innerHTML = `<span style='color: #dc3545;'>Error loading enhanced diff: ${errorMessage}</span>`;
+    }
+  }
+
+  /**
+   * Setup event listeners for diff view format radio buttons
+   */
+  private setupDiffViewFormatListeners(): void {
+    const formatRadios = document.getElementsByName("diffViewFormat") as NodeListOf<HTMLInputElement>;
+    
+    // Convert NodeListOf to Array to ensure [Symbol.iterator]() is available
+    Array.from(formatRadios).forEach(radio => {
+      radio.addEventListener("change", () => {
+        // Reload the diff with the new format when radio selection changes
+        this.loadDiff2HtmlContent(this.currentCommitHash);
+      });
+    })
+  }
+  
+  /**
+   * Setup handlers for diff2 code lines to enable commenting
+   */
+  private setupDiff2LineComments(): void {
+    const diff2htmlContent = document.getElementById("diff2htmlContent");
+    if (!diff2htmlContent) return;
+
+    console.log("Setting up diff2 line comments");
+
+    // Add plus buttons to each code line
+    this.addCommentButtonsToCodeLines();
+
+    // Use event delegation for handling clicks on plus buttons
+    diff2htmlContent.addEventListener("click", (event) => {
+      const target = event.target as HTMLElement;
+      
+      // Only respond to clicks on the plus button
+      if (target.classList.contains("d2h-gutter-comment-button")) {
+        // Find the parent row first
+        const row = target.closest("tr");
+        if (!row) return;
+        
+        // Then find the code line in that row
+        const codeLine = row.querySelector(".d2h-code-side-line") || row.querySelector(".d2h-code-line");
+        if (!codeLine) return;
+
+        // Get the line text content
+        const lineContent = codeLine.querySelector(".d2h-code-line-ctn");
+        if (!lineContent) return;
+
+        const lineText = lineContent.textContent?.trim() || "";
+
+        // Get file name to add context
+        const fileHeader = codeLine
+          .closest(".d2h-file-wrapper")
+          ?.querySelector(".d2h-file-name");
+        const fileName = fileHeader
+          ? fileHeader.textContent?.trim()
+          : "Unknown file";
+
+        // Get line number if available
+        const lineNumElem = codeLine
+          .closest("tr")
+          ?.querySelector(".d2h-code-side-linenumber");
+        const lineNum = lineNumElem ? lineNumElem.textContent?.trim() : "";
+        const lineInfo = lineNum ? `Line ${lineNum}: ` : "";
+
+        // Format the line for the comment box with file context and line number
+        const formattedLine = `${fileName} ${lineInfo}${lineText}`;
+
+        console.log("Comment button clicked for line: ", formattedLine);
+
+        // Open the comment box with this line
+        this.openDiffCommentBox(formattedLine, 0);
+
+        // Prevent event from bubbling up
+        event.stopPropagation();
+      }
+    });
+
+    // Handle text selection
+    let isSelecting = false;
+    
+    diff2htmlContent.addEventListener("mousedown", () => {
+      isSelecting = false;
+    });
+    
+    diff2htmlContent.addEventListener("mousemove", (event) => {
+      // If mouse is moving with button pressed, user is selecting text
+      if (event.buttons === 1) { // Primary button (usually left) is pressed
+        isSelecting = true;
+      }
+    });
+  }
+
+  /**
+   * Add plus buttons to each table row in the diff for commenting
+   */
+  private addCommentButtonsToCodeLines(): void {
+    const diff2htmlContent = document.getElementById("diff2htmlContent");
+    if (!diff2htmlContent) return;
+    
+    // Target code lines first, then find their parent rows
+    const codeLines = diff2htmlContent.querySelectorAll(
+      ".d2h-code-side-line, .d2h-code-line"
+    );
+    
+    // Create a Set to store unique rows to avoid duplicates
+    const rowsSet = new Set<HTMLElement>();
+    
+    // Get all rows that contain code lines
+    codeLines.forEach(line => {
+      const row = line.closest('tr');
+      if (row) rowsSet.add(row as HTMLElement);
+    });
+    
+    // Convert Set back to array for processing
+    const codeRows = Array.from(rowsSet);
+    
+    codeRows.forEach((row) => {
+      const rowElem = row as HTMLElement;
+      
+      // Skip info lines without actual code (e.g., "file added")
+      if (rowElem.querySelector(".d2h-info")) {
+        return;
+      }
+      
+      // Find the code line number element (first TD in the row)
+      const lineNumberCell = rowElem.querySelector(
+        ".d2h-code-side-linenumber, .d2h-code-linenumber"
+      );
+      
+      if (!lineNumberCell) return;
+      
+      // Create the plus button
+      const plusButton = document.createElement("span");
+      plusButton.className = "d2h-gutter-comment-button";
+      plusButton.innerHTML = "+";
+      plusButton.title = "Add a comment on this line";
+      
+      // Add button to the line number cell for proper positioning
+      (lineNumberCell as HTMLElement).style.position = "relative"; // Ensure positioning context
+      lineNumberCell.appendChild(plusButton);
+    });
+  }
+
+  /**
+   * Open the comment box for a selected diff line
+   */
+  private openDiffCommentBox(lineText: string, _lineNumber: number): void {
+    const commentBox = document.getElementById("diffCommentBox");
+    const selectedLine = document.getElementById("selectedLine");
+    const commentInput = document.getElementById(
+      "diffCommentInput",
+    ) as HTMLTextAreaElement;
+
+    if (!commentBox || !selectedLine || !commentInput) return;
+
+    // Store the selected line
+    this.selectedDiffLine = lineText;
+
+    // Display the line in the comment box
+    selectedLine.textContent = lineText;
+
+    // Reset the comment input
+    commentInput.value = "";
+
+    // Show the comment box
+    commentBox.style.display = "block";
+
+    // Focus on the comment input
+    commentInput.focus();
+
+    // Add event listeners for submit and cancel buttons
+    const submitButton = document.getElementById("submitDiffComment");
+    if (submitButton) {
+      submitButton.onclick = () => this.submitDiffComment();
+    }
+
+    const cancelButton = document.getElementById("cancelDiffComment");
+    if (cancelButton) {
+      cancelButton.onclick = () => this.closeDiffCommentBox();
+    }
+  }
+
+  /**
+   * Close the diff comment box without submitting
+   */
+  private closeDiffCommentBox(): void {
+    const commentBox = document.getElementById("diffCommentBox");
+    if (commentBox) {
+      commentBox.style.display = "none";
+    }
+    this.selectedDiffLine = null;
+  }
+
+  /**
+   * Submit a comment on a diff line
+   */
+  private submitDiffComment(): void {
+    const commentInput = document.getElementById(
+      "diffCommentInput",
+    ) as HTMLTextAreaElement;
+    const chatInput = document.getElementById(
+      "chatInput",
+    ) as HTMLTextAreaElement;
+
+    if (!commentInput || !chatInput) return;
+
+    const comment = commentInput.value.trim();
+
+    // Validate inputs
+    if (!this.selectedDiffLine || !comment) {
+      alert("Please select a line and enter a comment.");
+      return;
+    }
+
+    // Format the comment in a readable way
+    const formattedComment = `\`\`\`\n${this.selectedDiffLine}\n\`\`\`\n\n${comment}`;
+
+    // Append the formatted comment to the chat textarea
+    if (chatInput.value.trim() !== "") {
+      chatInput.value += "\n\n"; // Add two line breaks before the new comment
+    }
+    chatInput.value += formattedComment;
+    chatInput.focus();
+
+    // Close only the comment box but keep the diff view open
+    this.closeDiffCommentBox();
+  }
+
+  /**
+   * Show diff for a specific commit
+   * @param commitHash The commit hash to show diff for
+   * @param toggleViewModeCallback Callback to toggle view mode to diff
+   */
+  public showCommitDiff(commitHash: string, toggleViewModeCallback: (mode: string) => void): void {
+    // Store the commit hash
+    this.currentCommitHash = commitHash;
+    
+    // Switch to diff2 view (side-by-side)
+    toggleViewModeCallback("diff2");
+  }
+
+  /**
+   * Clean up resources when component is destroyed
+   */
+  public dispose(): void {
+    // Clean up any resources or event listeners here
+    // Currently there are no specific resources to clean up
+  }
+}
diff --git a/loop/webui/src/timeline/icons/index.ts b/loop/webui/src/timeline/icons/index.ts
new file mode 100644
index 0000000..d9480c5
--- /dev/null
+++ b/loop/webui/src/timeline/icons/index.ts
@@ -0,0 +1,19 @@
+/**
+ * Get the icon text to display for a message type
+ * @param type - The message type
+ * @returns The single character to represent this message type
+ */
+export function getIconText(type: string | null | undefined): string {
+  switch (type) {
+    case "user":
+      return "U";
+    case "agent":
+      return "A";
+    case "tool":
+      return "T";
+    case "error":
+      return "E";
+    default:
+      return "?";
+  }
+}
diff --git a/loop/webui/src/timeline/index.ts b/loop/webui/src/timeline/index.ts
new file mode 100644
index 0000000..a3d24b7
--- /dev/null
+++ b/loop/webui/src/timeline/index.ts
@@ -0,0 +1,24 @@
+// Export types
+export * from './types';
+
+// Export utility functions
+export * from './utils';
+
+// Export terminal handler
+export * from './terminal';
+
+// Export diff viewer
+export * from './diffviewer';
+
+// Export chart manager
+export * from './charts';
+
+// Export tool call utilities
+export * from './toolcalls';
+
+// Export copy button utilities
+export * from './copybutton';
+
+// Re-export the timeline manager (will be implemented later)
+// For now, we'll maintain backward compatibility by importing from the original file
+import '../timeline';
diff --git a/loop/webui/src/timeline/markdown/renderer.ts b/loop/webui/src/timeline/markdown/renderer.ts
new file mode 100644
index 0000000..8199b69
--- /dev/null
+++ b/loop/webui/src/timeline/markdown/renderer.ts
@@ -0,0 +1,40 @@
+import { marked } from "marked";
+
+/**
+ * Renders markdown content as HTML with proper security handling.
+ *
+ * @param markdownContent - The markdown string to render
+ * @returns The rendered HTML content as a string
+ */
+export async function renderMarkdown(markdownContent: string): Promise<string> {
+  try {
+    // Set markdown options for proper code block highlighting and safety
+    const markedOptions = {
+      gfm: true, // GitHub Flavored Markdown
+      breaks: true, // Convert newlines to <br>
+      headerIds: false, // Disable header IDs for safety
+      mangle: false, // Don't mangle email addresses
+      // DOMPurify is recommended for production, but not included in this implementation
+    };
+
+    return await marked.parse(markdownContent, markedOptions);
+  } catch (error) {
+    console.error("Error rendering markdown:", error);
+    // Fallback to plain text if markdown parsing fails
+    return markdownContent;
+  }
+}
+
+/**
+ * Process rendered markdown HTML element, adding security attributes to links.
+ *
+ * @param element - The HTML element containing rendered markdown
+ */
+export function processRenderedMarkdown(element: HTMLElement): void {
+  // Make sure links open in a new tab and have proper security attributes
+  const links = element.querySelectorAll("a");
+  links.forEach((link) => {
+    link.setAttribute("target", "_blank");
+    link.setAttribute("rel", "noopener noreferrer");
+  });
+}
diff --git a/loop/webui/src/timeline/renderer.ts b/loop/webui/src/timeline/renderer.ts
new file mode 100644
index 0000000..f2770ee
--- /dev/null
+++ b/loop/webui/src/timeline/renderer.ts
@@ -0,0 +1,729 @@
+/**
+ * MessageRenderer - Class to handle rendering of timeline messages
+ */
+
+import { TimelineMessage, ToolCall } from "./types";
+import { escapeHTML, formatNumber, generateColorFromId } from "./utils";
+import { renderMarkdown, processRenderedMarkdown } from "./markdown/renderer";
+import { createToolCallCard, updateToolCallCard } from "./toolcalls";
+import { createCommitsContainer } from "./commits";
+import { createCopyButton } from "./copybutton";
+import { getIconText } from "./icons";
+import { addCollapsibleFunctionality } from "./components/collapsible";
+import { checkShouldScroll, scrollToBottom } from "./scroll";
+
+export class MessageRenderer {
+  // Map to store references to agent message DOM elements by tool call ID
+  private toolCallIdToMessageElement: Map<
+    string,
+    {
+      messageEl: HTMLElement;
+      toolCallContainer: HTMLElement | null;
+      toolCardId: string;
+    }
+  > = new Map();
+
+  // State tracking variables
+  private isFirstLoad: boolean = true;
+  private shouldScrollToBottom: boolean = true;
+  private currentFetchStartIndex: number = 0;
+
+  constructor() {}
+
+  /**
+   * Initialize the renderer with state from the timeline manager
+   */
+  public initialize(isFirstLoad: boolean, currentFetchStartIndex: number) {
+    this.isFirstLoad = isFirstLoad;
+    this.currentFetchStartIndex = currentFetchStartIndex;
+  }
+
+  /**
+   * Renders the timeline with messages
+   * @param messages The messages to render
+   * @param clearExisting Whether to clear existing content before rendering
+   */
+  public renderTimeline(
+    messages: TimelineMessage[],
+    clearExisting: boolean = false,
+  ): void {
+    const timeline = document.getElementById("timeline");
+    if (!timeline) return;
+
+    // We'll keep the isFirstLoad value for this render cycle,
+    // but will set it to false afterwards in scrollToBottom
+
+    if (clearExisting) {
+      timeline.innerHTML = ""; // Clear existing content only if this is the first load
+      // Clear our map of tool call references
+      this.toolCallIdToMessageElement.clear();
+    }
+
+    if (!messages || messages.length === 0) {
+      if (clearExisting) {
+        timeline.innerHTML = "<p>No messages available.</p>";
+        timeline.classList.add("empty");
+      }
+      return;
+    }
+
+    // Remove empty class when there are messages
+    timeline.classList.remove("empty");
+
+    // Keep track of conversation groups to properly indent
+    interface ConversationGroup {
+      color: string;
+      level: number;
+    }
+
+    const conversationGroups: Record<string, ConversationGroup> = {};
+
+    // Use the currentFetchStartIndex as the base index for these messages
+    const startIndex = this.currentFetchStartIndex;
+    // Group tool messages with their parent agent messages
+    const organizedMessages: (TimelineMessage & {
+      toolResponses?: TimelineMessage[];
+    })[] = [];
+    const toolMessagesByCallId: Record<string, TimelineMessage> = {};
+
+    // First, process tool messages - check if any can update existing UI elements
+    const processedToolMessages = new Set<string>();
+
+    messages.forEach((message) => {
+      // If this is a tool message with a tool_call_id
+      if (message.type === "tool" && message.tool_call_id) {
+        // Try to find an existing agent message that's waiting for this tool response
+        const toolCallRef = this.toolCallIdToMessageElement.get(
+          message.tool_call_id,
+        );
+
+        if (toolCallRef) {
+          // Found an existing agent message that needs updating
+          this.updateToolCallInAgentMessage(message, toolCallRef);
+          processedToolMessages.add(message.tool_call_id);
+        } else {
+          // No existing agent message found, we'll include this in normal rendering
+          toolMessagesByCallId[message.tool_call_id] = message;
+        }
+      }
+    });
+
+    // Then, process messages and organize them
+    messages.forEach((message, localIndex) => {
+      const _index = startIndex + localIndex;
+      if (!message) return; // Skip if message is null/undefined
+
+      // If it's a tool message and we're going to inline it with its parent agent message,
+      // we'll skip rendering it here - it will be included with the agent message
+      if (message.type === "tool" && message.tool_call_id) {
+        // Skip if we've already processed this tool message (updated an existing agent message)
+        if (processedToolMessages.has(message.tool_call_id)) {
+          return;
+        }
+
+        // Skip if this tool message will be included with a new agent message
+        if (toolMessagesByCallId[message.tool_call_id]) {
+          return;
+        }
+      }
+
+      // For agent messages with tool calls, attach their tool responses
+      if (
+        message.type === "agent" &&
+        message.tool_calls &&
+        message.tool_calls.length > 0
+      ) {
+        const toolResponses: TimelineMessage[] = [];
+
+        // Look up tool responses for each tool call
+        message.tool_calls.forEach((toolCall) => {
+          if (
+            toolCall.tool_call_id &&
+            toolMessagesByCallId[toolCall.tool_call_id]
+          ) {
+            toolResponses.push(toolMessagesByCallId[toolCall.tool_call_id]);
+          }
+        });
+
+        if (toolResponses.length > 0) {
+          message = { ...message, toolResponses };
+        }
+      }
+
+      organizedMessages.push(message);
+    });
+
+    let lastMessage:TimelineMessage|undefined;
+    if (messages && messages.length > 0 && startIndex > 0) {
+      lastMessage = messages[startIndex-1];
+    }
+
+    // Loop through organized messages and create timeline items
+    organizedMessages.forEach((message, localIndex) => {
+      const _index = startIndex + localIndex;
+      if (!message) return; // Skip if message is null/undefined
+
+      if (localIndex > 0) {
+        lastMessage = organizedMessages.at(localIndex-1);
+      }
+      // Determine if this is a subconversation
+      const hasParent = !!message.parent_conversation_id;
+      const conversationId = message.conversation_id || "";
+      const _parentId = message.parent_conversation_id || "";
+
+      // Track the conversation group
+      if (conversationId && !conversationGroups[conversationId]) {
+        conversationGroups[conversationId] = {
+          color: generateColorFromId(conversationId),
+          level: hasParent ? 1 : 0, // Level 0 for main conversation, 1+ for nested
+        };
+      }
+
+      // Get the level and color for this message
+      const group = conversationGroups[conversationId] || {
+        level: 0,
+        color: "#888888",
+      };
+
+      const messageEl = document.createElement("div");
+      messageEl.className = `message ${message.type || "unknown"} ${message.end_of_turn ? "end-of-turn" : ""}`;
+
+      // Add indentation class for subconversations
+      if (hasParent) {
+        messageEl.classList.add("subconversation");
+        messageEl.style.marginLeft = `${group.level * 40}px`;
+
+        // Add a colored left border to indicate the subconversation
+        messageEl.style.borderLeft = `4px solid ${group.color}`;
+      }
+
+      // newMsgType indicates when to create a new icon and message
+      // type header. This is a primitive form of message coalescing,
+      // but it does reduce the amount of redundant information in
+      // the UI.
+      const newMsgType = !lastMessage || 
+        (message.type == 'user' && lastMessage.type != 'user') ||
+        (message.type != 'user' && lastMessage.type == 'user');
+
+      if (newMsgType) {
+        // Create message icon
+        const iconEl = document.createElement("div");
+        iconEl.className = "message-icon";
+        iconEl.textContent = getIconText(message.type);
+        messageEl.appendChild(iconEl);
+      }
+
+      // Create message content container
+      const contentEl = document.createElement("div");
+      contentEl.className = "message-content";
+
+      // Create message header
+      const headerEl = document.createElement("div");
+      headerEl.className = "message-header";
+
+      if (newMsgType) {
+        const typeEl = document.createElement("span");
+        typeEl.className = "message-type";
+        typeEl.textContent = this.getTypeName(message.type);
+        headerEl.appendChild(typeEl);
+      }
+
+      // Add timestamp and usage info combined for agent messages at the top
+      if (message.timestamp) {
+        const timestampEl = document.createElement("span");
+        timestampEl.className = "message-timestamp";
+        timestampEl.textContent = this.formatTimestamp(message.timestamp);
+
+        // Add elapsed time if available
+        if (message.elapsed) {
+          timestampEl.textContent += ` (${(message.elapsed / 1e9).toFixed(2)}s)`;
+        }
+
+        // Add turn duration for end-of-turn messages
+        if (message.turnDuration && message.end_of_turn) {
+          timestampEl.textContent += ` [Turn: ${(message.turnDuration / 1e9).toFixed(2)}s]`;
+        }
+
+        // Add usage info inline for agent messages
+        if (
+          message.type === "agent" &&
+          message.usage &&
+          (message.usage.input_tokens > 0 ||
+            message.usage.output_tokens > 0 ||
+            message.usage.cost_usd > 0)
+        ) {
+          try {
+            // Safe get all values
+            const inputTokens = formatNumber(
+              message.usage.input_tokens ?? 0,
+            );
+            const cacheInput = message.usage.cache_read_input_tokens ?? 0;
+            const outputTokens = formatNumber(
+              message.usage.output_tokens ?? 0,
+            );
+            const messageCost = this.formatCurrency(
+              message.usage.cost_usd ?? 0,
+              "$0.0000", // Default format for message costs
+              true, // Use 4 decimal places for message-level costs
+            );
+
+            timestampEl.textContent += ` | In: ${inputTokens}`;
+            if (cacheInput > 0) {
+              timestampEl.textContent += ` [Cache: ${formatNumber(cacheInput)}]`;
+            }
+            timestampEl.textContent += ` Out: ${outputTokens} (${messageCost})`;
+          } catch (e) {
+            console.error("Error adding usage info to timestamp:", e);
+          }
+        }
+
+        headerEl.appendChild(timestampEl);
+      }
+
+      contentEl.appendChild(headerEl);
+
+      // Add message content
+      if (message.content) {
+        const containerEl = document.createElement("div");
+        containerEl.className = "message-text-container";
+
+        const textEl = document.createElement("div");
+        textEl.className = "message-text markdown-content";
+        
+        // Render markdown content
+        // Handle the Promise returned by renderMarkdown
+        renderMarkdown(message.content).then(html => {
+          textEl.innerHTML = html;
+          processRenderedMarkdown(textEl);
+        });
+
+        // Add copy button
+        const { container: copyButtonContainer, button: copyButton } = createCopyButton(message.content);
+        containerEl.appendChild(copyButtonContainer);
+        containerEl.appendChild(textEl);
+
+        // Add collapse/expand for long content
+        addCollapsibleFunctionality(message, textEl, containerEl, contentEl);
+      }
+
+      // If the message has tool calls, show them in an ultra-compact row of boxes
+      if (message.tool_calls && message.tool_calls.length > 0) {
+        const toolCallsContainer = document.createElement("div");
+        toolCallsContainer.className = "tool-calls-container";
+
+        // Create a header row with tool count
+        const toolCallsHeaderRow = document.createElement("div");
+        toolCallsHeaderRow.className = "tool-calls-header";
+        // No header text - empty header
+        toolCallsContainer.appendChild(toolCallsHeaderRow);
+
+        // Create a container for the tool call cards
+        const toolCallsCardContainer = document.createElement("div");
+        toolCallsCardContainer.className = "tool-call-cards-container";
+
+        // Add each tool call as a card with response or spinner
+        message.tool_calls.forEach((toolCall: ToolCall, _index: number) => {
+          // Create a unique ID for this tool card
+          const toolCardId = `tool-card-${toolCall.tool_call_id || Math.random().toString(36).substring(2, 11)}`;
+          
+          // Find the matching tool response if it exists
+          const toolResponse = message.toolResponses?.find(
+            (resp) => resp.tool_call_id === toolCall.tool_call_id,
+          );
+          
+          // Use the extracted utility function to create the tool card
+          const toolCard = createToolCallCard(toolCall, toolResponse, toolCardId);
+
+          // Store reference to this element if it has a tool_call_id
+          if (toolCall.tool_call_id) {
+            this.toolCallIdToMessageElement.set(toolCall.tool_call_id, {
+              messageEl,
+              toolCallContainer: toolCallsCardContainer,
+              toolCardId,
+            });
+          }
+
+          // Add the card to the container
+          toolCallsCardContainer.appendChild(toolCard);
+        });
+
+        toolCallsContainer.appendChild(toolCallsCardContainer);
+        contentEl.appendChild(toolCallsContainer);
+      }
+      // If message is a commit message, display commits
+      if (
+        message.type === "commit" &&
+        message.commits &&
+        message.commits.length > 0
+      ) {
+        // Use the extracted utility function to create the commits container
+        const commitsContainer = createCommitsContainer(
+          message.commits,
+          (commitHash) => {
+            // This will need to be handled by the TimelineManager
+            const event = new CustomEvent('showCommitDiff', {
+              detail: { commitHash }
+            });
+            document.dispatchEvent(event);
+          }
+        );
+        contentEl.appendChild(commitsContainer);
+      }
+
+      // Tool messages are now handled inline with agent messages
+      // If we still see a tool message here, it means it's not associated with an agent message
+      // (this could be legacy data or a special case)
+      if (message.type === "tool") {
+        const toolDetailsEl = document.createElement("div");
+        toolDetailsEl.className = "tool-details standalone";
+
+        // Get tool input and result for display
+        let inputText = "";
+        try {
+          if (message.input) {
+            const parsedInput = JSON.parse(message.input);
+            // Format input compactly for simple inputs
+            inputText = JSON.stringify(parsedInput);
+          }
+        } catch (e) {
+          // Not valid JSON, use as-is
+          inputText = message.input || "";
+        }
+
+        const resultText = message.tool_result || "";
+        const statusEmoji = message.tool_error ? "❌" : "✅";
+        const toolName = message.tool_name || "Unknown";
+
+        // Determine if we can use super compact display (e.g., for bash command results)
+        // Use compact display for short inputs/outputs without newlines
+        const isSimpleCommand =
+          toolName === "bash" &&
+          inputText.length < 50 &&
+          resultText.length < 200 &&
+          !resultText.includes("\n");
+        const isCompact =
+          inputText.length < 50 &&
+          resultText.length < 100 &&
+          !resultText.includes("\n");
+
+        if (isSimpleCommand) {
+          // SUPER COMPACT VIEW FOR BASH: Display everything on a single line
+          const toolLineEl = document.createElement("div");
+          toolLineEl.className = "tool-compact-line";
+
+          // Create the compact bash display in format: "✅ bash({command}) → result"
+          try {
+            const parsed = JSON.parse(inputText);
+            const cmd = parsed.command || "";
+            toolLineEl.innerHTML = `${statusEmoji} <strong>${toolName}</strong>({"command":"${cmd}"}) → <span class="tool-result-inline">${resultText}</span>`;
+          } catch {
+            toolLineEl.innerHTML = `${statusEmoji} <strong>${toolName}</strong>(${inputText}) → <span class="tool-result-inline">${resultText}</span>`;
+          }
+
+          // Add copy button for result
+          const copyBtn = document.createElement("button");
+          copyBtn.className = "copy-inline-button";
+          copyBtn.textContent = "Copy";
+          copyBtn.title = "Copy result to clipboard";
+
+          copyBtn.addEventListener("click", (e) => {
+            e.stopPropagation();
+            navigator.clipboard
+              .writeText(resultText)
+              .then(() => {
+                copyBtn.textContent = "Copied!";
+                setTimeout(() => {
+                  copyBtn.textContent = "Copy";
+                }, 2000);
+              })
+              .catch((_err) => {
+                copyBtn.textContent = "Failed";
+                setTimeout(() => {
+                  copyBtn.textContent = "Copy";
+                }, 2000);
+              });
+          });
+
+          toolLineEl.appendChild(copyBtn);
+          toolDetailsEl.appendChild(toolLineEl);
+        } else if (isCompact && !isSimpleCommand) {
+          // COMPACT VIEW: Display everything on one or two lines for other tool types
+          const toolLineEl = document.createElement("div");
+          toolLineEl.className = "tool-compact-line";
+
+          // Create the compact display in format: "✅ tool_name(input) → result"
+          let compactDisplay = `${statusEmoji} <strong>${toolName}</strong>(${inputText})`;
+
+          if (resultText) {
+            compactDisplay += ` → <span class="tool-result-inline">${resultText}</span>`;
+          }
+
+          toolLineEl.innerHTML = compactDisplay;
+
+          // Add copy button for result
+          const copyBtn = document.createElement("button");
+          copyBtn.className = "copy-inline-button";
+          copyBtn.textContent = "Copy";
+          copyBtn.title = "Copy result to clipboard";
+
+          copyBtn.addEventListener("click", (e) => {
+            e.stopPropagation();
+            navigator.clipboard
+              .writeText(resultText)
+              .then(() => {
+                copyBtn.textContent = "Copied!";
+                setTimeout(() => {
+                  copyBtn.textContent = "Copy";
+                }, 2000);
+              })
+              .catch((_err) => {
+                copyBtn.textContent = "Failed";
+                setTimeout(() => {
+                  copyBtn.textContent = "Copy";
+                }, 2000);
+              });
+          });
+
+          toolLineEl.appendChild(copyBtn);
+          toolDetailsEl.appendChild(toolLineEl);
+        } else {
+          // EXPANDED VIEW: For longer inputs/results that need more space
+          // Tool name header
+          const toolNameEl = document.createElement("div");
+          toolNameEl.className = "tool-name";
+          toolNameEl.innerHTML = `${statusEmoji} <strong>${toolName}</strong>`;
+          toolDetailsEl.appendChild(toolNameEl);
+
+          // Show input (simplified)
+          if (message.input) {
+            const inputContainer = document.createElement("div");
+            inputContainer.className = "tool-input-container compact";
+
+            const inputEl = document.createElement("pre");
+            inputEl.className = "tool-input compact";
+            inputEl.textContent = inputText;
+            inputContainer.appendChild(inputEl);
+            toolDetailsEl.appendChild(inputContainer);
+          }
+
+          // Show result (simplified)
+          if (resultText) {
+            const resultContainer = document.createElement("div");
+            resultContainer.className = "tool-result-container compact";
+
+            const resultEl = document.createElement("pre");
+            resultEl.className = "tool-result compact";
+            resultEl.textContent = resultText;
+            resultContainer.appendChild(resultEl);
+
+            // Add collapse/expand for longer results
+            if (resultText.length > 100) {
+              resultEl.classList.add("collapsed");
+
+              const toggleButton = document.createElement("button");
+              toggleButton.className = "collapsible";
+              toggleButton.textContent = "Show more...";
+              toggleButton.addEventListener("click", () => {
+                resultEl.classList.toggle("collapsed");
+                toggleButton.textContent = resultEl.classList.contains(
+                  "collapsed",
+                )
+                  ? "Show more..."
+                  : "Show less";
+              });
+
+              toolDetailsEl.appendChild(resultContainer);
+              toolDetailsEl.appendChild(toggleButton);
+            } else {
+              toolDetailsEl.appendChild(resultContainer);
+            }
+          }
+        }
+
+        contentEl.appendChild(toolDetailsEl);
+      }
+
+      // Add usage info if available with robust null handling - only for non-agent messages
+      if (
+        message.type !== "agent" && // Skip for agent messages as we've already added usage info at the top
+        message.usage &&
+        (message.usage.input_tokens > 0 ||
+          message.usage.output_tokens > 0 ||
+          message.usage.cost_usd > 0)
+      ) {
+        try {
+          const usageEl = document.createElement("div");
+          usageEl.className = "usage-info";
+
+          // Safe get all values
+          const inputTokens = formatNumber(
+            message.usage.input_tokens ?? 0,
+          );
+          const cacheInput = message.usage.cache_read_input_tokens ?? 0;
+          const outputTokens = formatNumber(
+            message.usage.output_tokens ?? 0,
+          );
+          const messageCost = this.formatCurrency(
+            message.usage.cost_usd ?? 0,
+            "$0.0000", // Default format for message costs
+            true, // Use 4 decimal places for message-level costs
+          );
+
+          // Create usage info display
+          usageEl.innerHTML = `
+            <span title="Input tokens">In: ${inputTokens}</span>
+            ${cacheInput > 0 ? `<span title="Cache tokens">[Cache: ${formatNumber(cacheInput)}]</span>` : ""}
+            <span title="Output tokens">Out: ${outputTokens}</span>
+            <span title="Message cost">(${messageCost})</span>
+          `;
+
+          contentEl.appendChild(usageEl);
+        } catch (e) {
+          console.error("Error rendering usage info:", e);
+        }
+      }
+
+      messageEl.appendChild(contentEl);
+      timeline.appendChild(messageEl);
+    });
+
+    // Scroll to bottom of the timeline if needed
+    this.scrollToBottom();
+  }
+
+  /**
+   * Check if we should scroll to the bottom
+   */
+  private checkShouldScroll(): boolean {
+    return checkShouldScroll(this.isFirstLoad);
+  }
+
+  /**
+   * Scroll to the bottom of the timeline
+   */
+  private scrollToBottom(): void {
+    scrollToBottom(this.shouldScrollToBottom);
+
+    // After first load, we'll only auto-scroll if user is already near the bottom
+    this.isFirstLoad = false;
+  }
+
+  /**
+   * Get readable name for message type
+   */
+  private getTypeName(type: string | null | undefined): string {
+    switch (type) {
+      case "user":
+        return "User";
+      case "agent":
+        return "Agent";
+      case "tool":
+        return "Tool Use";
+      case "error":
+        return "Error";
+      default:
+        return (
+          (type || "Unknown").charAt(0).toUpperCase() +
+          (type || "unknown").slice(1)
+        );
+    }
+  }
+
+  /**
+   * Format timestamp for display
+   */
+  private formatTimestamp(
+    timestamp: string | number | Date | null | undefined,
+    defaultValue: string = "",
+  ): string {
+    if (!timestamp) return defaultValue;
+    try {
+      const date = new Date(timestamp);
+      if (isNaN(date.getTime())) return defaultValue;
+
+      // Format: Mar 13, 2025 09:53:25 AM
+      return date.toLocaleString("en-US", {
+        month: "short",
+        day: "numeric",
+        year: "numeric",
+        hour: "numeric",
+        minute: "2-digit",
+        second: "2-digit",
+        hour12: true,
+      });
+    } catch (e) {
+      return defaultValue;
+    }
+  }
+
+  /**
+   * Format currency values
+   */
+  private formatCurrency(
+    num: number | string | null | undefined,
+    defaultValue: string = "$0.00",
+    isMessageLevel: boolean = false,
+  ): string {
+    if (num === undefined || num === null) return defaultValue;
+    try {
+      // Use 4 decimal places for message-level costs, 2 for totals
+      const decimalPlaces = isMessageLevel ? 4 : 2;
+      return `$${parseFloat(String(num)).toFixed(decimalPlaces)}`;
+    } catch (e) {
+      return defaultValue;
+    }
+  }
+
+  /**
+   * Update a tool call in an agent message with the response
+   */
+  private updateToolCallInAgentMessage(
+    toolMessage: TimelineMessage,
+    toolCallRef: {
+      messageEl: HTMLElement;
+      toolCallContainer: HTMLElement | null;
+      toolCardId: string;
+    },
+  ): void {
+    const { messageEl, toolCardId } = toolCallRef;
+
+    // Find the tool card element
+    const toolCard = messageEl.querySelector(`#${toolCardId}`) as HTMLElement;
+    if (!toolCard) return;
+
+    // Use the extracted utility function to update the tool card
+    updateToolCallCard(toolCard, toolMessage);
+  }
+
+  /**
+   * Get the tool call id to message element map
+   * Used by the TimelineManager to access the map
+   */
+  public getToolCallIdToMessageElement(): Map<
+    string,
+    {
+      messageEl: HTMLElement;
+      toolCallContainer: HTMLElement | null;
+      toolCardId: string;
+    }
+  > {
+    return this.toolCallIdToMessageElement;
+  }
+
+  /**
+   * Set the tool call id to message element map
+   * Used by the TimelineManager to update the map
+   */
+  public setToolCallIdToMessageElement(
+    map: Map<
+      string,
+      {
+        messageEl: HTMLElement;
+        toolCallContainer: HTMLElement | null;
+        toolCardId: string;
+      }
+    >
+  ): void {
+    this.toolCallIdToMessageElement = map;
+  }
+}
diff --git a/loop/webui/src/timeline/scroll.ts b/loop/webui/src/timeline/scroll.ts
new file mode 100644
index 0000000..df3b8f9
--- /dev/null
+++ b/loop/webui/src/timeline/scroll.ts
@@ -0,0 +1,40 @@
+/**
+ * Check if the page should scroll to the bottom based on current view position
+ * @param isFirstLoad If this is the first load of the timeline
+ * @returns Boolean indicating if we should scroll to the bottom
+ */
+export function checkShouldScroll(isFirstLoad: boolean): boolean {
+  // Always scroll on first load
+  if (isFirstLoad) {
+    return true;
+  }
+
+  // Check if user is already near the bottom of the page
+  // Account for the fixed top bar and chat bar
+  return (
+    window.innerHeight + window.scrollY >= document.body.offsetHeight - 200
+  );
+}
+
+/**
+ * Scroll to the bottom of the timeline if shouldScrollToBottom is true
+ * @param shouldScrollToBottom Flag indicating if we should scroll
+ */
+export function scrollToBottom(shouldScrollToBottom: boolean): void {
+  // Find the timeline container
+  const timeline = document.getElementById("timeline");
+
+  // Scroll the window to the bottom based on our pre-determined value
+  if (timeline && shouldScrollToBottom) {
+    // Get the last message or element in the timeline
+    const lastElement = timeline.lastElementChild;
+
+    if (lastElement) {
+      // Scroll to the bottom of the page
+      window.scrollTo({
+        top: document.body.scrollHeight,
+        behavior: "smooth",
+      });
+    }
+  }
+}
diff --git a/loop/webui/src/timeline/terminal.ts b/loop/webui/src/timeline/terminal.ts
new file mode 100644
index 0000000..fbe9a7d
--- /dev/null
+++ b/loop/webui/src/timeline/terminal.ts
@@ -0,0 +1,269 @@
+import { Terminal } from "@xterm/xterm";
+import { FitAddon } from "@xterm/addon-fit";
+
+/**
+ * Class to handle terminal functionality in the timeline UI.
+ */
+export class TerminalHandler {
+  // Terminal instance
+  private terminal: Terminal | null = null;
+  // Terminal fit addon for handling resize
+  private fitAddon: FitAddon | null = null;
+  // Terminal EventSource for SSE
+  private terminalEventSource: EventSource | null = null;
+  // Terminal ID (always 1 for now, will support 1-9 later)
+  private terminalId: string = "1";
+  // Queue for serializing terminal inputs
+  private terminalInputQueue: string[] = [];
+  // Flag to track if we're currently processing a terminal input
+  private processingTerminalInput: boolean = false;
+  // Current view mode (needed for resize handling)
+  private viewMode: string = "chat";
+
+  /**
+   * Constructor for TerminalHandler
+   */
+  constructor() {}
+
+  /**
+   * Sets the current view mode
+   * @param mode The current view mode
+   */
+  public setViewMode(mode: string): void {
+    this.viewMode = mode;
+  }
+
+  /**
+   * Initialize the terminal component
+   * @param terminalContainer The DOM element to contain the terminal
+   */
+  public async initializeTerminal(): Promise<void> {
+    const terminalContainer = document.getElementById("terminalContainer");
+
+    if (!terminalContainer) {
+      console.error("Terminal container not found");
+      return;
+    }
+
+    // If terminal is already initialized, just focus it
+    if (this.terminal) {
+      this.terminal.focus();
+      if (this.fitAddon) {
+        this.fitAddon.fit();
+      }
+      return;
+    }
+
+    // Clear the terminal container
+    terminalContainer.innerHTML = "";
+
+    // Create new terminal instance
+    this.terminal = new Terminal({
+      cursorBlink: true,
+      theme: {
+        background: "#f5f5f5",
+        foreground: "#333333",
+        cursor: "#0078d7",
+        selectionBackground: "rgba(0, 120, 215, 0.4)",
+      },
+    });
+
+    // Add fit addon to handle terminal resizing
+    this.fitAddon = new FitAddon();
+    this.terminal.loadAddon(this.fitAddon);
+
+    // Open the terminal in the container
+    this.terminal.open(terminalContainer);
+
+    // Connect to WebSocket
+    await this.connectTerminal();
+
+    // Fit the terminal to the container
+    this.fitAddon.fit();
+
+    // Setup resize handler
+    window.addEventListener("resize", () => {
+      if (this.viewMode === "terminal" && this.fitAddon) {
+        this.fitAddon.fit();
+        // Send resize information to server
+        this.sendTerminalResize();
+      }
+    });
+
+    // Focus the terminal
+    this.terminal.focus();
+  }
+
+  /**
+   * Connect to terminal events stream
+   */
+  private async connectTerminal(): Promise<void> {
+    if (!this.terminal) {
+      return;
+    }
+
+    // Close existing connections if any
+    this.closeTerminalConnections();
+
+    try {
+      // Connect directly to the SSE endpoint for terminal 1
+      // Use relative URL based on current location
+      const baseUrl = window.location.pathname.endsWith('/') ? '.' : '.';
+      const eventsUrl = `${baseUrl}/terminal/events/${this.terminalId}`;
+      this.terminalEventSource = new EventSource(eventsUrl);
+      
+      // Handle SSE events
+      this.terminalEventSource.onopen = () => {
+        console.log("Terminal SSE connection opened");
+        this.sendTerminalResize();
+      };
+      
+      this.terminalEventSource.onmessage = (event) => {
+        if (this.terminal) {
+          // Decode base64 data before writing to terminal
+          try {
+            const decoded = atob(event.data);
+            this.terminal.write(decoded);
+          } catch (e) {
+            console.error('Error decoding terminal data:', e);
+            // Fallback to raw data if decoding fails
+            this.terminal.write(event.data);
+          }
+        }
+      };
+      
+      this.terminalEventSource.onerror = (error) => {
+        console.error("Terminal SSE error:", error);
+        if (this.terminal) {
+          this.terminal.write("\r\n\x1b[1;31mConnection error\x1b[0m\r\n");
+        }
+        // Attempt to reconnect if the connection was lost
+        if (this.terminalEventSource?.readyState === EventSource.CLOSED) {
+          this.closeTerminalConnections();
+        }
+      };
+      
+      // Send key inputs to the server via POST requests
+      if (this.terminal) {
+        this.terminal.onData((data) => {
+          this.sendTerminalInput(data);
+        });
+      }
+    } catch (error) {
+      console.error("Failed to connect to terminal:", error);
+      if (this.terminal) {
+        this.terminal.write(`\r\n\x1b[1;31mFailed to connect: ${error}\x1b[0m\r\n`);
+      }
+    }
+  }
+
+  /**
+   * Close any active terminal connections
+   */
+  private closeTerminalConnections(): void {
+    if (this.terminalEventSource) {
+      this.terminalEventSource.close();
+      this.terminalEventSource = null;
+    }
+  }
+
+  /**
+   * Send input to the terminal
+   * @param data The input data to send
+   */
+  private async sendTerminalInput(data: string): Promise<void> {
+    // Add the data to the queue
+    this.terminalInputQueue.push(data);
+    
+    // If we're not already processing inputs, start processing
+    if (!this.processingTerminalInput) {
+      await this.processTerminalInputQueue();
+    }
+  }
+
+  /**
+   * Process the terminal input queue in order
+   */
+  private async processTerminalInputQueue(): Promise<void> {
+    if (this.terminalInputQueue.length === 0) {
+      this.processingTerminalInput = false;
+      return;
+    }
+    
+    this.processingTerminalInput = true;
+    
+    // Concatenate all available inputs from the queue into a single request
+    let combinedData = '';
+    
+    // Take all currently available items from the queue
+    while (this.terminalInputQueue.length > 0) {
+      combinedData += this.terminalInputQueue.shift()!;
+    }
+    
+    try {
+      // Use relative URL based on current location
+      const baseUrl = window.location.pathname.endsWith('/') ? '.' : '.';
+      const response = await fetch(`${baseUrl}/terminal/input/${this.terminalId}`, {
+        method: 'POST',
+        body: combinedData,
+        headers: {
+          'Content-Type': 'text/plain'
+        }
+      });
+      
+      if (!response.ok) {
+        console.error(`Failed to send terminal input: ${response.status} ${response.statusText}`);
+      }
+    } catch (error) {
+      console.error("Error sending terminal input:", error);
+    }
+    
+    // Continue processing the queue (for any new items that may have been added)
+    await this.processTerminalInputQueue();
+  }
+
+  /**
+   * Send terminal resize information to the server
+   */
+  private async sendTerminalResize(): Promise<void> {
+    if (!this.terminal || !this.fitAddon) {
+      return;
+    }
+
+    // Get terminal dimensions
+    try {
+      // Send resize message in a format the server can understand
+      // Use relative URL based on current location
+      const baseUrl = window.location.pathname.endsWith('/') ? '.' : '.';
+      const response = await fetch(`${baseUrl}/terminal/input/${this.terminalId}`, {
+        method: 'POST',
+        body: JSON.stringify({
+          type: "resize",
+          cols: this.terminal.cols || 80, // Default to 80 if undefined
+          rows: this.terminal.rows || 24, // Default to 24 if undefined
+        }),
+        headers: {
+          'Content-Type': 'application/json'
+        }
+      });
+      
+      if (!response.ok) {
+        console.error(`Failed to send terminal resize: ${response.status} ${response.statusText}`);
+      }
+    } catch (error) {
+      console.error("Error sending terminal resize:", error);
+    }
+  }
+
+  /**
+   * Clean up resources when component is destroyed
+   */
+  public dispose(): void {
+    this.closeTerminalConnections();
+    if (this.terminal) {
+      this.terminal.dispose();
+      this.terminal = null;
+    }
+    this.fitAddon = null;
+  }
+}
diff --git a/loop/webui/src/timeline/toolcalls.ts b/loop/webui/src/timeline/toolcalls.ts
new file mode 100644
index 0000000..5df88bd
--- /dev/null
+++ b/loop/webui/src/timeline/toolcalls.ts
@@ -0,0 +1,259 @@
+/**
+ * Utility functions for rendering tool calls in the timeline
+ */
+
+import { ToolCall, TimelineMessage } from "./types";
+import { html, render } from "lit-html";
+
+/**
+ * Create a tool call card element for display in the timeline
+ * @param toolCall The tool call data to render
+ * @param toolResponse Optional tool response message if available
+ * @param toolCardId Unique ID for this tool card
+ * @returns The created tool card element
+ */
+export function createToolCallCard(
+  toolCall: ToolCall,
+  toolResponse?: TimelineMessage | null,
+  toolCardId?: string
+): HTMLElement {
+  // Create a unique ID for this tool card if not provided
+  const cardId =
+    toolCardId ||
+    `tool-card-${
+      toolCall.tool_call_id || Math.random().toString(36).substring(2, 11)
+    }`;
+
+  // Get input as compact string
+  let inputText = "";
+  try {
+    if (toolCall.input) {
+      const parsedInput = JSON.parse(toolCall.input);
+
+      // For bash commands, use a special format
+      if (toolCall.name === "bash" && parsedInput.command) {
+        inputText = parsedInput.command;
+      } else {
+        // For other tools, use the stringified JSON
+        inputText = JSON.stringify(parsedInput);
+      }
+    }
+  } catch (e) {
+    // Not valid JSON, use as-is
+    inputText = toolCall.input || "";
+  }
+
+  // Truncate input text for display
+  const displayInput =
+    inputText.length > 80 ? inputText.substring(0, 78) + "..." : inputText;
+
+  // Truncate for compact display
+  const shortInput =
+    displayInput.length > 30
+      ? displayInput.substring(0, 28) + "..."
+      : displayInput;
+
+  // Format input for expanded view
+  let formattedInput = displayInput;
+  try {
+    const parsedInput = JSON.parse(toolCall.input || "");
+    formattedInput = JSON.stringify(parsedInput, null, 2);
+  } catch (e) {
+    // Not valid JSON, use display input as-is
+  }
+
+  // Truncate result for compact display if available
+  let shortResult = "";
+  if (toolResponse && toolResponse.tool_result) {
+    shortResult =
+      toolResponse.tool_result.length > 40
+        ? toolResponse.tool_result.substring(0, 38) + "..."
+        : toolResponse.tool_result;
+  }
+
+  // State for collapsed/expanded view
+  let isCollapsed = true;
+
+  // Handler to copy text to clipboard
+  const copyToClipboard = (text: string, button: HTMLElement) => {
+    navigator.clipboard
+      .writeText(text)
+      .then(() => {
+        button.textContent = "Copied!";
+        setTimeout(() => {
+          button.textContent = "Copy";
+        }, 2000);
+      })
+      .catch((err) => {
+        console.error("Failed to copy text:", err);
+        button.textContent = "Failed";
+        setTimeout(() => {
+          button.textContent = "Copy";
+        }, 2000);
+      });
+  };
+
+  const cancelToolCall = async(tool_call_id: string, button: HTMLButtonElement) => {
+    console.log('cancelToolCall', tool_call_id, button);
+    button.innerText = 'Cancelling';
+    button.disabled = true;
+    try {
+      const response = await fetch("cancel", {
+        method: "POST",
+        headers: {
+          "Content-Type": "application/json",
+        },
+        body: JSON.stringify({tool_call_id: tool_call_id, reason: "user requested cancellation" }),
+      });
+      console.log('cancel', tool_call_id, response);
+      button.parentElement.removeChild(button);
+    } catch (e) {
+      console.error('cancel', tool_call_id,e);
+    }
+  };
+
+  // Create the container element
+  const container = document.createElement("div");
+  container.id = cardId;
+  container.className = "tool-call-card collapsed";
+
+  // Function to render the component
+  const renderComponent = () => {
+    const template = html`
+      <div
+        class="tool-call-compact-view"
+        @click=${() => {
+          isCollapsed = !isCollapsed;
+          container.classList.toggle("collapsed");
+          renderComponent();
+        }}
+      >
+        <span class="tool-call-status ${toolResponse ? "" : "spinner"}">
+          ${toolResponse ? (toolResponse.tool_error ? "❌" : "✅") : "⏳"}
+        </span>
+        <span class="tool-call-name">${toolCall.name}</span>
+        <code class="tool-call-input-preview">${shortInput}</code>
+        ${toolResponse && toolResponse.tool_result
+          ? html`<code class="tool-call-result-preview">${shortResult}</code>`
+          : ""}
+        ${toolResponse && toolResponse.elapsed !== undefined
+          ? html`<span class="tool-call-time"
+              >${(toolResponse.elapsed / 1e9).toFixed(2)}s</span
+            >`
+          : ""}
+          ${toolResponse ? "" : 
+            html`<button class="refresh-button stop-button" title="Cancel this operation" @click=${(e: Event) => {
+                e.stopPropagation(); // Don't toggle expansion when clicking cancel
+                const button = e.target as HTMLButtonElement;
+                cancelToolCall(toolCall.tool_call_id, button);
+              }}>Cancel</button>`}
+        <span class="tool-call-expand-icon">${isCollapsed ? "▼" : "▲"}</span>
+      </div>
+
+      <div class="tool-call-expanded-view">
+        <div class="tool-call-section">
+          <div class="tool-call-section-label">
+            Input:
+            <button
+              class="tool-call-copy-btn"
+              title="Copy input to clipboard"
+              @click=${(e: Event) => {
+                e.stopPropagation(); // Don't toggle expansion when clicking copy
+                const button = e.target as HTMLElement;
+                copyToClipboard(toolCall.input || displayInput, button);
+              }}
+            >
+              Copy
+            </button>
+          </div>
+          <div class="tool-call-section-content">
+            <pre class="tool-call-input">${formattedInput}</pre>
+          </div>
+        </div>
+
+        ${toolResponse && toolResponse.tool_result
+          ? html`
+              <div class="tool-call-section">
+                <div class="tool-call-section-label">
+                  Result:
+                  <button
+                    class="tool-call-copy-btn"
+                    title="Copy result to clipboard"
+                    @click=${(e: Event) => {
+                      e.stopPropagation(); // Don't toggle expansion when clicking copy
+                      const button = e.target as HTMLElement;
+                      copyToClipboard(toolResponse.tool_result || "", button);
+                    }}
+                  >
+                    Copy
+                  </button>
+                </div>
+                <div class="tool-call-section-content">
+                  <div class="tool-call-result">
+                    ${toolResponse.tool_result.includes("\n")
+                      ? html`<pre><code>${toolResponse.tool_result}</code></pre>`
+                      : toolResponse.tool_result}
+                  </div>
+                </div>
+              </div>
+            `
+          : ""}
+      </div>
+    `;
+
+    render(template, container);
+  };
+
+  // Initial render
+  renderComponent();
+
+  return container;
+}
+
+/**
+ * Update a tool call card with response data
+ * @param toolCard The tool card element to update
+ * @param toolMessage The tool response message
+ */
+export function updateToolCallCard(
+  toolCard: HTMLElement,
+  toolMessage: TimelineMessage
+): void {
+  if (!toolCard) return;
+
+  // Find the original tool call data to reconstruct the card
+  const toolName = toolCard.querySelector(".tool-call-name")?.textContent || "";
+  const inputPreview =
+    toolCard.querySelector(".tool-call-input-preview")?.textContent || "";
+
+  // Extract the original input from the expanded view
+  let originalInput = "";
+  const inputEl = toolCard.querySelector(".tool-call-input");
+  if (inputEl) {
+    originalInput = inputEl.textContent || "";
+  }
+
+  // Create a minimal ToolCall object from the existing data
+  const toolCall: Partial<ToolCall> = {
+    name: toolName,
+    // Try to reconstruct the original input if possible
+    input: originalInput,
+  };
+
+  // Replace the existing card with a new one
+  const newCard = createToolCallCard(
+    toolCall as ToolCall,
+    toolMessage,
+    toolCard.id
+  );
+
+  // Preserve the collapse state
+  if (!toolCard.classList.contains("collapsed")) {
+    newCard.classList.remove("collapsed");
+  }
+
+  // Replace the old card with the new one
+  if (toolCard.parentNode) {
+    toolCard.parentNode.replaceChild(newCard, toolCard);
+  }
+}
diff --git a/loop/webui/src/timeline/types.ts b/loop/webui/src/timeline/types.ts
new file mode 100644
index 0000000..81d47d0
--- /dev/null
+++ b/loop/webui/src/timeline/types.ts
@@ -0,0 +1,49 @@
+/**
+ * Interface for a Git commit
+ */
+export interface GitCommit {
+  hash: string; // Full commit hash
+  subject: string; // Commit subject line
+  body: string; // Full commit message body
+  pushed_branch?: string; // If set, this commit was pushed to this branch
+}
+
+/**
+ * Interface for a tool call
+ */
+export interface ToolCall {
+  name: string;
+  args?: string;
+  result?: string;
+  input?: string; // Input property for TypeScript compatibility
+  tool_call_id?: string;
+}
+
+/**
+ * Interface for a timeline message
+ */
+export interface TimelineMessage {
+  type: string;
+  content?: string;
+  timestamp?: string | number | Date;
+  elapsed?: number;
+  turnDuration?: number; // Turn duration field
+  end_of_turn?: boolean;
+  conversation_id?: string;
+  parent_conversation_id?: string;
+  tool_calls?: ToolCall[];
+  tool_name?: string;
+  tool_error?: boolean;
+  tool_call_id?: string;
+  commits?: GitCommit[]; // For commit messages
+  input?: string; // Input property
+  tool_result?: string; // Tool result property
+  toolResponses?: any[]; // Tool responses array
+  usage?: {
+    input_tokens?: number;
+    output_tokens?: number;
+    cache_read_input_tokens?: number;
+    cache_creation_input_tokens?: number;
+    cost_usd?: number;
+  };
+}
diff --git a/loop/webui/src/timeline/utils.ts b/loop/webui/src/timeline/utils.ts
new file mode 100644
index 0000000..ff505f9
--- /dev/null
+++ b/loop/webui/src/timeline/utils.ts
@@ -0,0 +1,50 @@
+/**
+ * Escapes HTML special characters in a string
+ */
+export function escapeHTML(str: string): string {
+  return str
+    .replace(/&/g, "&amp;")
+    .replace(/</g, "&lt;")
+    .replace(/>/g, "&gt;")
+    .replace(/"/g, "&quot;")
+    .replace(/'/g, "&#039;");
+}
+
+/**
+ * Formats a number with locale-specific formatting
+ */
+export function formatNumber(
+  num: number | null | undefined,
+  defaultValue: string = "0",
+): string {
+  if (num === undefined || num === null) return defaultValue;
+  try {
+    return num.toLocaleString();
+  } catch (e) {
+    return String(num);
+  }
+}
+
+/**
+ * Generates a consistent color based on an ID string
+ */
+export function generateColorFromId(id: string | null | undefined): string {
+  if (!id) return "#7c7c7c"; // Default color for null/undefined
+
+  // Generate a hash from the ID
+  let hash = 0;
+  for (let i = 0; i < id.length; i++) {
+    hash = id.charCodeAt(i) + ((hash << 5) - hash);
+  }
+
+  // Convert hash to a hex color
+  let color = "#";
+  for (let i = 0; i < 3; i++) {
+    // Generate more muted colors by using only part of the range
+    // and adding a base value to avoid very dark colors
+    const value = ((hash >> (i * 8)) & 0xff);
+    const scaledValue = Math.floor(100 + (value * 100) / 255); // Range 100-200 for more muted colors
+    color += scaledValue.toString(16).padStart(2, "0");
+  }
+  return color;
+}
