diff --git a/webui/src/web-components/sketch-app-shell-base.ts b/webui/src/web-components/sketch-app-shell-base.ts
new file mode 100644
index 0000000..07ce713
--- /dev/null
+++ b/webui/src/web-components/sketch-app-shell-base.ts
@@ -0,0 +1,1128 @@
+import { css, html, LitElement } from "lit";
+import { customElement, property, state } from "lit/decorators.js";
+import { ConnectionStatus, DataManager } from "../data";
+import { AgentMessage, GitLogEntry, State } from "../types";
+import { aggregateAgentMessages } from "./aggregateAgentMessages";
+import { SketchTailwindElement } from "./sketch-tailwind-element";
+
+import "./sketch-chat-input";
+import "./sketch-container-status";
+
+import "./sketch-diff2-view";
+import { SketchDiff2View } from "./sketch-diff2-view";
+import { DefaultGitDataService } from "./git-data-service";
+import "./sketch-monaco-view";
+import "./sketch-network-status";
+import "./sketch-call-status";
+import "./sketch-terminal";
+import "./sketch-timeline";
+import "./sketch-view-mode-select";
+import "./sketch-todo-panel";
+
+import { createRef, ref } from "lit/directives/ref.js";
+import { SketchChatInput } from "./sketch-chat-input";
+
+type ViewMode = "chat" | "diff2" | "terminal";
+
+// Base class for sketch app shells - contains shared logic
+export abstract class SketchAppShellBase extends SketchTailwindElement {
+  // Current view mode (chat, diff, terminal)
+  @state()
+  viewMode: ViewMode = "chat";
+
+  // Current commit hash for diff view
+  @state()
+  currentCommitHash: string = "";
+
+  // Last commit information
+  @state()
+
+  // Reference to the container status element
+  containerStatusElement: any = null;
+
+  // Note: CSS styles have been converted to Tailwind classes applied directly to HTML elements
+  // since this component now extends SketchTailwindElement which disables shadow DOM
+
+  // Override createRenderRoot to apply host styles for proper sizing while still using light DOM
+  createRenderRoot() {
+    // Use light DOM like SketchTailwindElement but still apply host styles
+    const style = document.createElement("style");
+    style.textContent = `
+      sketch-app-shell {
+        display: block;
+        width: 100%;
+        height: 100vh;
+        max-width: 100%;
+        box-sizing: border-box;
+        overflow: hidden;
+      }
+    `;
+
+    // Add the style to the document head if not already present
+    if (!document.head.querySelector("style[data-sketch-app-shell]")) {
+      style.setAttribute("data-sketch-app-shell", "");
+      document.head.appendChild(style);
+    }
+
+    return this;
+  }
+
+  // Header bar: Network connection status details
+  @property()
+  connectionStatus: ConnectionStatus = "disconnected";
+
+  // Track if the last commit info has been copied
+  @state()
+  // lastCommitCopied moved to sketch-container-status
+
+  // Track notification preferences
+  @state()
+  notificationsEnabled: boolean = false;
+
+  // Track if the window is focused to control notifications
+  @state()
+  private _windowFocused: boolean = document.hasFocus();
+
+  // Track if the todo panel should be visible
+  @state()
+  protected _todoPanelVisible: boolean = false;
+
+  // Store scroll position for the chat view to preserve it when switching tabs
+  @state()
+  private _chatScrollPosition: number = 0;
+
+  // ResizeObserver for tracking chat input height changes
+  private chatInputResizeObserver: ResizeObserver | null = null;
+
+  @property()
+  connectionErrorMessage: string = "";
+
+  // Chat messages
+  @property({ attribute: false })
+  messages: AgentMessage[] = [];
+
+  @property()
+  set slug(value: string) {
+    const oldValue = this._slug;
+    this._slug = value;
+    this.requestUpdate("slug", oldValue);
+    // Update document title when slug property changes
+    this.updateDocumentTitle();
+  }
+
+  get slug(): string {
+    return this._slug;
+  }
+
+  private _slug: string = "";
+
+  private dataManager = new DataManager();
+
+  @property({ attribute: false })
+  containerState: State = {
+    state_version: 2,
+    slug: "",
+    os: "",
+    message_count: 0,
+    hostname: "",
+    working_dir: "",
+    initial_commit: "",
+    outstanding_llm_calls: 0,
+    outstanding_tool_calls: [],
+    session_id: "",
+    ssh_available: false,
+    ssh_error: "",
+    in_container: false,
+    first_message_index: 0,
+    diff_lines_added: 0,
+    diff_lines_removed: 0,
+  };
+
+  // Mutation observer to detect when new messages are added
+  private mutationObserver: MutationObserver | null = null;
+
+  constructor() {
+    super();
+
+    // Reference to the container status element
+    this.containerStatusElement = null;
+
+    // Binding methods to this
+    this._handleViewModeSelect = this._handleViewModeSelect.bind(this);
+    this._handlePopState = this._handlePopState.bind(this);
+    this._handleShowCommitDiff = this._handleShowCommitDiff.bind(this);
+    this._handleMutlipleChoiceSelected =
+      this._handleMutlipleChoiceSelected.bind(this);
+    this._handleStopClick = this._handleStopClick.bind(this);
+    this._handleEndClick = this._handleEndClick.bind(this);
+    this._handleNotificationsToggle =
+      this._handleNotificationsToggle.bind(this);
+    this._handleWindowFocus = this._handleWindowFocus.bind(this);
+    this._handleWindowBlur = this._handleWindowBlur.bind(this);
+
+    // Load notification preference from localStorage
+    try {
+      const savedPref = localStorage.getItem("sketch-notifications-enabled");
+      if (savedPref !== null) {
+        this.notificationsEnabled = savedPref === "true";
+      }
+    } catch (error) {
+      console.error("Error loading notification preference:", error);
+    }
+  }
+
+  // See https://lit.dev/docs/components/lifecycle/
+  connectedCallback() {
+    super.connectedCallback();
+
+    // Get reference to the container status element
+    setTimeout(() => {
+      this.containerStatusElement =
+        this.shadowRoot?.getElementById("container-status");
+    }, 0);
+
+    // Initialize client-side nav history.
+    const url = new URL(window.location.href);
+    const mode = url.searchParams.get("view") || "chat";
+    window.history.replaceState({ mode }, "", url.toString());
+
+    this.toggleViewMode(mode as ViewMode, false);
+    // Add popstate event listener to handle browser back/forward navigation
+    window.addEventListener("popstate", this._handlePopState);
+
+    // Add event listeners
+    window.addEventListener("view-mode-select", this._handleViewModeSelect);
+    window.addEventListener("show-commit-diff", this._handleShowCommitDiff);
+
+    // Add window focus/blur listeners for controlling notifications
+    window.addEventListener("focus", this._handleWindowFocus);
+    window.addEventListener("blur", this._handleWindowBlur);
+    window.addEventListener(
+      "multiple-choice-selected",
+      this._handleMutlipleChoiceSelected,
+    );
+
+    // register event listeners
+    this.dataManager.addEventListener(
+      "dataChanged",
+      this.handleDataChanged.bind(this),
+    );
+    this.dataManager.addEventListener(
+      "connectionStatusChanged",
+      this.handleConnectionStatusChanged.bind(this),
+    );
+
+    // Set initial document title
+    this.updateDocumentTitle();
+
+    // Initialize the data manager
+    this.dataManager.initialize();
+
+    // Process existing messages for commit info
+    if (this.messages && this.messages.length > 0) {
+      // Update last commit info via container status component
+      setTimeout(() => {
+        if (this.containerStatusElement) {
+          this.containerStatusElement.updateLastCommitInfo(this.messages);
+        }
+      }, 100);
+    }
+
+    // Check if todo panel should be visible on initial load
+    this.checkTodoPanelVisibility();
+
+    // Set up ResizeObserver for chat input to update todo panel height
+    this.setupChatInputObserver();
+  }
+
+  // See https://lit.dev/docs/components/lifecycle/
+  disconnectedCallback() {
+    super.disconnectedCallback();
+    window.removeEventListener("popstate", this._handlePopState);
+
+    // Remove event listeners
+    window.removeEventListener("view-mode-select", this._handleViewModeSelect);
+    window.removeEventListener("show-commit-diff", this._handleShowCommitDiff);
+    window.removeEventListener("focus", this._handleWindowFocus);
+    window.removeEventListener("blur", this._handleWindowBlur);
+    window.removeEventListener(
+      "multiple-choice-selected",
+      this._handleMutlipleChoiceSelected,
+    );
+
+    // unregister data manager event listeners
+    this.dataManager.removeEventListener(
+      "dataChanged",
+      this.handleDataChanged.bind(this),
+    );
+    this.dataManager.removeEventListener(
+      "connectionStatusChanged",
+      this.handleConnectionStatusChanged.bind(this),
+    );
+
+    // Disconnect mutation observer if it exists
+    if (this.mutationObserver) {
+      this.mutationObserver.disconnect();
+      this.mutationObserver = null;
+    }
+
+    // Disconnect chat input resize observer if it exists
+    if (this.chatInputResizeObserver) {
+      this.chatInputResizeObserver.disconnect();
+      this.chatInputResizeObserver = null;
+    }
+  }
+
+  updateUrlForViewMode(mode: ViewMode): 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);
+      const diff2View = this.shadowRoot?.querySelector(
+        "sketch-diff2-view",
+      ) as SketchDiff2View;
+
+      // If in diff2 view and there's a commit hash, include that too
+      if (mode === "diff2" && diff2View?.commit) {
+        url.searchParams.set("commit", diff2View.commit);
+      }
+    }
+
+    // Update the browser history without reloading the page
+    window.history.pushState({ mode }, "", url.toString());
+  }
+
+  private _handlePopState(event: PopStateEvent) {
+    if (event.state && event.state.mode) {
+      this.toggleViewMode(event.state.mode, false);
+    } else {
+      this.toggleViewMode("chat", false);
+    }
+  }
+
+  /**
+   * Handle view mode selection event
+   */
+  private _handleViewModeSelect(event: CustomEvent) {
+    const mode = event.detail.mode as "chat" | "diff2" | "terminal";
+    this.toggleViewMode(mode, true);
+  }
+
+  /**
+   * Handle show commit diff event
+   */
+  private _handleShowCommitDiff(event: CustomEvent) {
+    const { commitHash } = event.detail;
+    if (commitHash) {
+      this.showCommitDiff(commitHash);
+    }
+  }
+
+  private _handleMultipleChoice(event: CustomEvent) {
+    window.console.log("_handleMultipleChoice", event);
+    this._sendChat;
+  }
+
+  private _handleDiffComment(event: CustomEvent) {
+    // Empty stub required by the event binding in the template
+    // Actual handling occurs at global level in sketch-chat-input component
+  }
+  /**
+   * Listen for commit diff event
+   * @param commitHash The commit hash to show diff for
+   */
+  private showCommitDiff(commitHash: string): void {
+    // Store the commit hash
+    this.currentCommitHash = commitHash;
+
+    this.toggleViewMode("diff2", true);
+
+    this.updateComplete.then(() => {
+      const diff2View = this.shadowRoot?.querySelector("sketch-diff2-view");
+      if (diff2View) {
+        (diff2View as SketchDiff2View).refreshDiffView();
+      }
+    });
+  }
+
+  /**
+   * Toggle between different view modes: chat, diff2, terminal
+   */
+  private toggleViewMode(mode: ViewMode, updateHistory: boolean): void {
+    // Don't do anything if the mode is already active
+    if (this.viewMode === mode) return;
+
+    // Store scroll position if we're leaving the chat view
+    if (this.viewMode === "chat" && this.scrollContainerRef.value) {
+      // Only store scroll position if we actually have meaningful content
+      const scrollTop = this.scrollContainerRef.value.scrollTop;
+      const scrollHeight = this.scrollContainerRef.value.scrollHeight;
+      const clientHeight = this.scrollContainerRef.value.clientHeight;
+
+      // Store position only if we have scrollable content and have actually scrolled
+      if (scrollHeight > clientHeight && scrollTop > 0) {
+        this._chatScrollPosition = scrollTop;
+      }
+    }
+
+    // Update the view mode
+    this.viewMode = mode;
+
+    if (updateHistory) {
+      // Update URL with the current view mode
+      this.updateUrlForViewMode(mode);
+    }
+
+    // Wait for DOM update to complete
+    this.updateComplete.then(() => {
+      // Handle scroll position restoration for chat view
+      if (
+        mode === "chat" &&
+        this.scrollContainerRef.value &&
+        this._chatScrollPosition > 0
+      ) {
+        // Use requestAnimationFrame to ensure DOM is ready
+        requestAnimationFrame(() => {
+          if (this.scrollContainerRef.value) {
+            // Double-check that we're still in chat mode and the container is available
+            if (
+              this.viewMode === "chat" &&
+              this.scrollContainerRef.value.isConnected
+            ) {
+              this.scrollContainerRef.value.scrollTop =
+                this._chatScrollPosition;
+            }
+          }
+        });
+      }
+
+      // Handle diff2 view specific logic
+      if (mode === "diff2") {
+        // Refresh git/recentlog when Monaco diff view is opened
+        // This ensures branch information is always up-to-date, as branches can change frequently
+        const diff2ViewComp = this.querySelector("sketch-diff2-view");
+        if (diff2ViewComp) {
+          (diff2ViewComp as SketchDiff2View).refreshDiffView();
+        }
+      }
+
+      // Update view mode buttons
+      const viewModeSelect = this.querySelector("sketch-view-mode-select");
+      if (viewModeSelect) {
+        const event = new CustomEvent("update-active-mode", {
+          detail: { mode },
+          bubbles: true,
+          composed: true,
+        });
+        viewModeSelect.dispatchEvent(event);
+      }
+    });
+  }
+
+  /**
+   * Updates the document title based on current slug and connection status
+   */
+  private updateDocumentTitle(): void {
+    let docTitle = `sk: ${this.slug || "untitled"}`;
+
+    // Add red circle emoji if disconnected
+    if (this.connectionStatus === "disconnected") {
+      docTitle += " 🔴";
+    }
+
+    document.title = docTitle;
+  }
+
+  // Check and request notification permission if needed
+  private async checkNotificationPermission(): Promise<boolean> {
+    // Check if the Notification API is supported
+    if (!("Notification" in window)) {
+      console.log("This browser does not support notifications");
+      return false;
+    }
+
+    // Check if permission is already granted
+    if (Notification.permission === "granted") {
+      return true;
+    }
+
+    // If permission is not denied, request it
+    if (Notification.permission !== "denied") {
+      const permission = await Notification.requestPermission();
+      return permission === "granted";
+    }
+
+    return false;
+  }
+
+  // Handle notifications toggle click
+  private _handleNotificationsToggle(): void {
+    this.notificationsEnabled = !this.notificationsEnabled;
+
+    // If enabling notifications, check permissions
+    if (this.notificationsEnabled) {
+      this.checkNotificationPermission();
+    }
+
+    // Save preference to localStorage
+    try {
+      localStorage.setItem(
+        "sketch-notifications-enabled",
+        String(this.notificationsEnabled),
+      );
+    } catch (error) {
+      console.error("Error saving notification preference:", error);
+    }
+  }
+
+  // Handle window focus event
+  private _handleWindowFocus(): void {
+    this._windowFocused = true;
+  }
+
+  // Handle window blur event
+  private _handleWindowBlur(): void {
+    this._windowFocused = false;
+  }
+
+  // Get the last user or agent message (ignore system messages like commit, error, etc.)
+  // For example, when Sketch notices a new commit, it'll send a message,
+  // but it's still idle!
+  private getLastUserOrAgentMessage(): AgentMessage | null {
+    for (let i = this.messages.length - 1; i >= 0; i--) {
+      const message = this.messages[i];
+      if (message.type === "user" || message.type === "agent") {
+        return message;
+      }
+    }
+    return null;
+  }
+
+  // Show notification for message with EndOfTurn=true
+  private async showEndOfTurnNotification(
+    message: AgentMessage,
+  ): Promise<void> {
+    // Don't show notifications if they're disabled
+    if (!this.notificationsEnabled) return;
+
+    // Don't show notifications if the window is focused
+    if (this._windowFocused) return;
+
+    // Check if we have permission to show notifications
+    const hasPermission = await this.checkNotificationPermission();
+    if (!hasPermission) return;
+
+    // Only show notifications for agent messages with end_of_turn=true and no parent_conversation_id
+    if (
+      message.type !== "agent" ||
+      !message.end_of_turn ||
+      message.parent_conversation_id
+    )
+      return;
+
+    // Create a title that includes the sketch slug
+    const notificationTitle = `Sketch: ${this.slug || "untitled"}`;
+
+    // Extract the beginning of the message content (first 100 chars)
+    const messagePreview = message.content
+      ? message.content.substring(0, 100) +
+        (message.content.length > 100 ? "..." : "")
+      : "Agent has completed its turn";
+
+    // Create and show the notification
+    try {
+      new Notification(notificationTitle, {
+        body: messagePreview,
+        icon: "https://sketch.dev/favicon.ico", // Use sketch.dev favicon for notification
+      });
+    } catch (error) {
+      console.error("Error showing notification:", error);
+    }
+  }
+
+  // Check if todo panel should be visible based on latest todo content from messages or state
+  private checkTodoPanelVisibility(): void {
+    // Find the latest todo content from messages first
+    let latestTodoContent = "";
+    for (let i = this.messages.length - 1; i >= 0; i--) {
+      const message = this.messages[i];
+      if (message.todo_content !== undefined) {
+        latestTodoContent = message.todo_content || "";
+        break;
+      }
+    }
+
+    // If no todo content found in messages, check the current state
+    if (latestTodoContent === "" && this.containerState?.todo_content) {
+      latestTodoContent = this.containerState.todo_content;
+    }
+
+    // Parse the todo data to check if there are any actual todos
+    let hasTodos = false;
+    if (latestTodoContent.trim()) {
+      try {
+        const todoData = JSON.parse(latestTodoContent);
+        hasTodos = todoData.items && todoData.items.length > 0;
+      } catch (error) {
+        // Invalid JSON, treat as no todos
+        hasTodos = false;
+      }
+    }
+
+    this._todoPanelVisible = hasTodos;
+
+    // Update todo panel content if visible
+    if (hasTodos) {
+      const todoPanel = this.shadowRoot?.querySelector(
+        "sketch-todo-panel",
+      ) as any;
+      if (todoPanel && todoPanel.updateTodoContent) {
+        todoPanel.updateTodoContent(latestTodoContent);
+      }
+    }
+  }
+
+  private handleDataChanged(eventData: {
+    state: State;
+    newMessages: AgentMessage[];
+  }): void {
+    const { state, newMessages } = eventData;
+
+    // Update state if we received it
+    if (state) {
+      // Ensure we're using the latest call status to prevent indicators from being stuck
+      if (
+        state.outstanding_llm_calls === 0 &&
+        state.outstanding_tool_calls.length === 0
+      ) {
+        // Force reset containerState calls when nothing is reported as in progress
+        state.outstanding_llm_calls = 0;
+        state.outstanding_tool_calls = [];
+      }
+
+      this.containerState = state;
+      this.slug = state.slug || "";
+
+      // Update document title when sketch slug changes
+      this.updateDocumentTitle();
+    }
+
+    // Update messages
+    const oldMessageCount = this.messages.length;
+    this.messages = aggregateAgentMessages(this.messages, newMessages);
+
+    // If new messages were added and we're in chat view, reset stored scroll position
+    // so the timeline can auto-scroll to bottom for new content
+    if (this.messages.length > oldMessageCount && this.viewMode === "chat") {
+      // Only reset if we were near the bottom (indicating user wants to follow new messages)
+      if (this.scrollContainerRef.value) {
+        const scrollTop = this.scrollContainerRef.value.scrollTop;
+        const scrollHeight = this.scrollContainerRef.value.scrollHeight;
+        const clientHeight = this.scrollContainerRef.value.clientHeight;
+        const isNearBottom = scrollTop + clientHeight >= scrollHeight - 50; // 50px tolerance
+
+        if (isNearBottom) {
+          this._chatScrollPosition = 0; // Reset stored position to allow auto-scroll
+        }
+      }
+    }
+
+    // Process new messages to find commit messages
+    // Update last commit info via container status component
+    if (this.containerStatusElement) {
+      this.containerStatusElement.updateLastCommitInfo(newMessages);
+    }
+
+    // Check for agent messages with end_of_turn=true and show notifications
+    if (newMessages && newMessages.length > 0) {
+      for (const message of newMessages) {
+        if (
+          message.type === "agent" &&
+          message.end_of_turn &&
+          !message.parent_conversation_id
+        ) {
+          this.showEndOfTurnNotification(message);
+          break; // Only show one notification per batch of messages
+        }
+      }
+    }
+
+    // Check if todo panel should be visible after agent loop iteration
+    this.checkTodoPanelVisibility();
+
+    // Ensure chat input observer is set up when new data comes in
+    if (!this.chatInputResizeObserver) {
+      this.setupChatInputObserver();
+    }
+  }
+
+  private handleConnectionStatusChanged(
+    status: ConnectionStatus,
+    errorMessage?: string,
+  ): void {
+    this.connectionStatus = status;
+    this.connectionErrorMessage = errorMessage || "";
+
+    // Update document title when connection status changes
+    this.updateDocumentTitle();
+  }
+
+  private async _handleStopClick(): Promise<void> {
+    try {
+      const response = await fetch("cancel", {
+        method: "POST",
+        headers: {
+          "Content-Type": "application/json",
+        },
+        body: JSON.stringify({ reason: "user requested cancellation" }),
+      });
+
+      if (!response.ok) {
+        const errorData = await response.text();
+        throw new Error(
+          `Failed to stop operation: ${response.status} - ${errorData}`,
+        );
+      }
+
+      // Stop request sent
+    } catch (error) {
+      console.error("Error stopping operation:", error);
+    }
+  }
+
+  private async _handleEndClick(event?: Event): Promise<void> {
+    if (event) {
+      event.preventDefault();
+      event.stopPropagation();
+    }
+
+    // Show confirmation dialog
+    const confirmed = window.confirm(
+      "Ending the session will shut down the underlying container. Are you sure?",
+    );
+    if (!confirmed) return;
+
+    try {
+      const response = await fetch("end", {
+        method: "POST",
+        headers: {
+          "Content-Type": "application/json",
+        },
+        body: JSON.stringify({ reason: "user requested end of session" }),
+      });
+
+      if (!response.ok) {
+        const errorData = await response.text();
+        throw new Error(
+          `Failed to end session: ${response.status} - ${errorData}`,
+        );
+      }
+
+      // After successful response, redirect to messages view
+      // Extract the session ID from the URL
+      const currentUrl = window.location.href;
+      // The URL pattern should be like https://sketch.dev/s/cs71-8qa6-1124-aw79/
+      const urlParts = currentUrl.split("/");
+      let sessionId = "";
+
+      // Find the session ID in the URL (should be after /s/)
+      for (let i = 0; i < urlParts.length; i++) {
+        if (urlParts[i] === "s" && i + 1 < urlParts.length) {
+          sessionId = urlParts[i + 1];
+          break;
+        }
+      }
+
+      if (sessionId) {
+        // Create the messages URL
+        const messagesUrl = `/messages/${sessionId}`;
+        // Redirect to messages view
+        window.location.href = messagesUrl;
+      }
+
+      // End request sent - connection will be closed by server
+    } catch (error) {
+      console.error("Error ending session:", error);
+    }
+  }
+
+  async _handleMutlipleChoiceSelected(e: CustomEvent) {
+    const chatInput = this.shadowRoot?.querySelector(
+      "sketch-chat-input",
+    ) as SketchChatInput;
+    if (chatInput) {
+      if (chatInput.content && chatInput.content.trim() !== "") {
+        chatInput.content += "\n\n";
+      }
+      chatInput.content += e.detail.responseText;
+      chatInput.focus();
+      // Adjust textarea height to accommodate new content
+      requestAnimationFrame(() => {
+        if (chatInput.adjustChatSpacing) {
+          chatInput.adjustChatSpacing();
+        }
+      });
+    }
+  }
+
+  async _sendChat(e: CustomEvent) {
+    console.log("app shell: _sendChat", e);
+    e.preventDefault();
+    e.stopPropagation();
+    const message = e.detail.message?.trim();
+    if (message == "") {
+      return;
+    }
+    try {
+      // Always switch to chat view when sending a message so user can see processing
+      if (this.viewMode !== "chat") {
+        this.toggleViewMode("chat", true);
+      }
+
+      // 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}`);
+      }
+    } catch (error) {
+      console.error("Error sending chat message:", error);
+      const statusText = document.getElementById("statusText");
+      if (statusText) {
+        statusText.textContent = "Error sending message";
+      }
+    }
+  }
+
+  protected scrollContainerRef = createRef<HTMLElement>();
+
+  /**
+   * Set up ResizeObserver to monitor chat input height changes
+   */
+  private setupChatInputObserver(): void {
+    // Wait for DOM to be ready
+    this.updateComplete.then(() => {
+      const chatInputElement = this.shadowRoot?.querySelector("#chat-input");
+      if (chatInputElement && !this.chatInputResizeObserver) {
+        this.chatInputResizeObserver = new ResizeObserver((entries) => {
+          for (const entry of entries) {
+            this.updateTodoPanelHeight(entry.contentRect.height);
+          }
+        });
+
+        this.chatInputResizeObserver.observe(chatInputElement);
+
+        // Initial height calculation
+        const rect = chatInputElement.getBoundingClientRect();
+        this.updateTodoPanelHeight(rect.height);
+      }
+    });
+  }
+
+  /**
+   * Update the CSS custom property that controls todo panel bottom position
+   */
+  private updateTodoPanelHeight(chatInputHeight: number): void {
+    // Add some padding (20px) between todo panel and chat input
+    const bottomOffset = chatInputHeight;
+
+    // Update the CSS custom property on the host element
+    this.style.setProperty("--chat-input-height", `${bottomOffset}px`);
+  }
+
+  // Abstract method to be implemented by subclasses
+  abstract render(): any;
+
+  // Protected helper methods for subclasses to render common UI elements
+  protected renderTopBanner() {
+    return html`
+      <!-- Top banner: flex row, space between, border bottom, shadow -->
+      <div
+        id="top-banner"
+        class="flex self-stretch justify-between items-center px-5 pr-8 mb-0 border-b border-gray-200 gap-5 bg-white shadow-md w-full h-12"
+      >
+        <!-- Title container -->
+        <div
+          class="flex flex-col whitespace-nowrap overflow-hidden text-ellipsis max-w-[30%] md:max-w-1/2 sm:max-w-[60%] py-1.5"
+        >
+          <h1
+            class="text-lg md:text-base sm:text-sm font-semibold m-0 min-w-24 whitespace-nowrap overflow-hidden text-ellipsis"
+          >
+            ${this.containerState?.skaband_addr
+              ? html`<a
+                  href="${this.containerState.skaband_addr}"
+                  target="_blank"
+                  rel="noopener noreferrer"
+                  class="text-inherit no-underline transition-opacity duration-200 ease-in-out flex items-center gap-2 hover:opacity-80 hover:underline"
+                >
+                  <img
+                    src="${this.containerState.skaband_addr}/sketch.dev.png"
+                    alt="sketch"
+                    class="w-5 h-5 md:w-[18px] md:h-[18px] sm:w-4 sm:h-4 rounded-sm"
+                  />
+                  sketch
+                </a>`
+              : html`sketch`}
+          </h1>
+          <h2
+            class="m-0 p-0 text-gray-600 text-sm font-normal italic whitespace-nowrap overflow-hidden text-ellipsis"
+          >
+            ${this.slug}
+          </h2>
+        </div>
+
+        <!-- Container status info moved above tabs -->
+        <sketch-container-status
+          .state=${this.containerState}
+          id="container-status"
+        ></sketch-container-status>
+
+        <!-- Last Commit section moved to sketch-container-status -->
+
+        <!-- Views section with tabs -->
+        <sketch-view-mode-select
+          .diffLinesAdded=${this.containerState?.diff_lines_added || 0}
+          .diffLinesRemoved=${this.containerState?.diff_lines_removed || 0}
+        ></sketch-view-mode-select>
+
+        <!-- Control buttons and status -->
+        <div
+          class="flex items-center mb-0 flex-nowrap whitespace-nowrap flex-shrink-0 gap-4 pl-4 mr-12"
+        >
+          <button
+            id="stopButton"
+            class="bg-red-600 hover:bg-red-700 disabled:bg-red-300 disabled:cursor-not-allowed disabled:opacity-70 text-white border-none px-2.5 py-1 xl:px-1.5 rounded cursor-pointer text-xs mr-1.5 flex items-center gap-1.5 transition-colors"
+            ?disabled=${(this.containerState?.outstanding_llm_calls || 0) ===
+              0 &&
+            (this.containerState?.outstanding_tool_calls || []).length === 0}
+          >
+            <svg
+              class="w-4 h-4"
+              xmlns="http://www.w3.org/2000/svg"
+              viewBox="0 0 24 24"
+              fill="none"
+              stroke="currentColor"
+              stroke-width="2"
+              stroke-linecap="round"
+              stroke-linejoin="round"
+            >
+              <rect x="6" y="6" width="12" height="12" />
+            </svg>
+            <span class="xl:hidden">Stop</span>
+          </button>
+          <button
+            id="endButton"
+            class="bg-gray-600 hover:bg-gray-700 disabled:bg-gray-400 disabled:cursor-not-allowed disabled:opacity-70 text-white border-none px-2.5 py-1 xl:px-1.5 rounded cursor-pointer text-xs mr-1.5 flex items-center gap-1.5 transition-colors"
+            @click=${this._handleEndClick}
+          >
+            <svg
+              class="w-4 h-4"
+              xmlns="http://www.w3.org/2000/svg"
+              viewBox="0 0 24 24"
+              fill="none"
+              stroke="currentColor"
+              stroke-width="2"
+              stroke-linecap="round"
+              stroke-linejoin="round"
+            >
+              <path d="M18 6L6 18" />
+              <path d="M6 6l12 12" />
+            </svg>
+            <span class="xl:hidden">End</span>
+          </button>
+
+          <div
+            class="flex items-center text-xs mr-2.5 cursor-pointer"
+            @click=${this._handleNotificationsToggle}
+            title="${this.notificationsEnabled
+              ? "Disable"
+              : "Enable"} notifications when the agent completes its turn"
+          >
+            <div
+              class="w-5 h-5 relative inline-flex items-center justify-center"
+            >
+              <!-- Bell SVG icon -->
+              <svg
+                xmlns="http://www.w3.org/2000/svg"
+                width="16"
+                height="16"
+                fill="currentColor"
+                viewBox="0 0 16 16"
+                class="${!this.notificationsEnabled ? "relative z-10" : ""}"
+              >
+                <path
+                  d="M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2zM8 1.918l-.797.161A4.002 4.002 0 0 0 4 6c0 .628-.134 2.197-.459 3.742-.16.767-.376 1.566-.663 2.258h10.244c-.287-.692-.502-1.49-.663-2.258C12.134 8.197 12 6.628 12 6a4.002 4.002 0 0 0-3.203-3.92L8 1.917zM14.22 12c.223.447.481.801.78 1H1c.299-.199.557-.553.78-1C2.68 10.2 3 6.88 3 6c0-2.42 1.72-4.44 4.005-4.901a1 1 0 1 1 1.99 0A5.002 5.002 0 0 1 13 6c0 .88.32 4.2 1.22 6z"
+                />
+              </svg>
+              ${!this.notificationsEnabled
+                ? html`<div
+                    class="absolute w-0.5 h-6 bg-red-600 rotate-45 origin-center"
+                  ></div>`
+                : ""}
+            </div>
+          </div>
+
+          <sketch-call-status
+            .agentState=${this.containerState?.agent_state}
+            .llmCalls=${this.containerState?.outstanding_llm_calls || 0}
+            .toolCalls=${this.containerState?.outstanding_tool_calls || []}
+            .isIdle=${(() => {
+              const lastUserOrAgentMessage = this.getLastUserOrAgentMessage();
+              return lastUserOrAgentMessage
+                ? lastUserOrAgentMessage.end_of_turn &&
+                    !lastUserOrAgentMessage.parent_conversation_id
+                : true;
+            })()}
+            .isDisconnected=${this.connectionStatus === "disconnected"}
+          ></sketch-call-status>
+
+          <sketch-network-status
+            connection=${this.connectionStatus}
+            error=${this.connectionErrorMessage}
+          ></sketch-network-status>
+        </div>
+      </div>
+    `;
+  }
+
+  protected renderMainViews() {
+    return html`
+      <!-- Chat View -->
+      <div
+        class="chat-view ${this.viewMode === "chat"
+          ? "view-active flex flex-col"
+          : "hidden"} w-full h-full"
+      >
+        <div
+          class="${this._todoPanelVisible && this.viewMode === "chat"
+            ? "mr-[400px] xl:mr-[350px] lg:mr-[300px] md:mr-0 w-[calc(100%-400px)] xl:w-[calc(100%-350px)] lg:w-[calc(100%-300px)] md:w-full"
+            : "mr-0"} flex-1 flex flex-col w-full h-full transition-[margin-right] duration-200 ease-in-out"
+        >
+          <sketch-timeline
+            .messages=${this.messages}
+            .scrollContainer=${this.scrollContainerRef}
+            .agentState=${this.containerState?.agent_state}
+            .llmCalls=${this.containerState?.outstanding_llm_calls || 0}
+            .toolCalls=${this.containerState?.outstanding_tool_calls || []}
+            .firstMessageIndex=${this.containerState?.first_message_index || 0}
+            .state=${this.containerState}
+            .dataManager=${this.dataManager}
+          ></sketch-timeline>
+        </div>
+      </div>
+
+      <!-- Todo panel positioned outside the main flow - only visible in chat view -->
+      <div
+        class="${this._todoPanelVisible && this.viewMode === "chat"
+          ? "block"
+          : "hidden"} fixed top-12 right-4 w-[400px] xl:w-[350px] lg:w-[300px] md:hidden z-[100] transition-[bottom] duration-200 ease-in-out"
+        style="bottom: var(--chat-input-height, 90px); background: linear-gradient(to bottom, #fafafa 0%, #fafafa 90%, rgba(250, 250, 250, 0.5) 95%, rgba(250, 250, 250, 0.2) 100%); border-left: 1px solid #e0e0e0;"
+      >
+        <sketch-todo-panel
+          .visible=${this._todoPanelVisible && this.viewMode === "chat"}
+        ></sketch-todo-panel>
+      </div>
+      <!-- Diff2 View -->
+      <div
+        class="diff2-view ${this.viewMode === "diff2"
+          ? "view-active flex-1 overflow-hidden min-h-0 flex flex-col h-full"
+          : "hidden"} w-full h-full"
+      >
+        <sketch-diff2-view
+          .commit=${this.currentCommitHash}
+          .gitService=${new DefaultGitDataService()}
+          @diff-comment="${this._handleDiffComment}"
+        ></sketch-diff2-view>
+      </div>
+
+      <!-- Terminal View -->
+      <div
+        class="terminal-view ${this.viewMode === "terminal"
+          ? "view-active flex flex-col"
+          : "hidden"} w-full h-full"
+      >
+        <sketch-terminal></sketch-terminal>
+      </div>
+    `;
+  }
+
+  protected renderChatInput() {
+    return html`
+      <!-- Chat input fixed at bottom -->
+      <div
+        id="chat-input"
+        class="self-end w-full shadow-[0_-2px_10px_rgba(0,0,0,0.1)]"
+      >
+        <sketch-chat-input @send-chat="${this._sendChat}"></sketch-chat-input>
+      </div>
+    `;
+  }
+
+  /**
+   * Lifecycle callback when component is first connected to DOM
+   */
+  firstUpdated(): void {
+    if (this.viewMode !== "chat") {
+      return;
+    }
+
+    // Initial scroll to bottom when component is first rendered
+    setTimeout(
+      () => this.scrollTo({ top: this.scrollHeight, behavior: "smooth" }),
+      50,
+    );
+
+    // Setup stop button
+    const stopButton = this.renderRoot?.querySelector(
+      "#stopButton",
+    ) as HTMLButtonElement;
+    stopButton?.addEventListener("click", async () => {
+      try {
+        const response = await fetch("cancel", {
+          method: "POST",
+          headers: {
+            "Content-Type": "application/json",
+          },
+          body: JSON.stringify({ reason: "User clicked stop button" }),
+        });
+        if (!response.ok) {
+          console.error("Failed to cancel:", await response.text());
+        }
+      } catch (error) {
+        console.error("Error cancelling operation:", error);
+      }
+    });
+
+    // Setup end button
+    const endButton = this.renderRoot?.querySelector(
+      "#endButton",
+    ) as HTMLButtonElement;
+    // We're already using the @click binding in the HTML, so manual event listener not needed here
+
+    // Process any existing messages to find commit information
+    if (this.messages && this.messages.length > 0) {
+      // Update last commit info via container status component
+      if (this.containerStatusElement) {
+        this.containerStatusElement.updateLastCommitInfo(this.messages);
+      }
+    }
+
+    // Set up chat input height observer for todo panel
+    this.setupChatInputObserver();
+  }
+}
+
+// Export the ViewMode type for use in subclasses
+export type { ViewMode };
diff --git a/webui/src/web-components/sketch-app-shell.ts b/webui/src/web-components/sketch-app-shell.ts
index f37d9c9..9d0f2f6 100644
--- a/webui/src/web-components/sketch-app-shell.ts
+++ b/webui/src/web-components/sketch-app-shell.ts
@@ -1,999 +1,17 @@
-import { css, html, LitElement } from "lit";
-import { customElement, property, state } from "lit/decorators.js";
-import { ConnectionStatus, DataManager } from "../data";
-import { AgentMessage, GitLogEntry, State } from "../types";
-import { aggregateAgentMessages } from "./aggregateAgentMessages";
-import { SketchTailwindElement } from "./sketch-tailwind-element";
-
-import "./sketch-chat-input";
-import "./sketch-container-status";
-
-import "./sketch-diff2-view";
-import { SketchDiff2View } from "./sketch-diff2-view";
-import { DefaultGitDataService } from "./git-data-service";
-import "./sketch-monaco-view";
-import "./sketch-network-status";
-import "./sketch-call-status";
-import "./sketch-terminal";
-import "./sketch-timeline";
-import "./sketch-view-mode-select";
-import "./sketch-todo-panel";
-
-import { createRef, ref } from "lit/directives/ref.js";
-import { SketchChatInput } from "./sketch-chat-input";
-
-type ViewMode = "chat" | "diff2" | "terminal";
+import { html } from "lit";
+import { customElement } from "lit/decorators.js";
+import { ref } from "lit/directives/ref.js";
+import { SketchAppShellBase } from "./sketch-app-shell-base";
 
 @customElement("sketch-app-shell")
