diff --git a/loop/webui/src/timeline.ts b/loop/webui/src/timeline.ts
new file mode 100644
index 0000000..eef2726
--- /dev/null
+++ b/loop/webui/src/timeline.ts
@@ -0,0 +1,641 @@
+import { TimelineMessage } from "./timeline/types";
+import { formatNumber } from "./timeline/utils";
+import { checkShouldScroll } from "./timeline/scroll";
+import { ChartManager } from "./timeline/charts";
+import { ConnectionStatus, DataManager } from "./timeline/data";
+import { DiffViewer } from "./timeline/diffviewer";
+import { MessageRenderer } from "./timeline/renderer";
+import { TerminalHandler } from "./timeline/terminal";
+
+/**
+ * TimelineManager - Class to manage the timeline UI and functionality
+ */
+class TimelineManager {
+  private diffViewer = new DiffViewer();
+  private terminalHandler = new TerminalHandler();
+  private chartManager = new ChartManager();
+  private messageRenderer = new MessageRenderer();
+  private dataManager = new DataManager();
+
+  private viewMode: "chat" | "diff2" | "charts" | "terminal" = "chat";
+  shouldScrollToBottom: boolean;
+
+  constructor() {
+    // Initialize when DOM is ready
+    document.addEventListener("DOMContentLoaded", () => {
+      // First initialize from URL params to prevent flash of incorrect view
+      // This must happen before setting up other event handlers
+      void this.initializeViewFromUrl()
+        .then(() => {
+          // Continue with the rest of initialization
+          return this.initialize();
+        })
+        .catch((err) => {
+          console.error("Failed to initialize timeline:", err);
+        });
+    });
+
+    // Add popstate event listener to handle browser back/forward navigation
+    window.addEventListener("popstate", (event) => {
+      if (event.state && event.state.mode) {
+        // Using void to handle the promise returned by toggleViewMode
+        void this.toggleViewMode(event.state.mode);
+      } else {
+        // If no state or no mode in state, default to chat view
+        void this.toggleViewMode("chat");
+      }
+    });
+
+    // Listen for commit diff event from MessageRenderer
+    document.addEventListener("showCommitDiff", ((e: CustomEvent) => {
+      const { commitHash } = e.detail;
+      this.diffViewer.showCommitDiff(
+        commitHash,
+        (mode: "chat" | "diff2" | "terminal" | "charts") =>
+          this.toggleViewMode(mode)
+      );
+    }) as EventListener);
+  }
+
+  /**
+   * Initialize the timeline manager
+   */
+  private async initialize(): Promise<void> {
+    // Set up data manager event listeners
+    this.dataManager.addEventListener(
+      "dataChanged",
+      this.handleDataChanged.bind(this)
+    );
+    this.dataManager.addEventListener(
+      "connectionStatusChanged",
+      this.handleConnectionStatusChanged.bind(this)
+    );
+
+    // Initialize the data manager
+    await this.dataManager.initialize();
+
+    // URL parameters have already been read in constructor
+    // to prevent flash of incorrect content
+
+    // Set up conversation button handler
+    document
+      .getElementById("showConversationButton")
+      ?.addEventListener("click", async () => {
+        this.toggleViewMode("chat");
+      });
+
+    // Set up diff2 button handler
+    document
+      .getElementById("showDiff2Button")
+      ?.addEventListener("click", async () => {
+        this.toggleViewMode("diff2");
+      });
+
+    // Set up charts button handler
+    document
+      .getElementById("showChartsButton")
+      ?.addEventListener("click", async () => {
+        this.toggleViewMode("charts");
+      });
+
+    // Set up terminal button handler
+    document
+      .getElementById("showTerminalButton")
+      ?.addEventListener("click", async () => {
+        this.toggleViewMode("terminal");
+      });
+
+    // The active button will be set by toggleViewMode
+    // We'll initialize view based on URL params or default to chat view if no params
+    // We defer button activation to the toggleViewMode function
+
+    // Set up stop button handler
+    document
+      .getElementById("stopButton")
+      ?.addEventListener("click", async () => {
+        this.stopInnerLoop();
+      });
+
+    const pollToggleCheckbox = document.getElementById(
+      "pollToggle"
+    ) as HTMLInputElement;
+    pollToggleCheckbox?.addEventListener("change", () => {
+      this.dataManager.setPollingEnabled(pollToggleCheckbox.checked);
+      const statusText = document.getElementById("statusText");
+      if (statusText) {
+        if (pollToggleCheckbox.checked) {
+          statusText.textContent = "Polling for updates...";
+        } else {
+          statusText.textContent = "Polling stopped";
+        }
+      }
+    });
+
+    // Initial data fetch and polling is now handled by the DataManager
+
+    // Set up chat functionality
+    this.setupChatBox();
+
+    // Set up keyboard shortcuts
+    this.setupKeyboardShortcuts();
+
+    // Set up spacing adjustments
+    this.adjustChatSpacing();
+    window.addEventListener("resize", () => this.adjustChatSpacing());
+  }
+
+  /**
+   * Set up chat box event listeners
+   */
+  private setupChatBox(): void {
+    const chatInput = document.getElementById(
+      "chatInput"
+    ) as HTMLTextAreaElement;
+    const sendButton = document.getElementById("sendChatButton");
+
+    // Handle pressing Enter in the text area
+    chatInput?.addEventListener("keydown", (event: KeyboardEvent) => {
+      // Send message if Enter is pressed without Shift key
+      if (event.key === "Enter" && !event.shiftKey) {
+        event.preventDefault(); // Prevent default newline
+        this.sendChatMessage();
+      }
+    });
+
+    // Handle send button click
+    sendButton?.addEventListener("click", () => this.sendChatMessage());
+
+    // Set up mutation observer for the chat container
+    if (chatInput) {
+      chatInput.addEventListener("input", () => {
+        // When content changes, adjust the spacing
+        requestAnimationFrame(() => this.adjustChatSpacing());
+      });
+    }
+  }
+
+  /**
+   * Send the chat message to the server
+   */
+  private async sendChatMessage(): Promise<void> {
+    const chatInput = document.getElementById(
+      "chatInput"
+    ) as HTMLTextAreaElement;
+    if (!chatInput) return;
+
+    const message = chatInput.value.trim();
+
+    // Don't send empty messages
+    if (!message) return;
+
+    try {
+      // Send the message to the server
+      const response = await fetch("chat", {
+        method: "POST",
+        headers: {
+          "Content-Type": "application/json",
+        },
+        body: JSON.stringify({ message }),
+      });
+
+      if (!response.ok) {
+        const errorData = await response.text();
+        throw new Error(`Server error: ${response.status} - ${errorData}`);
+      }
+
+      // Clear the input after sending
+      chatInput.value = "";
+
+      // Reset data manager state to force a full refresh after sending a message
+      // This ensures we get all messages in the correct order
+      // Use private API for now - TODO: add a resetState() method to DataManager
+      (this.dataManager as any).nextFetchIndex = 0;
+      (this.dataManager as any).currentFetchStartIndex = 0;
+
+      // If in diff view, switch to conversation view
+      if (this.viewMode === "diff2") {
+        await this.toggleViewMode("chat");
+      }
+
+      // Refresh the timeline data to show the new message
+      await this.dataManager.fetchData();
+    } catch (error) {
+      console.error("Error sending chat message:", error);
+      const statusText = document.getElementById("statusText");
+      if (statusText) {
+        statusText.textContent = "Error sending message";
+      }
+    }
+  }
+
+  /**
+   * Handle data changed event from the data manager
+   */
+  private handleDataChanged(eventData: {
+    state: any;
+    newMessages: TimelineMessage[];
+    isFirstFetch?: boolean;
+  }): void {
+    const { state, newMessages, isFirstFetch } = eventData;
+
+    // Check if we should scroll to bottom BEFORE handling new data
+    this.shouldScrollToBottom = this.checkShouldScroll();
+
+    // Update state info in the UI
+    this.updateUIWithState(state);
+
+    // Update the timeline if there are new messages
+    if (newMessages.length > 0) {
+      // Initialize the message renderer with current state
+      this.messageRenderer.initialize(
+        this.dataManager.getIsFirstLoad(),
+        this.dataManager.getCurrentFetchStartIndex()
+      );
+
+      this.messageRenderer.renderTimeline(newMessages, isFirstFetch || false);
+
+      // Update chart data using our full messages array
+      this.chartManager.setChartData(
+        this.chartManager.calculateCumulativeCostData(
+          this.dataManager.getMessages()
+        )
+      );
+
+      // If in charts view, update the charts
+      if (this.viewMode === "charts") {
+        this.chartManager.renderCharts();
+      }
+
+      const statusTextEl = document.getElementById("statusText");
+      if (statusTextEl) {
+        statusTextEl.textContent = "Updated just now";
+      }
+    } else {
+      const statusTextEl = document.getElementById("statusText");
+      if (statusTextEl) {
+        statusTextEl.textContent = "No new messages";
+      }
+    }
+  }
+
+  /**
+   * Handle connection status changed event from the data manager
+   */
+  private handleConnectionStatusChanged(
+    status: ConnectionStatus,
+    errorMessage?: string
+  ): void {
+    const pollingIndicator = document.getElementById("pollingIndicator");
+    if (!pollingIndicator) return;
+
+    // Remove all status classes
+    pollingIndicator.classList.remove("active", "error");
+
+    // Add appropriate class based on status
+    if (status === "connected") {
+      pollingIndicator.classList.add("active");
+    } else if (status === "disconnected") {
+      pollingIndicator.classList.add("error");
+    }
+
+    // Update status text if error message is provided
+    if (errorMessage) {
+      const statusTextEl = document.getElementById("statusText");
+      if (statusTextEl) {
+        statusTextEl.textContent = errorMessage;
+      }
+    }
+  }
+
+  /**
+   * Update UI elements with state data
+   */
+  private updateUIWithState(state: any): void {
+    // Update state info in the UI with safe getters
+    const hostnameEl = document.getElementById("hostname");
+    if (hostnameEl) {
+      hostnameEl.textContent = state?.hostname ?? "Unknown";
+    }
+
+    const workingDirEl = document.getElementById("workingDir");
+    if (workingDirEl) {
+      workingDirEl.textContent = state?.working_dir ?? "Unknown";
+    }
+
+    const initialCommitEl = document.getElementById("initialCommit");
+    if (initialCommitEl) {
+      initialCommitEl.textContent = state?.initial_commit
+        ? state.initial_commit.substring(0, 8)
+        : "Unknown";
+    }
+
+    const messageCountEl = document.getElementById("messageCount");
+    if (messageCountEl) {
+      messageCountEl.textContent = state?.message_count ?? "0";
+    }
+
+    const chatTitleEl = document.getElementById("chatTitle");
+    const bannerTitleEl = document.querySelector(".banner-title");
+
+    if (chatTitleEl && bannerTitleEl) {
+      if (state?.title) {
+        chatTitleEl.textContent = state.title;
+        chatTitleEl.style.display = "block";
+        bannerTitleEl.textContent = "sketch"; // Shorten title when chat title exists
+      } else {
+        chatTitleEl.style.display = "none";
+        bannerTitleEl.textContent = "sketch coding assistant"; // Full title when no chat title
+      }
+    }
+
+    // Get token and cost info safely
+    const inputTokens = state?.total_usage?.input_tokens ?? 0;
+    const outputTokens = state?.total_usage?.output_tokens ?? 0;
+    const cacheReadInputTokens =
+      state?.total_usage?.cache_read_input_tokens ?? 0;
+    const cacheCreationInputTokens =
+      state?.total_usage?.cache_creation_input_tokens ?? 0;
+    const totalCost = state?.total_usage?.total_cost_usd ?? 0;
+
+    const inputTokensEl = document.getElementById("inputTokens");
+    if (inputTokensEl) {
+      inputTokensEl.textContent = formatNumber(inputTokens, "0");
+    }
+
+    const outputTokensEl = document.getElementById("outputTokens");
+    if (outputTokensEl) {
+      outputTokensEl.textContent = formatNumber(outputTokens, "0");
+    }
+
+    const cacheReadInputTokensEl = document.getElementById(
+      "cacheReadInputTokens"
+    );
+    if (cacheReadInputTokensEl) {
+      cacheReadInputTokensEl.textContent = formatNumber(
+        cacheReadInputTokens,
+        "0"
+      );
+    }
+
+    const cacheCreationInputTokensEl = document.getElementById(
+      "cacheCreationInputTokens"
+    );
+    if (cacheCreationInputTokensEl) {
+      cacheCreationInputTokensEl.textContent = formatNumber(
+        cacheCreationInputTokens,
+        "0"
+      );
+    }
+
+    const totalCostEl = document.getElementById("totalCost");
+    if (totalCostEl) {
+      totalCostEl.textContent = `$${totalCost.toFixed(2)}`;
+    }
+  }
+
+  /**
+   * Check if we should scroll to the bottom
+   */
+  private checkShouldScroll(): boolean {
+    return checkShouldScroll(this.dataManager.getIsFirstLoad());
+  }
+
+  /**
+   * Dynamically adjust body padding based on the chat container height and top banner
+   */
+  private adjustChatSpacing(): void {
+    const chatContainer = document.querySelector(".chat-container");
+    const topBanner = document.querySelector(".top-banner");
+
+    if (chatContainer) {
+      const chatHeight = (chatContainer as HTMLElement).offsetHeight;
+      document.body.style.paddingBottom = `${chatHeight + 20}px`; // 20px extra for spacing
+    }
+
+    if (topBanner) {
+      const topHeight = (topBanner as HTMLElement).offsetHeight;
+      document.body.style.paddingTop = `${topHeight + 20}px`; // 20px extra for spacing
+    }
+  }
+
+  /**
+   * Set up keyboard shortcuts
+   */
+  private setupKeyboardShortcuts(): void {
+    // Add keyboard shortcut to automatically copy selected text with Ctrl+C (or Command+C on Mac)
+    document.addEventListener("keydown", (e: KeyboardEvent) => {
+      // We only want to handle Ctrl+C or Command+C
+      if ((e.ctrlKey || e.metaKey) && e.key === "c") {
+        // If text is already selected, we don't need to do anything special
+        // as the browser's default behavior will handle copying
+        // But we could add additional behavior here if needed
+      }
+    });
+  }
+
+  /**
+   * Toggle between different view modes: chat, diff2, charts
+   */
+  public async toggleViewMode(
+    mode: "chat" | "diff2" | "charts" | "terminal"
+  ): Promise<void> {
+    // Set the new view mode
+    this.viewMode = mode;
+
+    // Update URL with the current view mode
+    this.updateUrlForViewMode(mode);
+
+    // Get DOM elements
+    const timeline = document.getElementById("timeline");
+    const diff2View = document.getElementById("diff2View");
+    const chartView = document.getElementById("chartView");
+    const container = document.querySelector(".timeline-container");
+    const terminalView = document.getElementById("terminalView");
+    const conversationButton = document.getElementById(
+      "showConversationButton"
+    );
+    const diff2Button = document.getElementById("showDiff2Button");
+    const chartsButton = document.getElementById("showChartsButton");
+    const terminalButton = document.getElementById("showTerminalButton");
+
+    if (
+      !timeline ||
+      !diff2View ||
+      !chartView ||
+      !container ||
+      !conversationButton ||
+      !diff2Button ||
+      !chartsButton ||
+      !terminalView ||
+      !terminalButton
+    ) {
+      console.error("Required DOM elements not found");
+      return;
+    }
+
+    // Hide all views first
+    timeline.style.display = "none";
+    diff2View.style.display = "none";
+    chartView.style.display = "none";
+    terminalView.style.display = "none";
+
+    // Reset all button states
+    conversationButton.classList.remove("active");
+    diff2Button.classList.remove("active");
+    chartsButton.classList.remove("active");
+    terminalButton.classList.remove("active");
+
+    // Remove diff2-active and diff-active classes from container
+    container.classList.remove("diff2-active");
+    container.classList.remove("diff-active");
+
+    // If switching to chat view, clear the current commit hash
+    if (mode === "chat") {
+      this.diffViewer.clearCurrentCommitHash();
+    }
+
+    // Add class to indicate views are initialized (prevents flash of content)
+    container.classList.add("view-initialized");
+
+    // Show the selected view based on mode
+    switch (mode) {
+      case "chat":
+        timeline.style.display = "block";
+        conversationButton.classList.add("active");
+        break;
+      case "diff2":
+        diff2View.style.display = "block";
+        diff2Button.classList.add("active");
+        this.diffViewer.setViewMode(mode); // Update view mode in diff viewer
+        await this.diffViewer.loadDiff2HtmlContent();
+        break;
+      case "charts":
+        chartView.style.display = "block";
+        chartsButton.classList.add("active");
+        await this.chartManager.renderCharts();
+        break;
+      case "terminal":
+        terminalView.style.display = "block";
+        terminalButton.classList.add("active");
+        this.terminalHandler.setViewMode(mode); // Update view mode in terminal handler
+        this.diffViewer.setViewMode(mode); // Update view mode in diff viewer
+        await this.initializeTerminal();
+        break;
+    }
+  }
+
+  /**
+   * Initialize the terminal view
+   */
+  private async initializeTerminal(): Promise<void> {
+    // Use the TerminalHandler to initialize the terminal
+    await this.terminalHandler.initializeTerminal();
+  }
+
+  /**
+   * Initialize the view based on URL parameters
+   * This allows bookmarking and sharing of specific views
+   */
+  private async initializeViewFromUrl(): Promise<void> {
+    // Parse the URL parameters
+    const urlParams = new URLSearchParams(window.location.search);
+    const viewParam = urlParams.get("view");
+    const commitParam = urlParams.get("commit");
+
+    // Default to chat view if no valid view parameter is provided
+    if (!viewParam) {
+      // Explicitly set chat view to ensure button state is correct
+      await this.toggleViewMode("chat");
+      return;
+    }
+
+    // Check if the view parameter is valid
+    if (
+      viewParam === "chat" ||
+      viewParam === "diff2" ||
+      viewParam === "charts" ||
+      viewParam === "terminal"
+    ) {
+      // If it's a diff view with a commit hash, set the commit hash
+      if (viewParam === "diff2" && commitParam) {
+        this.diffViewer.setCurrentCommitHash(commitParam);
+      }
+
+      // Set the view mode
+      await this.toggleViewMode(
+        viewParam as "chat" | "diff2" | "charts" | "terminal"
+      );
+    }
+  }
+
+  /**
+   * Update URL to reflect current view mode for bookmarking and sharing
+   * @param mode The current view mode
+   */
+  private updateUrlForViewMode(
+    mode: "chat" | "diff2" | "charts" | "terminal"
+  ): void {
+    // Get the current URL without search parameters
+    const url = new URL(window.location.href);
+
+    // Clear existing parameters
+    url.search = "";
+
+    // Only add view parameter if not in default chat view
+    if (mode !== "chat") {
+      url.searchParams.set("view", mode);
+
+      // If in diff view and there's a commit hash, include that too
+      if (mode === "diff2" && this.diffViewer.getCurrentCommitHash()) {
+        url.searchParams.set("commit", this.diffViewer.getCurrentCommitHash());
+      }
+    }
+
+    // Update the browser history without reloading the page
+    window.history.pushState({ mode }, "", url.toString());
+  }
+
+  /**
+   * Stop the inner loop by calling the /cancel endpoint
+   */
+  private async stopInnerLoop(): Promise<void> {
+    if (!confirm("Are you sure you want to stop the current operation?")) {
+      return;
+    }
+
+    try {
+      const statusText = document.getElementById("statusText");
+      if (statusText) {
+        statusText.textContent = "Cancelling...";
+      }
+
+      const response = await fetch("cancel", {
+        method: "POST",
+        headers: {
+          "Content-Type": "application/json",
+        },
+        body: JSON.stringify({ reason: "User requested cancellation via UI" }),
+      });
+
+      if (!response.ok) {
+        const errorData = await response.text();
+        throw new Error(`Server error: ${response.status} - ${errorData}`);
+      }
+
+      // Parse the response
+      const _result = await response.json();
+      if (statusText) {
+        statusText.textContent = "Operation cancelled";
+      }
+    } catch (error) {
+      console.error("Error cancelling operation:", error);
+      const statusText = document.getElementById("statusText");
+      if (statusText) {
+        statusText.textContent = "Error cancelling operation";
+      }
+    }
+  }
+}
+
+// Create and initialize the timeline manager when the page loads
+const _timelineManager = new TimelineManager();
