Initial commit
diff --git a/loop/webui/src/timeline.html b/loop/webui/src/timeline.html
new file mode 100644
index 0000000..46144c1
--- /dev/null
+++ b/loop/webui/src/timeline.html
@@ -0,0 +1,158 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>sketch coding assistant</title>
+    <!-- Import the diff2html CSS -->
+    <link rel="stylesheet" href="static/diff2html.min.css" />
+    <link rel="stylesheet" href="static/timeline.css" />
+    <link rel="stylesheet" href="static/diff2.css" />
+    <link rel="stylesheet" href="static/xterm.css" />
+    <link rel="stylesheet" href="static/tailwind.css" />
+  </head>
+  <body>
+    <div class="top-banner">
+      <div class="title-container">
+        <h1 class="banner-title">sketch coding assistant</h1>
+        <h2 id="chatTitle" class="chat-title"></h2>
+      </div>
+      <div class="info-grid">
+        <div class="info-item">
+          <a href="logs" class="text-blue-600 font-medium hover:text-blue-800 hover:underline">Logs</a>
+        </div>
+        <div class="info-item">
+          <a href="download" class="text-blue-600 font-medium hover:text-blue-800 hover:underline">Download</a>
+        </div>
+        <div class="info-item">
+          <span id="hostname" class="info-value">Loading...</span>
+        </div>
+        <div class="info-item">
+          <span id="workingDir" class="info-value">Loading...</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">Commit:</span>
+          <span id="initialCommit" class="info-value">Loading...</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">Msgs:</span>
+          <span id="messageCount" class="info-value">0</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">In:</span>
+          <span id="inputTokens" class="info-value">0</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">Cache Read:</span>
+          <span id="cacheReadInputTokens" class="info-value">0</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">Cache Create:</span>
+          <span id="cacheCreationInputTokens" class="info-value">0</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">Out:</span>
+          <span id="outputTokens" class="info-value">0</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">Cost:</span>
+          <span id="totalCost" class="info-value cost">$0.00</span>
+        </div>
+      </div>
+      <div class="refresh-control">
+        <div class="view-mode-buttons">
+          <button
+            id="showConversationButton"
+            class="emoji-button"
+            title="Conversation View"
+          >
+            💬
+          </button>
+          <button
+            id="showDiff2Button"
+            class="emoji-button"
+            title="Diff View"
+          >
+            ±
+          </button>
+          <button
+            id="showChartsButton"
+            class="emoji-button"
+            title="Charts View"
+          >
+            📈
+          </button>
+          <button
+            id="showTerminalButton"
+            class="emoji-button"
+            title="Terminal View"
+          >
+            💻
+          </button>
+        </div>
+        <button id="stopButton" class="refresh-button stop-button">Stop</button>
+        <div class="poll-updates">
+          <input type="checkbox" id="pollToggle" checked />
+          <label for="pollToggle">Poll</label>
+        </div>
+        <div class="status-container">
+          <span id="pollingIndicator" class="polling-indicator"></span>
+          <span id="statusText" class="status-text"></span>
+        </div>
+      </div>
+    </div>
+
+    <div class="timeline-container">
+      <div id="timeline" class="timeline empty"></div>
+      <div id="diff2View" class="diff-view" style="display: none">
+        <div id="diff2Container" class="diff-container">
+          <div id="diff-view-controls">
+            <div class="diff-view-format">
+              <label>
+                <input type="radio" name="diffViewFormat" value="side-by-side" checked> Side-by-side
+              </label>
+              <label>
+                <input type="radio" name="diffViewFormat" value="line-by-line"> Line-by-line
+              </label>
+            </div>
+          </div>
+          <div id="diff2htmlContent" class="diff2html-content"></div>
+        </div>
+      </div>
+      <div id="chartView" class="chart-view" style="display: none">
+        <div id="chartContainer" class="chart-container"></div>
+      </div>
+      <div id="terminalView" class="terminal-view" style="display: none">
+        <div id="terminalContainer" class="terminal-container"></div>
+      </div>
+      <div id="diffCommentBox" class="diff-comment-box" style="display: none">
+        <h3>Add a comment</h3>
+        <div class="selected-line">
+          Line:
+          <pre id="selectedLine"></pre>
+        </div>
+        <textarea
+          id="diffCommentInput"
+          placeholder="Enter your comment about this line..."
+        ></textarea>
+        <div class="diff-comment-buttons">
+          <button id="submitDiffComment">Add Comment</button>
+          <button id="cancelDiffComment">Cancel</button>
+        </div>
+      </div>
+    </div>
+
+    <div class="chat-container">
+      <div class="chat-input-wrapper">
+        <textarea
+          id="chatInput"
+          placeholder="Type your message here and press Enter to send..."
+          autofocus
+        ></textarea>
+        <button id="sendChatButton">Send</button>
+      </div>
+    </div>
+
+    <script src="static/timeline.js"></script>
+  </body>
+</html>