-export class SketchAppShell extends SketchTailwindElement {
-  // Current view mode (chat, diff, terminal)
-  @state()
-  viewMode: ViewMode = "chat";
-
-  // Current commit hash for diff view
-  @state()
-  currentCommitHash: string = "";
-
-  // Last commit information
-  @state()
-
-  // Reference to the container status element
-  containerStatusElement: any = null;
-
-  // Note: CSS styles have been converted to Tailwind classes applied directly to HTML elements
-  // since this component now extends SketchTailwindElement which disables shadow DOM
-
-  // Override createRenderRoot to apply host styles for proper sizing while still using light DOM
-  createRenderRoot() {
-    // Use light DOM like SketchTailwindElement but still apply host styles
-    const style = document.createElement("style");
-    style.textContent = `
-      sketch-app-shell {
-        display: block;
-        width: 100%;
-        height: 100vh;
-        max-width: 100%;
-        box-sizing: border-box;
-        overflow: hidden;
-      }
-    `;
-
-    // Add the style to the document head if not already present
-    if (!document.head.querySelector("style[data-sketch-app-shell]")) {
-      style.setAttribute("data-sketch-app-shell", "");
-      document.head.appendChild(style);
-    }
-
-    return this;
-  }
-
-  // Header bar: Network connection status details
-  @property()
-  connectionStatus: ConnectionStatus = "disconnected";
-
-  // Track if the last commit info has been copied
-  @state()
-  // lastCommitCopied moved to sketch-container-status
-
-  // Track notification preferences
-  @state()
-  notificationsEnabled: boolean = false;
-
-  // Track if the window is focused to control notifications
-  @state()
-  private _windowFocused: boolean = document.hasFocus();
-
-  // Track if the todo panel should be visible
-  @state()
-  private _todoPanelVisible: boolean = false;
-
-  // Store scroll position for the chat view to preserve it when switching tabs
-  @state()
-  private _chatScrollPosition: number = 0;
-
-  // ResizeObserver for tracking chat input height changes
-  private chatInputResizeObserver: ResizeObserver | null = null;
-
-  @property()
-  connectionErrorMessage: string = "";
-
-  // Chat messages
-  @property({ attribute: false })
-  messages: AgentMessage[] = [];
-
-  @property()
-  set slug(value: string) {
-    const oldValue = this._slug;
-    this._slug = value;
-    this.requestUpdate("slug", oldValue);
-    // Update document title when slug property changes
-    this.updateDocumentTitle();
-  }
-
-  get slug(): string {
-    return this._slug;
-  }
-
-  private _slug: string = "";
-
-  private dataManager = new DataManager();
-
-  @property({ attribute: false })
-  containerState: State = {
-    state_version: 2,
-    slug: "",
-    os: "",
-    message_count: 0,
-    hostname: "",
-    working_dir: "",
-    initial_commit: "",
-    outstanding_llm_calls: 0,
-    outstanding_tool_calls: [],
-    session_id: "",
-    ssh_available: false,
-    ssh_error: "",
-    in_container: false,
-    first_message_index: 0,
-    diff_lines_added: 0,
-    diff_lines_removed: 0,
-  };
-
-  // Mutation observer to detect when new messages are added
-  private mutationObserver: MutationObserver | null = null;
-
-  constructor() {
-    super();
-
-    // Reference to the container status element
-    this.containerStatusElement = null;
-
-    // Binding methods to this
-    this._handleViewModeSelect = this._handleViewModeSelect.bind(this);
-    this._handlePopState = this._handlePopState.bind(this);
-    this._handleShowCommitDiff = this._handleShowCommitDiff.bind(this);
-    this._handleMutlipleChoiceSelected =
-      this._handleMutlipleChoiceSelected.bind(this);
-    this._handleStopClick = this._handleStopClick.bind(this);
-    this._handleEndClick = this._handleEndClick.bind(this);
-    this._handleNotificationsToggle =
-      this._handleNotificationsToggle.bind(this);
-    this._handleWindowFocus = this._handleWindowFocus.bind(this);
-    this._handleWindowBlur = this._handleWindowBlur.bind(this);
-
-    // Load notification preference from localStorage
-    try {
-      const savedPref = localStorage.getItem("sketch-notifications-enabled");
-      if (savedPref !== null) {
-        this.notificationsEnabled = savedPref === "true";
-      }
-    } catch (error) {
-      console.error("Error loading notification preference:", error);
-    }
-  }
-
-  // See https://lit.dev/docs/components/lifecycle/
-  connectedCallback() {
-    super.connectedCallback();
-
-    // Get reference to the container status element
-    setTimeout(() => {
-      this.containerStatusElement =
-        this.shadowRoot?.getElementById("container-status");
-    }, 0);
-
-    // Initialize client-side nav history.
-    const url = new URL(window.location.href);
-    const mode = url.searchParams.get("view") || "chat";
-    window.history.replaceState({ mode }, "", url.toString());
-
-    this.toggleViewMode(mode as ViewMode, false);
-    // Add popstate event listener to handle browser back/forward navigation
-    window.addEventListener("popstate", this._handlePopState);
-
-    // Add event listeners
-    window.addEventListener("view-mode-select", this._handleViewModeSelect);
-    window.addEventListener("show-commit-diff", this._handleShowCommitDiff);
-
-    // Add window focus/blur listeners for controlling notifications
-    window.addEventListener("focus", this._handleWindowFocus);
-    window.addEventListener("blur", this._handleWindowBlur);
-    window.addEventListener(
-      "multiple-choice-selected",
-      this._handleMutlipleChoiceSelected,
-    );
-
-    // register event listeners
-    this.dataManager.addEventListener(
-      "dataChanged",
-      this.handleDataChanged.bind(this),
-    );
-    this.dataManager.addEventListener(
-      "connectionStatusChanged",
-      this.handleConnectionStatusChanged.bind(this),
-    );
-
-    // Set initial document title
-    this.updateDocumentTitle();
-
-    // Initialize the data manager
-    this.dataManager.initialize();
-
-    // Process existing messages for commit info
-    if (this.messages && this.messages.length > 0) {
-      // Update last commit info via container status component
-      setTimeout(() => {
-        if (this.containerStatusElement) {
-          this.containerStatusElement.updateLastCommitInfo(this.messages);
-        }
-      }, 100);
-    }
-
-    // Check if todo panel should be visible on initial load
-    this.checkTodoPanelVisibility();
-
-    // Set up ResizeObserver for chat input to update todo panel height
-    this.setupChatInputObserver();
-  }
-
-  // See https://lit.dev/docs/components/lifecycle/
-  disconnectedCallback() {
-    super.disconnectedCallback();
-    window.removeEventListener("popstate", this._handlePopState);
-
-    // Remove event listeners
-    window.removeEventListener("view-mode-select", this._handleViewModeSelect);
-    window.removeEventListener("show-commit-diff", this._handleShowCommitDiff);
-    window.removeEventListener("focus", this._handleWindowFocus);
-    window.removeEventListener("blur", this._handleWindowBlur);
-    window.removeEventListener(
-      "multiple-choice-selected",
-      this._handleMutlipleChoiceSelected,
-    );
-
-    // unregister data manager event listeners
-    this.dataManager.removeEventListener(
-      "dataChanged",
-      this.handleDataChanged.bind(this),
-    );
-    this.dataManager.removeEventListener(
-      "connectionStatusChanged",
-      this.handleConnectionStatusChanged.bind(this),
-    );
-
-    // Disconnect mutation observer if it exists
-    if (this.mutationObserver) {
-      this.mutationObserver.disconnect();
-      this.mutationObserver = null;
-    }
-
-    // Disconnect chat input resize observer if it exists
-    if (this.chatInputResizeObserver) {
-      this.chatInputResizeObserver.disconnect();
-      this.chatInputResizeObserver = null;
-    }
-  }
-
-  updateUrlForViewMode(mode: ViewMode): 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);
-      const diff2View = this.shadowRoot?.querySelector(
-        "sketch-diff2-view",
-      ) as SketchDiff2View;
-
-      // If in diff2 view and there's a commit hash, include that too
-      if (mode === "diff2" && diff2View?.commit) {
-        url.searchParams.set("commit", diff2View.commit);
-      }
-    }
-
-    // Update the browser history without reloading the page
-    window.history.pushState({ mode }, "", url.toString());
-  }
-
-  private _handlePopState(event: PopStateEvent) {
-    if (event.state && event.state.mode) {
-      this.toggleViewMode(event.state.mode, false);
-    } else {
-      this.toggleViewMode("chat", false);
-    }
-  }
-
-  /**
-   * Handle view mode selection event
-   */
-  private _handleViewModeSelect(event: CustomEvent) {
-    const mode = event.detail.mode as "chat" | "diff2" | "terminal";
-    this.toggleViewMode(mode, true);
-  }
-
-  /**
-   * Handle show commit diff event
-   */
-  private _handleShowCommitDiff(event: CustomEvent) {
-    const { commitHash } = event.detail;
-    if (commitHash) {
-      this.showCommitDiff(commitHash);
-    }
-  }
-
-  private _handleMultipleChoice(event: CustomEvent) {
-    window.console.log("_handleMultipleChoice", event);
-    this._sendChat;
-  }
-
-  private _handleDiffComment(event: CustomEvent) {
-    // Empty stub required by the event binding in the template
-    // Actual handling occurs at global level in sketch-chat-input component
-  }
-  /**
-   * Listen for commit diff event
-   * @param commitHash The commit hash to show diff for
-   */
-  private showCommitDiff(commitHash: string): void {
-    // Store the commit hash
-    this.currentCommitHash = commitHash;
-
-    this.toggleViewMode("diff2", true);
-
-    this.updateComplete.then(() => {
-      const diff2View = this.shadowRoot?.querySelector("sketch-diff2-view");
-      if (diff2View) {
-        (diff2View as SketchDiff2View).refreshDiffView();
-      }
-    });
-  }
-
-  /**
-   * Toggle between different view modes: chat, diff2, terminal
-   */
-  private toggleViewMode(mode: ViewMode, updateHistory: boolean): void {
-    // Don't do anything if the mode is already active
-    if (this.viewMode === mode) return;
-
-    // Store scroll position if we're leaving the chat view
-    if (this.viewMode === "chat" && this.scrollContainerRef.value) {
-      // Only store scroll position if we actually have meaningful content
-      const scrollTop = this.scrollContainerRef.value.scrollTop;
-      const scrollHeight = this.scrollContainerRef.value.scrollHeight;
-      const clientHeight = this.scrollContainerRef.value.clientHeight;
-
-      // Store position only if we have scrollable content and have actually scrolled
-      if (scrollHeight > clientHeight && scrollTop > 0) {
-        this._chatScrollPosition = scrollTop;
-      }
-    }
-
-    // Update the view mode
-    this.viewMode = mode;
-
-    if (updateHistory) {
-      // Update URL with the current view mode
-      this.updateUrlForViewMode(mode);
-    }
-
-    // Wait for DOM update to complete
-    this.updateComplete.then(() => {
-      // Handle scroll position restoration for chat view
-      if (
-        mode === "chat" &&
-        this.scrollContainerRef.value &&
-        this._chatScrollPosition > 0
-      ) {
-        // Use requestAnimationFrame to ensure DOM is ready
-        requestAnimationFrame(() => {
-          if (this.scrollContainerRef.value) {
-            // Double-check that we're still in chat mode and the container is available
-            if (
-              this.viewMode === "chat" &&
-              this.scrollContainerRef.value.isConnected
-            ) {
-              this.scrollContainerRef.value.scrollTop =
-                this._chatScrollPosition;
-            }
-          }
-        });
-      }
-
-      // Handle diff2 view specific logic
-      if (mode === "diff2") {
-        // Refresh git/recentlog when Monaco diff view is opened
-        // This ensures branch information is always up-to-date, as branches can change frequently
-        const diff2ViewComp = this.querySelector("sketch-diff2-view");
-        if (diff2ViewComp) {
-          (diff2ViewComp as SketchDiff2View).refreshDiffView();
-        }
-      }
-
-      // Update view mode buttons
-      const viewModeSelect = this.querySelector("sketch-view-mode-select");
-      if (viewModeSelect) {
-        const event = new CustomEvent("update-active-mode", {
-          detail: { mode },
-          bubbles: true,
-          composed: true,
-        });
-        viewModeSelect.dispatchEvent(event);
-      }
-    });
-  }
-
-  /**
-   * Updates the document title based on current slug and connection status
-   */
-  private updateDocumentTitle(): void {
-    let docTitle = `sk: ${this.slug || "untitled"}`;
-
-    // Add red circle emoji if disconnected
-    if (this.connectionStatus === "disconnected") {
-      docTitle += " 🔴";
-    }
-
-    document.title = docTitle;
-  }
-
-  // Check and request notification permission if needed
-  private async checkNotificationPermission(): Promise<boolean> {
-    // Check if the Notification API is supported
-    if (!("Notification" in window)) {
-      console.log("This browser does not support notifications");
-      return false;
-    }
-
-    // Check if permission is already granted
-    if (Notification.permission === "granted") {
-      return true;
-    }
-
-    // If permission is not denied, request it
-    if (Notification.permission !== "denied") {
-      const permission = await Notification.requestPermission();
-      return permission === "granted";
-    }
-
-    return false;
-  }
-
-  // Handle notifications toggle click
-  private _handleNotificationsToggle(): void {
-    this.notificationsEnabled = !this.notificationsEnabled;
-
-    // If enabling notifications, check permissions
-    if (this.notificationsEnabled) {
-      this.checkNotificationPermission();
-    }
-
-    // Save preference to localStorage
-    try {
-      localStorage.setItem(
-        "sketch-notifications-enabled",
-        String(this.notificationsEnabled),
-      );
-    } catch (error) {
-      console.error("Error saving notification preference:", error);
-    }
-  }
-
-  // Handle window focus event
-  private _handleWindowFocus(): void {
-    this._windowFocused = true;
-  }
-
-  // Handle window blur event
-  private _handleWindowBlur(): void {
-    this._windowFocused = false;
-  }
-
-  // Get the last user or agent message (ignore system messages like commit, error, etc.)
-  // For example, when Sketch notices a new commit, it'll send a message,
-  // but it's still idle!
-  private getLastUserOrAgentMessage(): AgentMessage | null {
-    for (let i = this.messages.length - 1; i >= 0; i--) {
-      const message = this.messages[i];
-      if (message.type === "user" || message.type === "agent") {
-        return message;
-      }
-    }
-    return null;
-  }
-
-  // Show notification for message with EndOfTurn=true
-  private async showEndOfTurnNotification(
-    message: AgentMessage,
-  ): Promise<void> {
-    // Don't show notifications if they're disabled
-    if (!this.notificationsEnabled) return;
-
-    // Don't show notifications if the window is focused
-    if (this._windowFocused) return;
-
-    // Check if we have permission to show notifications
-    const hasPermission = await this.checkNotificationPermission();
-    if (!hasPermission) return;
-
-    // Only show notifications for agent messages with end_of_turn=true and no parent_conversation_id
-    if (
-      message.type !== "agent" ||
-      !message.end_of_turn ||
-      message.parent_conversation_id
-    )
-      return;
-
-    // Create a title that includes the sketch slug
-    const notificationTitle = `Sketch: ${this.slug || "untitled"}`;
-
-    // Extract the beginning of the message content (first 100 chars)
-    const messagePreview = message.content
-      ? message.content.substring(0, 100) +
-        (message.content.length > 100 ? "..." : "")
-      : "Agent has completed its turn";
-
-    // Create and show the notification
-    try {
-      new Notification(notificationTitle, {
-        body: messagePreview,
-        icon: "https://sketch.dev/favicon.ico", // Use sketch.dev favicon for notification
-      });
-    } catch (error) {
-      console.error("Error showing notification:", error);
-    }
-  }
-
-  // Check if todo panel should be visible based on latest todo content from messages or state
-  private checkTodoPanelVisibility(): void {
-    // Find the latest todo content from messages first
-    let latestTodoContent = "";
-    for (let i = this.messages.length - 1; i >= 0; i--) {
-      const message = this.messages[i];
-      if (message.todo_content !== undefined) {
-        latestTodoContent = message.todo_content || "";
-        break;
-      }
-    }
-
-    // If no todo content found in messages, check the current state
-    if (latestTodoContent === "" && this.containerState?.todo_content) {
-      latestTodoContent = this.containerState.todo_content;
-    }
-
-    // Parse the todo data to check if there are any actual todos
-    let hasTodos = false;
-    if (latestTodoContent.trim()) {
-      try {
-        const todoData = JSON.parse(latestTodoContent);
-        hasTodos = todoData.items && todoData.items.length > 0;
-      } catch (error) {
-        // Invalid JSON, treat as no todos
-        hasTodos = false;
-      }
-    }
-
-    this._todoPanelVisible = hasTodos;
-
-    // Update todo panel content if visible
-    if (hasTodos) {
-      const todoPanel = this.shadowRoot?.querySelector(
-        "sketch-todo-panel",
-      ) as any;
-      if (todoPanel && todoPanel.updateTodoContent) {
-        todoPanel.updateTodoContent(latestTodoContent);
-      }
-    }
-  }
-
-  private handleDataChanged(eventData: {
-    state: State;
-    newMessages: AgentMessage[];
-  }): void {
-    const { state, newMessages } = eventData;
-
-    // Update state if we received it
-    if (state) {
-      // Ensure we're using the latest call status to prevent indicators from being stuck
-      if (
-        state.outstanding_llm_calls === 0 &&
-        state.outstanding_tool_calls.length === 0
-      ) {
-        // Force reset containerState calls when nothing is reported as in progress
-        state.outstanding_llm_calls = 0;
-        state.outstanding_tool_calls = [];
-      }
-
-      this.containerState = state;
-      this.slug = state.slug || "";
-
-      // Update document title when sketch slug changes
-      this.updateDocumentTitle();
-    }
-
-    // Update messages
-    const oldMessageCount = this.messages.length;
-    this.messages = aggregateAgentMessages(this.messages, newMessages);
-
-    // If new messages were added and we're in chat view, reset stored scroll position
-    // so the timeline can auto-scroll to bottom for new content
-    if (this.messages.length > oldMessageCount && this.viewMode === "chat") {
-      // Only reset if we were near the bottom (indicating user wants to follow new messages)
-      if (this.scrollContainerRef.value) {
-        const scrollTop = this.scrollContainerRef.value.scrollTop;
-        const scrollHeight = this.scrollContainerRef.value.scrollHeight;
-        const clientHeight = this.scrollContainerRef.value.clientHeight;
-        const isNearBottom = scrollTop + clientHeight >= scrollHeight - 50; // 50px tolerance
-
-        if (isNearBottom) {
-          this._chatScrollPosition = 0; // Reset stored position to allow auto-scroll
-        }
-      }
-    }
-
-    // Process new messages to find commit messages
-    // Update last commit info via container status component
-    if (this.containerStatusElement) {
-      this.containerStatusElement.updateLastCommitInfo(newMessages);
-    }
-
-    // Check for agent messages with end_of_turn=true and show notifications
-    if (newMessages && newMessages.length > 0) {
-      for (const message of newMessages) {
-        if (
-          message.type === "agent" &&
-          message.end_of_turn &&
-          !message.parent_conversation_id
-        ) {
-          this.showEndOfTurnNotification(message);
-          break; // Only show one notification per batch of messages
-        }
-      }
-    }
-
-    // Check if todo panel should be visible after agent loop iteration
-    this.checkTodoPanelVisibility();
-
-    // Ensure chat input observer is set up when new data comes in
-    if (!this.chatInputResizeObserver) {
-      this.setupChatInputObserver();
-    }
-  }
-
-  private handleConnectionStatusChanged(
-    status: ConnectionStatus,
-    errorMessage?: string,
-  ): void {
-    this.connectionStatus = status;
-    this.connectionErrorMessage = errorMessage || "";
-
-    // Update document title when connection status changes
-    this.updateDocumentTitle();
-  }
-
-  private async _handleStopClick(): Promise<void> {
-    try {
-      const response = await fetch("cancel", {
-        method: "POST",
-        headers: {
-          "Content-Type": "application/json",
-        },
-        body: JSON.stringify({ reason: "user requested cancellation" }),
-      });
-
-      if (!response.ok) {
-        const errorData = await response.text();
-        throw new Error(
-          `Failed to stop operation: ${response.status} - ${errorData}`,
-        );
-      }
-
-      // Stop request sent
-    } catch (error) {
-      console.error("Error stopping operation:", error);
-    }
-  }
-
-  private async _handleEndClick(event?: Event): Promise<void> {
-    if (event) {
-      event.preventDefault();
-      event.stopPropagation();
-    }
-
-    // Show confirmation dialog
-    const confirmed = window.confirm(
-      "Ending the session will shut down the underlying container. Are you sure?",
-    );
-    if (!confirmed) return;
-
-    try {
-      const response = await fetch("end", {
-        method: "POST",
-        headers: {
-          "Content-Type": "application/json",
-        },
-        body: JSON.stringify({ reason: "user requested end of session" }),
-      });
-
-      if (!response.ok) {
-        const errorData = await response.text();
-        throw new Error(
-          `Failed to end session: ${response.status} - ${errorData}`,
-        );
-      }
-
-      // After successful response, redirect to messages view
-      // Extract the session ID from the URL
-      const currentUrl = window.location.href;
-      // The URL pattern should be like https://sketch.dev/s/cs71-8qa6-1124-aw79/
-      const urlParts = currentUrl.split("/");
-      let sessionId = "";
-
-      // Find the session ID in the URL (should be after /s/)
-      for (let i = 0; i < urlParts.length; i++) {
-        if (urlParts[i] === "s" && i + 1 < urlParts.length) {
-          sessionId = urlParts[i + 1];
-          break;
-        }
-      }
-
-      if (sessionId) {
-        // Create the messages URL
-        const messagesUrl = `/messages/${sessionId}`;
-        // Redirect to messages view
-        window.location.href = messagesUrl;
-      }
-
-      // End request sent - connection will be closed by server
-    } catch (error) {
-      console.error("Error ending session:", error);
-    }
-  }
-
-  async _handleMutlipleChoiceSelected(e: CustomEvent) {
-    const chatInput = this.shadowRoot?.querySelector(
-      "sketch-chat-input",
-    ) as SketchChatInput;
-    if (chatInput) {
-      if (chatInput.content && chatInput.content.trim() !== "") {
-        chatInput.content += "\n\n";
-      }
-      chatInput.content += e.detail.responseText;
-      chatInput.focus();
-      // Adjust textarea height to accommodate new content
-      requestAnimationFrame(() => {
-        if (chatInput.adjustChatSpacing) {
-          chatInput.adjustChatSpacing();
-        }
-      });
-    }
-  }
-
-  async _sendChat(e: CustomEvent) {
-    console.log("app shell: _sendChat", e);
-    e.preventDefault();
-    e.stopPropagation();
-    const message = e.detail.message?.trim();
-    if (message == "") {
-      return;
-    }
-    try {
-      // Always switch to chat view when sending a message so user can see processing
-      if (this.viewMode !== "chat") {
-        this.toggleViewMode("chat", true);
-      }
-
-      // 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}`);
-      }
-    } catch (error) {
-      console.error("Error sending chat message:", error);
-      const statusText = document.getElementById("statusText");
-      if (statusText) {
-        statusText.textContent = "Error sending message";
-      }
-    }
-  }
-
-  private scrollContainerRef = createRef<HTMLElement>();
-
-  /**
-   * Set up ResizeObserver to monitor chat input height changes
-   */
-  private setupChatInputObserver(): void {
-    // Wait for DOM to be ready
-    this.updateComplete.then(() => {
-      const chatInputElement = this.shadowRoot?.querySelector("#chat-input");
-      if (chatInputElement && !this.chatInputResizeObserver) {
-        this.chatInputResizeObserver = new ResizeObserver((entries) => {
-          for (const entry of entries) {
-            this.updateTodoPanelHeight(entry.contentRect.height);
-          }
-        });
-
-        this.chatInputResizeObserver.observe(chatInputElement);
-
-        // Initial height calculation
-        const rect = chatInputElement.getBoundingClientRect();
-        this.updateTodoPanelHeight(rect.height);
-      }
-    });
-  }
-
-  /**
-   * Update the CSS custom property that controls todo panel bottom position
-   */
-  private updateTodoPanelHeight(chatInputHeight: number): void {
-    // Add some padding (20px) between todo panel and chat input
-    const bottomOffset = chatInputHeight;
-
-    // Update the CSS custom property on the host element
-    this.style.setProperty("--chat-input-height", `${bottomOffset}px`);
-  }
-
+export class SketchAppShell extends SketchAppShellBase {
   render() {
     return html`
       <!-- Main container: flex column, full height, system font, hidden overflow-x -->
       <div
         class="block font-sans text-gray-800 leading-relaxed h-screen w-full relative overflow-x-hidden flex flex-col"
       >
-        <!-- Top banner: flex row, space between, border bottom, shadow -->
-        <div
-          id="top-banner"
-          class="flex self-stretch justify-between items-center px-5 pr-8 mb-0 border-b border-gray-200 gap-5 bg-white shadow-md w-full h-12"
-        >
-          <!-- Title container -->
-          <div
-            class="flex flex-col whitespace-nowrap overflow-hidden text-ellipsis max-w-[30%] md:max-w-1/2 sm:max-w-[60%] py-1.5"
-          >
-            <h1
-              class="text-lg md:text-base sm:text-sm font-semibold m-0 min-w-24 whitespace-nowrap overflow-hidden text-ellipsis"
-            >
-              ${this.containerState?.skaband_addr
-                ? html`<a
-                    href="${this.containerState.skaband_addr}"
-                    target="_blank"
-                    rel="noopener noreferrer"
-                    class="text-inherit no-underline transition-opacity duration-200 ease-in-out flex items-center gap-2 hover:opacity-80 hover:underline"
-                  >
-                    <img
-                      src="${this.containerState.skaband_addr}/sketch.dev.png"
-                      alt="sketch"
-                      class="w-5 h-5 md:w-[18px] md:h-[18px] sm:w-4 sm:h-4 rounded-sm"
-                    />
-                    sketch
-                  </a>`
-                : html`sketch`}
-            </h1>
-            <h2
-              class="m-0 p-0 text-gray-600 text-sm font-normal italic whitespace-nowrap overflow-hidden text-ellipsis"
-            >
-              ${this.slug}
-            </h2>
-          </div>
-
-          <!-- Container status info moved above tabs -->
-          <sketch-container-status
-            .state=${this.containerState}
-            id="container-status"
-          ></sketch-container-status>
-
-          <!-- Last Commit section moved to sketch-container-status -->
-
-          <!-- Views section with tabs -->
-          <sketch-view-mode-select
-            .diffLinesAdded=${this.containerState?.diff_lines_added || 0}
-            .diffLinesRemoved=${this.containerState?.diff_lines_removed || 0}
-          ></sketch-view-mode-select>
-
-          <!-- Control buttons and status -->
-          <div
-            class="flex items-center mb-0 flex-nowrap whitespace-nowrap flex-shrink-0 gap-4 pl-4 mr-12"
-          >
-            <button
-              id="stopButton"
-              class="bg-red-600 hover:bg-red-700 disabled:bg-red-300 disabled:cursor-not-allowed disabled:opacity-70 text-white border-none px-2.5 py-1 xl:px-1.5 rounded cursor-pointer text-xs mr-1.5 flex items-center gap-1.5 transition-colors"
-              ?disabled=${(this.containerState?.outstanding_llm_calls || 0) ===
-                0 &&
-              (this.containerState?.outstanding_tool_calls || []).length === 0}
-            >
-              <svg
-                class="w-4 h-4"
-                xmlns="http://www.w3.org/2000/svg"
-                viewBox="0 0 24 24"
-                fill="none"
-                stroke="currentColor"
-                stroke-width="2"
-                stroke-linecap="round"
-                stroke-linejoin="round"
-              >
-                <rect x="6" y="6" width="12" height="12" />
-              </svg>
-              <span class="xl:hidden">Stop</span>
-            </button>
-            <button
-              id="endButton"
-              class="bg-gray-600 hover:bg-gray-700 disabled:bg-gray-400 disabled:cursor-not-allowed disabled:opacity-70 text-white border-none px-2.5 py-1 xl:px-1.5 rounded cursor-pointer text-xs mr-1.5 flex items-center gap-1.5 transition-colors"
-              @click=${this._handleEndClick}
-            >
-              <svg
-                class="w-4 h-4"
-                xmlns="http://www.w3.org/2000/svg"
-                viewBox="0 0 24 24"
-                fill="none"
-                stroke="currentColor"
-                stroke-width="2"
-                stroke-linecap="round"
-                stroke-linejoin="round"
-              >
-                <path d="M18 6L6 18" />
-                <path d="M6 6l12 12" />
-              </svg>
-              <span class="xl:hidden">End</span>
-            </button>
-
-            <div
-              class="flex items-center text-xs mr-2.5 cursor-pointer"
-              @click=${this._handleNotificationsToggle}
-              title="${this.notificationsEnabled
-                ? "Disable"
-                : "Enable"} notifications when the agent completes its turn"
-            >
-              <div
-                class="w-5 h-5 relative inline-flex items-center justify-center"
-              >
-                <!-- Bell SVG icon -->
-                <svg
-                  xmlns="http://www.w3.org/2000/svg"
-                  width="16"
-                  height="16"
-                  fill="currentColor"
-                  viewBox="0 0 16 16"
-                  class="${!this.notificationsEnabled ? "relative z-10" : ""}"
-                >
-                  <path
-                    d="M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2zM8 1.918l-.797.161A4.002 4.002 0 0 0 4 6c0 .628-.134 2.197-.459 3.742-.16.767-.376 1.566-.663 2.258h10.244c-.287-.692-.502-1.49-.663-2.258C12.134 8.197 12 6.628 12 6a4.002 4.002 0 0 0-3.203-3.92L8 1.917zM14.22 12c.223.447.481.801.78 1H1c.299-.199.557-.553.78-1C2.68 10.2 3 6.88 3 6c0-2.42 1.72-4.44 4.005-4.901a1 1 0 1 1 1.99 0A5.002 5.002 0 0 1 13 6c0 .88.32 4.2 1.22 6z"
-                  />
-                </svg>
-                ${!this.notificationsEnabled
-                  ? html`<div
-                      class="absolute w-0.5 h-6 bg-red-600 rotate-45 origin-center"
-                    ></div>`
-                  : ""}
-              </div>
-            </div>
-
-            <sketch-call-status
-              .agentState=${this.containerState?.agent_state}
-              .llmCalls=${this.containerState?.outstanding_llm_calls || 0}
-              .toolCalls=${this.containerState?.outstanding_tool_calls || []}
-              .isIdle=${(() => {
-                const lastUserOrAgentMessage = this.getLastUserOrAgentMessage();
-                return lastUserOrAgentMessage
-                  ? lastUserOrAgentMessage.end_of_turn &&
-                      !lastUserOrAgentMessage.parent_conversation_id
-                  : true;
-              })()}
-              .isDisconnected=${this.connectionStatus === "disconnected"}
-            ></sketch-call-status>
-
-            <sketch-network-status
-              connection=${this.connectionStatus}
-              error=${this.connectionErrorMessage}
-            ></sketch-network-status>
-          </div>
-        </div>
+        ${this.renderTopBanner()}
 
         <!-- Main content area: scrollable, flex-1 -->
         <div
@@ -1009,130 +27,14 @@
                 ? "max-w-none w-full m-0 px-5"
                 : "max-w-6xl w-[calc(100%-40px)] mx-auto"} relative pb-2.5 pt-2.5 flex flex-col h-full"
           >
-            <!-- Chat View -->
-            <div
-              class="chat-view ${this.viewMode === "chat"
-                ? "view-active flex flex-col"
-                : "hidden"} w-full h-full"
-            >
-              <div
-                class="${this._todoPanelVisible && this.viewMode === "chat"
-                  ? "mr-[400px] xl:mr-[350px] lg:mr-[300px] md:mr-0 w-[calc(100%-400px)] xl:w-[calc(100%-350px)] lg:w-[calc(100%-300px)] md:w-full"
-                  : "mr-0"} flex-1 flex flex-col w-full h-full transition-[margin-right] duration-200 ease-in-out"
-              >
-                <sketch-timeline
-                  .messages=${this.messages}
-                  .scrollContainer=${this.scrollContainerRef}
-                  .agentState=${this.containerState?.agent_state}
-                  .llmCalls=${this.containerState?.outstanding_llm_calls || 0}
-                  .toolCalls=${this.containerState?.outstanding_tool_calls ||
-                  []}
-                  .firstMessageIndex=${this.containerState
-                    ?.first_message_index || 0}
-                  .state=${this.containerState}
-                  .dataManager=${this.dataManager}
-                ></sketch-timeline>
-              </div>
-            </div>
-
-            <!-- Todo panel positioned outside the main flow - only visible in chat view -->
-            <div
-              class="${this._todoPanelVisible && this.viewMode === "chat"
-                ? "block"
-                : "hidden"} fixed top-12 right-4 w-[400px] xl:w-[350px] lg:w-[300px] md:hidden z-[100] transition-[bottom] duration-200 ease-in-out"
-              style="bottom: var(--chat-input-height, 90px); background: linear-gradient(to bottom, #fafafa 0%, #fafafa 90%, rgba(250, 250, 250, 0.5) 95%, rgba(250, 250, 250, 0.2) 100%); border-left: 1px solid #e0e0e0;"
-            >
-              <sketch-todo-panel
-                .visible=${this._todoPanelVisible && this.viewMode === "chat"}
-              ></sketch-todo-panel>
-            </div>
-            <!-- Diff2 View -->
-            <div
-              class="diff2-view ${this.viewMode === "diff2"
-                ? "view-active flex-1 overflow-hidden min-h-0 flex flex-col h-full"
-                : "hidden"} w-full h-full"
-            >
-              <sketch-diff2-view
-                .commit=${this.currentCommitHash}
-                .gitService=${new DefaultGitDataService()}
-                @diff-comment="${this._handleDiffComment}"
-              ></sketch-diff2-view>
-            </div>
-
-            <!-- Terminal View -->
-            <div
-              class="terminal-view ${this.viewMode === "terminal"
-                ? "view-active flex flex-col"
-                : "hidden"} w-full h-full"
-            >
-              <sketch-terminal></sketch-terminal>
-            </div>
+            ${this.renderMainViews()}
           </div>
         </div>
 
-        <!-- Chat input fixed at bottom -->
-        <div
-          id="chat-input"
-          class="self-end w-full shadow-[0_-2px_10px_rgba(0,0,0,0.1)]"
-        >
-          <sketch-chat-input @send-chat="${this._sendChat}"></sketch-chat-input>
-        </div>
+        ${this.renderChatInput()}
       </div>
     `;
   }
-
-  /**
-   * Lifecycle callback when component is first connected to DOM
-   */
-  firstUpdated(): void {
-    if (this.viewMode !== "chat") {
-      return;
-    }
-
-    // Initial scroll to bottom when component is first rendered
-    setTimeout(
-      () => this.scrollTo({ top: this.scrollHeight, behavior: "smooth" }),
-      50,
-    );
-
-    // Setup stop button
-    const stopButton = this.renderRoot?.querySelector(
-      "#stopButton",
-    ) as HTMLButtonElement;
-    stopButton?.addEventListener("click", async () => {
-      try {
-        const response = await fetch("cancel", {
-          method: "POST",
-          headers: {
-            "Content-Type": "application/json",
-          },
-          body: JSON.stringify({ reason: "User clicked stop button" }),
-        });
-        if (!response.ok) {
-          console.error("Failed to cancel:", await response.text());
-        }
-      } catch (error) {
-        console.error("Error cancelling operation:", error);
-      }
-    });
-
-    // Setup end button
-    const endButton = this.renderRoot?.querySelector(
-      "#endButton",
-    ) as HTMLButtonElement;
-    // We're already using the @click binding in the HTML, so manual event listener not needed here
-
-    // Process any existing messages to find commit information
-    if (this.messages && this.messages.length > 0) {
-      // Update last commit info via container status component
-      if (this.containerStatusElement) {
-        this.containerStatusElement.updateLastCommitInfo(this.messages);
-      }
-    }
-
-    // Set up chat input height observer for todo panel
-    this.setupChatInputObserver();
-  }
 }
 
 declare global {
