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 {
