pi-kanban 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,674 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Pi Kanban</title>
7
+ <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='6' fill='%231a1a1a'/%3E%3Crect x='4' y='6' width='7' height='20' rx='2' fill='%23e8927c'/%3E%3Crect x='13' y='6' width='7' height='14' rx='2' fill='%23e8927c'/%3E%3Crect x='22' y='6' width='7' height='8' rx='2' fill='%23e8927c'/%3E%3C/svg%3E">
8
+ <link rel="manifest" href="/manifest.json">
9
+ <meta name="theme-color" content="#101114" media="(prefers-color-scheme: dark)">
10
+ <meta name="theme-color" content="#e8e6e3" media="(prefers-color-scheme: light)">
11
+ <meta name="mobile-web-app-capable" content="yes">
12
+ <meta name="apple-mobile-web-app-capable" content="yes">
13
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
14
+ <link rel="apple-touch-icon" href="/icons/icon-192.png">
15
+ <link rel="preconnect" href="https://fonts.googleapis.com">
16
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
17
+ <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Playfair+Display:wght@400;500;600&display=swap" rel="stylesheet">
18
+ <link rel="stylesheet" href="/style.css">
19
+ <script defer src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
20
+ <script defer src="https://cdn.jsdelivr.net/npm/dompurify@3/dist/purify.min.js"></script>
21
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11/build/styles/github-dark.min.css" id="hljs-theme-dark">
22
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11/build/styles/github.min.css" id="hljs-theme-light" disabled>
23
+ <script defer src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11/build/highlight.min.js"></script>
24
+ <script defer src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
25
+ <script defer src="/app.js"></script>
26
+ </head>
27
+ <body>
28
+ <div id="offline-overlay" class="offline-overlay">
29
+ <div class="offline-card">
30
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
31
+ <rect width="512" height="512" rx="96" fill="#1a1a1a"/>
32
+ <rect x="64" y="96" width="112" height="320" rx="32" fill="#e8927c"/>
33
+ <rect x="208" y="96" width="112" height="224" rx="32" fill="#e8927c"/>
34
+ <rect x="352" y="96" width="112" height="128" rx="32" fill="#e8927c"/>
35
+ </svg>
36
+ <h2>Server Not Running</h2>
37
+ <p>The dashboard needs the pi-kanban server to stream live task data. Start it with:</p>
38
+ <code>npx pi-kanban</code>
39
+ <button class="btn btn-primary" onclick="location.reload()">Retry Connection</button>
40
+ <div class="offline-status" id="offline-status" aria-live="polite"></div>
41
+ </div>
42
+ </div>
43
+ <a href="#main-content" class="skip-link">Skip to main content</a>
44
+ <div class="app">
45
+ <!-- Sidebar -->
46
+ <aside class="sidebar">
47
+ <header class="sidebar-header">
48
+ <div class="logo">
49
+ <div class="logo-mark">
50
+ <svg viewBox="4 6 16 12" fill="none" stroke="currentColor" stroke-width="2.5">
51
+ <path d="M5 13l4 4L19 7"/>
52
+ </svg>
53
+ </div>
54
+ <span class="logo-text">Dashboard</span>
55
+ </div>
56
+ <div id="connection-status" class="connection">
57
+ <span class="connection-dot"></span>
58
+ <span>Connecting</span>
59
+ </div>
60
+ <button id="sidebar-toggle" class="sidebar-toggle-btn" onclick="toggleSidebar()" title="Toggle sidebar" aria-label="Toggle sidebar">
61
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
62
+ <path d="M15 18l-6-6 6-6"/>
63
+ </svg>
64
+ </button>
65
+ </header>
66
+
67
+ <!-- Tasks -->
68
+ <div class="sidebar-section flex-1">
69
+ <div class="section-header" onclick="toggleSection('sessions-filters', 'sessions-chevron')" style="cursor: pointer;">
70
+ <span>Sessions</span>
71
+ <svg id="sessions-chevron" class="collapse-chevron" viewBox="0 0 24 24">
72
+ <path d="M6 9l6 6 6-6"/>
73
+ </svg>
74
+ </div>
75
+ <div id="sessions-filters" class="collapsible-section">
76
+ <div class="search-container">
77
+ <input
78
+ id="search-input"
79
+ type="text"
80
+ class="search-input"
81
+ placeholder="Search tasks, sessions, projects..."
82
+ oninput="handleSearch(this.value)"
83
+ />
84
+ <button id="search-clear-btn" class="search-clear" onclick="clearSearch()" title="Clear search" aria-label="Clear search">
85
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
86
+ <path d="M18 6L6 18M6 6l12 12"/>
87
+ </svg>
88
+ </button>
89
+ </div>
90
+ <div class="filter-row">
91
+ <select id="project-filter" class="filter-dropdown" onchange="filterByProject(this.value)" aria-label="Filter by project">
92
+ <option value="">All Projects</option>
93
+ </select>
94
+ <select id="session-filter" class="filter-dropdown" onchange="filterBySessions(this.value)" aria-label="Filter by session status">
95
+ <option value="all">All Sessions</option>
96
+ <option value="active">Active Only</option>
97
+ </select>
98
+ </div>
99
+ <div class="filter-row">
100
+ <select id="session-limit" class="filter-dropdown" onchange="changeSessionLimit(this.value)" aria-label="Number of sessions to show">
101
+ <option value="10">Show 10</option>
102
+ <option value="20">Show 20</option>
103
+ <option value="50">Show 50</option>
104
+ <option value="all">Show All</option>
105
+ </select>
106
+ <button class="icon-btn reset-btn" onclick="resetState()" title="Reset all filters" aria-label="Reset all filters">
107
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16">
108
+ <path d="M3 12a9 9 0 1 1 9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/>
109
+ <path d="M3 22v-6h6"/>
110
+ </svg>
111
+ </button>
112
+ </div>
113
+ </div>
114
+ <div id="sessions-list" class="sessions-list"></div>
115
+ </div>
116
+
117
+ <div class="sidebar-footer" id="sidebar-footer"></div>
118
+ <div class="sidebar-resize-handle" id="sidebar-resize"></div>
119
+ </aside>
120
+
121
+ <!-- Main -->
122
+ <main class="main">
123
+ <div id="no-session" class="empty-state">
124
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
125
+ <path d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
126
+ </svg>
127
+ <p>Select a session to view tasks</p>
128
+ </div>
129
+
130
+ <div id="session-view" class="session-view">
131
+ <header class="view-header">
132
+ <div>
133
+ <h1 id="session-title" class="view-title">Session</h1>
134
+ <p id="session-meta" class="view-meta"></p>
135
+ </div>
136
+ <div class="view-actions">
137
+ <div class="view-progress">
138
+ <div class="progress-bar">
139
+ <div id="progress-bar" class="progress-fill" style="width: 0%"></div>
140
+ </div>
141
+ <span id="progress-percent" class="progress-text">0%</span>
142
+ </div>
143
+ <button id="message-toggle" class="icon-btn" onclick="toggleMessagePanel()" title="Session log (L)" aria-label="Toggle session log">
144
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
145
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
146
+ </svg>
147
+ </button>
148
+ <button id="scratchpad-toggle" class="icon-btn" onclick="toggleScratchpad()" title="Scratchpad (N)" aria-label="Toggle scratchpad">
149
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
150
+ <path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/>
151
+ </svg>
152
+ </button>
153
+ <button class="icon-btn" onclick="showStorageManager()" title="Storage manager (Shift+S)" aria-label="Storage manager">
154
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
155
+ <ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/>
156
+ </svg>
157
+ </button>
158
+ <button id="theme-toggle" class="icon-btn" onclick="toggleTheme()" title="Toggle theme" aria-label="Toggle theme">
159
+ <svg id="theme-icon-dark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
160
+ <path d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/>
161
+ </svg>
162
+ <svg id="theme-icon-light" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:none">
163
+ <circle cx="12" cy="12" r="5"/>
164
+ <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
165
+ </svg>
166
+ </button>
167
+ <button class="icon-btn" onclick="showHelpModal()" title="Keyboard shortcuts (?)" aria-label="Keyboard shortcuts">
168
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
169
+ <circle cx="12" cy="12" r="10"/>
170
+ <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/>
171
+ <circle cx="12" cy="17" r="0.5" fill="currentColor"/>
172
+ </svg>
173
+ </button>
174
+ <a href="https://github.com/NikiforovAll/pi-kanban" target="_blank" class="icon-btn" title="View on GitHub" aria-label="View on GitHub">
175
+ <svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16">
176
+ <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/>
177
+ </svg>
178
+ </a>
179
+ </div>
180
+ </header>
181
+
182
+ <div class="kanban" id="main-content">
183
+ <div class="kanban-column" aria-label="Pending tasks">
184
+ <div class="column-header">
185
+ <span class="column-dot pending"></span>
186
+ <span class="column-title pending">Pending</span>
187
+ <span id="pending-count" class="column-count pending">0</span>
188
+ </div>
189
+ <div id="pending-tasks" class="column-tasks" role="list" data-status="pending" ondragover="onColumnDragOver(event)" ondragleave="onColumnDragLeave(event)" ondrop="onColumnDrop(event)"></div>
190
+ </div>
191
+
192
+ <div class="kanban-column" aria-label="In progress tasks">
193
+ <div class="column-header">
194
+ <span class="column-dot in-progress"></span>
195
+ <span class="column-title in-progress">In Progress</span>
196
+ <span id="in-progress-count" class="column-count in-progress">0</span>
197
+ </div>
198
+ <div id="in-progress-tasks" class="column-tasks" role="list" data-status="in_progress" ondragover="onColumnDragOver(event)" ondragleave="onColumnDragLeave(event)" ondrop="onColumnDrop(event)"></div>
199
+ </div>
200
+
201
+ <div class="kanban-column" aria-label="Completed tasks">
202
+ <div class="column-header">
203
+ <span class="column-dot completed"></span>
204
+ <span class="column-title completed">Completed</span>
205
+ <span id="completed-count" class="column-count completed">0</span>
206
+ </div>
207
+ <div id="completed-tasks" class="column-tasks" role="list" data-status="completed" ondragover="onColumnDragOver(event)" ondragleave="onColumnDragLeave(event)" ondrop="onColumnDrop(event)"></div>
208
+ </div>
209
+ </div>
210
+ <div id="agent-footer" class="agent-footer">
211
+ <div class="agent-footer-header" onclick="toggleAgentFooter()">
212
+ <span id="agent-footer-label">Agents</span>
213
+ <button class="agent-footer-toggle" id="agent-footer-toggle" aria-label="Toggle agent panel">&#x25BE;</button>
214
+ </div>
215
+ <div class="agent-footer-content" id="agent-footer-content"></div>
216
+ </div>
217
+ </div>
218
+ </main>
219
+
220
+ <!-- Detail panel -->
221
+ <aside id="detail-panel" class="detail-panel">
222
+ <div class="panel-resize-handle" id="detail-panel-resize"></div>
223
+ <header class="detail-header">
224
+ <h3>Task Details</h3>
225
+ <div style="display: flex; gap: 8px; align-items: center;">
226
+ <button id="delete-task-btn" class="icon-btn" title="Delete task (D)" aria-label="Delete task" style="color: #ef4444; border-color: #ef4444; display: none;">
227
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
228
+ <path d="M3 6h18M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/>
229
+ </svg>
230
+ </button>
231
+ <button id="close-detail" class="detail-close" aria-label="Close detail panel">
232
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
233
+ <path d="M6 18L18 6M6 6l12 12"/>
234
+ </svg>
235
+ </button>
236
+ </div>
237
+ </header>
238
+ <div id="detail-content" class="detail-content"></div>
239
+ </aside>
240
+
241
+ <aside id="message-panel" class="message-panel">
242
+ <div class="panel-resize-handle" id="message-panel-resize"></div>
243
+ <header class="message-panel-header">
244
+ <h3>Session Log</h3>
245
+ <div style="display:flex;gap:4px;align-items:center;">
246
+ <button class="icon-btn" onclick="openLiveLatestMessage()" title="Follow latest message (Shift+M)" aria-label="Follow latest message">
247
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
248
+ </button>
249
+ <button class="detail-close" onclick="toggleMessagePanel()" aria-label="Close message panel">
250
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
251
+ <path d="M6 18L18 6M6 6l12 12"/>
252
+ </svg>
253
+ </button>
254
+ </div>
255
+ </header>
256
+ <div id="message-panel-pinned"></div>
257
+ <div id="message-panel-content" class="message-panel-content"></div>
258
+ </aside>
259
+ </div>
260
+
261
+
262
+
263
+ <!-- Message Detail Modal -->
264
+ <div id="msg-detail-modal" class="modal-overlay" onclick="closeMsgDetailModal()">
265
+ <div class="modal" onclick="event.stopPropagation()" style="max-width: 860px; width: 90vw; max-height: 90vh; display: flex; flex-direction: column;">
266
+ <div class="modal-header">
267
+ <h3 class="modal-title" id="msg-detail-title">Message</h3>
268
+ <div style="display:flex;gap:4px;align-items:center;">
269
+ <button id="msg-detail-agent-btn" class="icon-btn" aria-label="View Agent" title="View Agent" style="display:none" onclick="closeMsgDetailModal();showAgentModal(this.dataset.agentId)">
270
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="16" height="16"><rect x="4" y="10" width="16" height="10" rx="2"/><circle cx="9" cy="15" r="1"/><circle cx="15" cy="15" r="1"/><path d="M12 2v4"/><path d="M2 14h2"/><path d="M20 14h2"/></svg>
271
+ </button>
272
+ <button id="msg-detail-pin-btn" class="icon-btn" aria-label="Pin message" title="Pin message" onclick="togglePinFromModal()">
273
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></svg>
274
+ </button>
275
+ <button class="icon-btn" aria-label="Copy to clipboard" title="Copy to clipboard" onclick="copyMsgToClipboard(this)">
276
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
277
+ </button>
278
+ <button class="icon-btn" aria-label="Open in editor" title="Open in editor" onclick="openMsgInEditor()">
279
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
280
+ </button>
281
+ <button id="msg-detail-fullscreen-btn" class="icon-btn" aria-label="Toggle fullscreen" title="Toggle fullscreen" onclick="toggleModalFullscreen('msg-detail-modal')">
282
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>
283
+ </button>
284
+ <button class="modal-close" aria-label="Close" onclick="closeMsgDetailModal()">
285
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6L6 18M6 6l12 12"/></svg>
286
+ </button>
287
+ </div>
288
+ </div>
289
+ <div class="modal-body" style="flex: 0 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden;">
290
+ <div id="msg-detail-body" class="rendered-md" style="word-break: break-word; font-size: 13px; line-height: 1.6; overflow-y: auto; flex: 0 1 auto; min-height: 0; padding-right: 8px;"></div>
291
+ <div id="msg-detail-meta" style="margin-top: 12px; font-size: 11px; color: var(--text-muted); flex-shrink: 0;"></div>
292
+ </div>
293
+ </div>
294
+ </div>
295
+
296
+ <!-- Markdown Preview Modal -->
297
+ <div id="preview-modal" class="modal-overlay" style="z-index:10002;" onclick="closePreviewModal()">
298
+ <div class="modal preview-modal-dialog" onclick="event.stopPropagation()">
299
+ <div class="modal-header">
300
+ <h3 class="modal-title" id="preview-modal-title">Preview</h3>
301
+ <div style="display:flex;gap:4px;align-items:center;">
302
+ <button id="preview-link-btn" class="icon-btn" aria-label="Link to current session" title="Link to current session" onclick="togglePreviewSessionLink()">
303
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>
304
+ </button>
305
+ <button class="icon-btn" aria-label="Open in editor" title="Open in editor" onclick="openPreviewInEditor()">
306
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
307
+ </button>
308
+ <button id="preview-modal-fullscreen-btn" class="icon-btn" aria-label="Toggle fullscreen" title="Toggle fullscreen" onclick="toggleModalFullscreen('preview-modal')">
309
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>
310
+ </button>
311
+ <button class="modal-close" aria-label="Close" onclick="closePreviewModal()">
312
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6L6 18M6 6l12 12"/></svg>
313
+ </button>
314
+ </div>
315
+ </div>
316
+ <div class="modal-body" style="flex: 0 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden;">
317
+ <div id="preview-modal-body" class="rendered-md" style="word-break: break-word; font-size: 13px; line-height: 1.6; overflow-y: auto; flex: 0 1 auto; min-height: 0; padding-right: 8px;"></div>
318
+ <div id="preview-modal-meta" style="margin-top: 12px; font-size: 11px; color: var(--text-muted); flex-shrink: 0;"></div>
319
+ </div>
320
+ </div>
321
+ </div>
322
+
323
+ <!-- Help Modal -->
324
+ <div id="help-modal" class="modal-overlay" onclick="closeHelpModal()">
325
+ <div class="modal" onclick="event.stopPropagation()">
326
+ <div class="modal-header">
327
+ <h3 class="modal-title">Keyboard Shortcuts</h3>
328
+ <button class="modal-close" aria-label="Close dialog" onclick="closeHelpModal()">
329
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
330
+ <path d="M18 6L6 18M6 6l12 12"/>
331
+ </svg>
332
+ </button>
333
+ </div>
334
+ <div class="modal-body">
335
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 0 24px;">
336
+ <div style="display: grid; gap: 16px; align-content: start;">
337
+ <div>
338
+ <h4 style="margin: 0 0 8px 0; color: var(--text-primary); font-size: 14px; font-weight: 600;">Global</h4>
339
+ <table style="width: 100%; font-size: 13px;">
340
+ <tr>
341
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">?</kbd></td>
342
+ <td style="padding: 4px 0; color: var(--text-primary);">Show keyboard shortcuts</td>
343
+ </tr>
344
+ <tr>
345
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">Esc</kbd></td>
346
+ <td style="padding: 4px 0; color: var(--text-primary);">Close panels or cancel</td>
347
+ </tr>
348
+ <tr>
349
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">Tab</kbd></td>
350
+ <td style="padding: 4px 0; color: var(--text-primary);">Toggle sidebar / board focus</td>
351
+ </tr>
352
+ <tr>
353
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">[</kbd></td>
354
+ <td style="padding: 4px 0; color: var(--text-primary);">Toggle sidebar collapse</td>
355
+ </tr>
356
+ <tr>
357
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">R</kbd></td>
358
+ <td style="padding: 4px 0; color: var(--text-primary);">Reload page</td>
359
+ </tr>
360
+ </table>
361
+ </div>
362
+ <div>
363
+ <h4 style="margin: 0 0 8px 0; color: var(--text-primary); font-size: 14px; font-weight: 600;">Navigation</h4>
364
+ <table style="width: 100%; font-size: 13px;">
365
+ <tr>
366
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">J</kbd> / <kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">&darr;</kbd></td>
367
+ <td style="padding: 4px 0; color: var(--text-primary);">Next task in column</td>
368
+ </tr>
369
+ <tr>
370
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">K</kbd> / <kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">&uarr;</kbd></td>
371
+ <td style="padding: 4px 0; color: var(--text-primary);">Previous task in column</td>
372
+ </tr>
373
+ <tr>
374
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">H</kbd> / <kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">&larr;</kbd></td>
375
+ <td style="padding: 4px 0; color: var(--text-primary);">Move to left column</td>
376
+ </tr>
377
+ <tr>
378
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">L</kbd> / <kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">&rarr;</kbd></td>
379
+ <td style="padding: 4px 0; color: var(--text-primary);">Move to right column</td>
380
+ </tr>
381
+ <tr>
382
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">Enter</kbd></td>
383
+ <td style="padding: 4px 0; color: var(--text-primary);">Toggle task detail panel</td>
384
+ </tr>
385
+ </table>
386
+ </div>
387
+ </div>
388
+ <div style="align-content: start;">
389
+ <h4 style="margin: 0 0 8px 0; color: var(--text-primary); font-size: 14px; font-weight: 600;">Actions</h4>
390
+ <table style="width: 100%; font-size: 13px;">
391
+ <tr>
392
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">P</kbd></td>
393
+ <td style="padding: 4px 0; color: var(--text-primary);">Open session plan</td>
394
+ </tr>
395
+ <tr>
396
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">I</kbd></td>
397
+ <td style="padding: 4px 0; color: var(--text-primary);">Open session info</td>
398
+ </tr>
399
+ <tr>
400
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">D</kbd></td>
401
+ <td style="padding: 4px 0; color: var(--text-primary);">Delete selected task</td>
402
+ </tr>
403
+ <tr>
404
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">N</kbd></td>
405
+ <td style="padding: 4px 0; color: var(--text-primary);">Toggle scratchpad</td>
406
+ </tr>
407
+ <tr>
408
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">.</kbd></td>
409
+ <td style="padding: 4px 0; color: var(--text-primary);">Pin/unpin selected session</td>
410
+ </tr>
411
+ <tr>
412
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">&gt;</kbd></td>
413
+ <td style="padding: 4px 0; color: var(--text-primary);">Toggle sticky on selected session</td>
414
+ </tr>
415
+ <tr>
416
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">T</kbd></td>
417
+ <td style="padding: 4px 0; color: var(--text-primary);">Toggle theme</td>
418
+ </tr>
419
+ <tr>
420
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">Shift+L</kbd></td>
421
+ <td style="padding: 4px 0; color: var(--text-primary);">Toggle session log</td>
422
+ </tr>
423
+ <tr>
424
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">Shift+M</kbd></td>
425
+ <td style="padding: 4px 0; color: var(--text-primary);">Open last message detail</td>
426
+ </tr>
427
+ <tr>
428
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">Shift+S</kbd></td>
429
+ <td style="padding: 4px 0; color: var(--text-primary);">Storage manager</td>
430
+ </tr>
431
+ <tr>
432
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">Shift+C</kbd></td>
433
+ <td style="padding: 4px 0; color: var(--text-primary);">Copy session id</td>
434
+ </tr>
435
+ <tr>
436
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">J/K</kbd></td>
437
+ <td style="padding: 4px 0; color: var(--text-primary);">Navigate messages in detail modal</td>
438
+ </tr>
439
+ <tr>
440
+ <td style="padding: 4px 0; color: var(--text-secondary);"><kbd style="background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-family: monospace;">Ctrl+D</kbd></td>
441
+ <td style="padding: 4px 0; color: var(--text-primary);">Dismiss current session</td>
442
+ </tr>
443
+ </table>
444
+ </div>
445
+ </div>
446
+ </div>
447
+ <div class="modal-footer">
448
+ <button class="btn btn-primary" onclick="closeHelpModal()">Got it</button>
449
+ </div>
450
+ </div>
451
+ </div>
452
+
453
+ <!-- Delete Confirmation Modal -->
454
+ <div id="delete-confirm-modal" class="modal-overlay" onclick="closeDeleteConfirmModal()">
455
+ <div class="modal modal-sm" onclick="event.stopPropagation()">
456
+ <div class="modal-header">
457
+ <h3 class="modal-title">Delete Task</h3>
458
+ <button class="modal-close" aria-label="Close dialog" onclick="closeDeleteConfirmModal()">
459
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
460
+ <path d="M18 6L6 18M6 6l12 12"/>
461
+ </svg>
462
+ </button>
463
+ </div>
464
+ <div class="modal-body">
465
+ <p id="delete-confirm-message" style="margin: 0; color: var(--text-primary);"></p>
466
+ </div>
467
+ <div class="modal-footer">
468
+ <button id="delete-cancel-btn" class="btn btn-secondary" onclick="closeDeleteConfirmModal()">Cancel</button>
469
+ <button id="delete-confirm-btn" class="btn btn-primary" onclick="confirmDelete()" style="background: #ef4444; border-color: #ef4444;">Delete</button>
470
+ </div>
471
+ </div>
472
+ </div>
473
+
474
+ <!-- Delete All Session Tasks Confirmation Modal -->
475
+ <div id="delete-session-tasks-modal" class="modal-overlay" onclick="closeDeleteSessionTasksModal()">
476
+ <div class="modal" onclick="event.stopPropagation()">
477
+ <div class="modal-header">
478
+ <h3 class="modal-title">Delete All Tasks</h3>
479
+ <button class="modal-close" aria-label="Close dialog" onclick="closeDeleteSessionTasksModal()">
480
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
481
+ <path d="M18 6L6 18M6 6l12 12"/>
482
+ </svg>
483
+ </button>
484
+ </div>
485
+ <div class="modal-body">
486
+ <p id="delete-session-tasks-message" style="margin: 0 0 12px 0; color: var(--text-primary);"></p>
487
+ <p style="margin: 0; font-size: 13px; color: var(--text-secondary);">This action cannot be undone.</p>
488
+ </div>
489
+ <div class="modal-footer">
490
+ <button class="btn btn-secondary" onclick="closeDeleteSessionTasksModal()">Cancel</button>
491
+ <button class="btn btn-primary" onclick="confirmDeleteSessionTasks()" style="background: #ef4444; border-color: #ef4444;">Delete All</button>
492
+ </div>
493
+ </div>
494
+ </div>
495
+
496
+ <!-- Delete Result Modal -->
497
+ <div id="delete-result-modal" class="modal-overlay" onclick="closeDeleteResultModal()">
498
+ <div class="modal" onclick="event.stopPropagation()">
499
+ <div class="modal-header">
500
+ <h3 class="modal-title">Deletion Result</h3>
501
+ <button class="modal-close" aria-label="Close dialog" onclick="closeDeleteResultModal()">
502
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
503
+ <path d="M18 6L6 18M6 6l12 12"/>
504
+ </svg>
505
+ </button>
506
+ </div>
507
+ <div class="modal-body">
508
+ <p id="delete-result-message" style="margin: 0; color: var(--text-primary);"></p>
509
+ <div id="delete-result-details" style="margin-top: 12px; font-size: 13px; color: var(--text-secondary);"></div>
510
+ </div>
511
+ <div class="modal-footer">
512
+ <button class="btn btn-primary" onclick="closeDeleteResultModal()">Close</button>
513
+ </div>
514
+ </div>
515
+ </div>
516
+
517
+ <!-- Session Info Modal -->
518
+ <div id="session-info-modal" class="modal-overlay" onclick="closeSessionInfoModal()">
519
+ <div class="modal" onclick="event.stopPropagation()">
520
+ <div class="modal-header">
521
+ <h3 id="session-info-modal-title" class="modal-title">Session</h3>
522
+ <div style="display:flex;align-items:center;gap:4px;">
523
+ <button id="session-info-sticky-btn" class="icon-btn" style="display:none" title="Sticky pin — always show at top" onclick="toggleSessionSticky(_infoModalSessionId); updateStickyBtnState()">
524
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2 L15 9 L22 9 L17 14 L19 22 L12 18 L5 22 L7 14 L2 9 L9 9 Z"/></svg>
525
+ </button>
526
+ <button class="modal-close" aria-label="Close dialog" onclick="closeSessionInfoModal()">
527
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
528
+ <path d="M18 6L6 18M6 6l12 12"/>
529
+ </svg>
530
+ </button>
531
+ </div>
532
+ </div>
533
+ <div id="session-info-modal-body" class="modal-body"></div>
534
+ <div class="modal-footer">
535
+ <button id="session-info-dismiss-btn" class="btn btn-secondary" onclick="dismissAndAdvance(_infoModalSessionId); closeSessionInfoModal()">Dismiss</button>
536
+ <button class="btn btn-primary" onclick="closeSessionInfoModal()">Close</button>
537
+ </div>
538
+ </div>
539
+ </div>
540
+
541
+ <!-- Plan Modal (stacked on top of info modal) -->
542
+ <div id="plan-modal" class="modal-overlay plan-modal-overlay" onclick="closePlanModal()">
543
+ <div class="modal plan-modal" onclick="event.stopPropagation()">
544
+ <div class="modal-header">
545
+ <h3 id="plan-modal-title" class="modal-title">Plan</h3>
546
+ <div style="display:flex;align-items:center;gap:4px;">
547
+ <button class="icon-btn" aria-label="Open in editor" title="Open in editor" onclick="openPlanInEditor()">
548
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
549
+ </button>
550
+ <button class="icon-btn" aria-label="Copy plan" title="Copy plan" onclick="copyWithFeedback(_pendingPlanContent||'',this)">
551
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg>
552
+ </button>
553
+ <button id="plan-modal-fullscreen-btn" class="icon-btn" aria-label="Toggle fullscreen" title="Toggle fullscreen" onclick="toggleModalFullscreen('plan-modal')">
554
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>
555
+ </button>
556
+ <button class="modal-close" aria-label="Close dialog" onclick="closePlanModal()">
557
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
558
+ <path d="M18 6L6 18M6 6l12 12"/>
559
+ </svg>
560
+ </button>
561
+ </div>
562
+ </div>
563
+ <div id="plan-modal-body" class="modal-body detail-desc rendered-md" style="overflow-y: auto; flex: 0 1 auto; min-height: 0;"></div>
564
+ <div class="modal-footer">
565
+ <button class="btn btn-primary" onclick="closePlanModal()">Close</button>
566
+ </div>
567
+ </div>
568
+ </div>
569
+
570
+ <!-- Blocked Task Warning Modal -->
571
+ <div id="blocked-task-modal" class="modal-overlay" onclick="closeBlockedTaskModal()">
572
+ <div class="modal modal-sm" onclick="event.stopPropagation()">
573
+ <div class="modal-header">
574
+ <h3 class="modal-title" style="display: flex; align-items: center; gap: 8px;">
575
+ <svg viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2" style="width: 20px; height: 20px;">
576
+ <circle cx="12" cy="12" r="10"/>
577
+ <line x1="15" y1="9" x2="9" y2="15"/>
578
+ <line x1="9" y1="9" x2="15" y2="15"/>
579
+ </svg>
580
+ Cannot Start Blocked Task
581
+ </h3>
582
+ <button class="modal-close" aria-label="Close dialog" onclick="closeBlockedTaskModal()">
583
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
584
+ <path d="M18 6L6 18M6 6l12 12"/>
585
+ </svg>
586
+ </button>
587
+ </div>
588
+ <div class="modal-body">
589
+ <div id="blocked-task-message" style="color: var(--text-primary); line-height: 1.6;"></div>
590
+ </div>
591
+ <div class="modal-footer">
592
+ <button class="btn btn-primary" onclick="closeBlockedTaskModal()">OK</button>
593
+ </div>
594
+ </div>
595
+ </div>
596
+
597
+ <div id="agent-modal" class="modal-overlay plan-modal-overlay" onclick="closeAgentModal()">
598
+ <div class="modal plan-modal" onclick="event.stopPropagation()">
599
+ <div class="modal-header">
600
+ <h3 id="agent-modal-title" class="modal-title">Agent</h3>
601
+ <div style="display:flex;align-items:center;gap:4px;">
602
+ <button id="agent-modal-log-btn" class="icon-btn" aria-label="View session log" title="View session log" onclick="viewAgentLog(currentAgentModalId)">
603
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
604
+ </button>
605
+ <button id="agent-modal-pin-btn" class="icon-btn" aria-label="Pin agent" title="Pin agent" onclick="togglePinFromAgentModal()">
606
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></svg>
607
+ </button>
608
+ <button class="icon-btn" id="agent-modal-copy-all" aria-label="Copy all" title="Copy prompt + response" onclick="copyAgentModalAll(this)">
609
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg>
610
+ </button>
611
+ <button id="agent-modal-fullscreen-btn" class="icon-btn" aria-label="Toggle fullscreen" title="Toggle fullscreen" onclick="toggleModalFullscreen('agent-modal')">
612
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>
613
+ </button>
614
+ <button class="modal-close" aria-label="Close dialog" onclick="closeAgentModal()">
615
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
616
+ <path d="M18 6L6 18M6 6l12 12"/>
617
+ </svg>
618
+ </button>
619
+ </div>
620
+ </div>
621
+ <div id="agent-modal-body" class="modal-body" style="overflow-y: auto; overflow-x: hidden; flex: 0 1 auto; min-height: 0;"></div>
622
+ <div class="modal-footer">
623
+ <button id="agent-modal-dismiss-btn" class="btn agent-dismiss-btn" style="display:none" onclick="dismissAgent(currentAgentModalId);closeAgentModal()">Dismiss</button>
624
+ <button class="btn btn-primary" onclick="closeAgentModal()">Close</button>
625
+ </div>
626
+ </div>
627
+ </div>
628
+ <div id="scratchpad-modal" class="modal-overlay" onclick="closeScratchpad()">
629
+ <div class="modal scratchpad-modal" onclick="event.stopPropagation()">
630
+ <div class="modal-header">
631
+ <h3 class="modal-title">Scratchpad</h3>
632
+ <button class="modal-close" aria-label="Close dialog" onclick="closeScratchpad()">
633
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
634
+ <path d="M18 6L6 18M6 6l12 12"/>
635
+ </svg>
636
+ </button>
637
+ </div>
638
+ <div class="modal-body">
639
+ <textarea id="scratchpad-textarea" class="scratchpad-textarea" placeholder="Jot down ideas, notes, reminders..."></textarea>
640
+ </div>
641
+ <div class="modal-footer scratchpad-footer">
642
+ <span id="scratchpad-charcount" class="scratchpad-charcount">0 chars</span>
643
+ <button class="btn btn-primary" onclick="closeScratchpad()">Close</button>
644
+ </div>
645
+ </div>
646
+ </div>
647
+
648
+ <div id="storage-modal" class="modal-overlay" onclick="closeStorageManager()">
649
+ <div class="modal storage-modal" onclick="event.stopPropagation()">
650
+ <div class="modal-header">
651
+ <h3 class="modal-title">Storage Manager</h3>
652
+ <div style="display:flex;align-items:center;gap:8px;">
653
+ <span id="storage-total" class="storage-total"></span>
654
+ <button class="modal-close" aria-label="Close dialog" onclick="closeStorageManager()">
655
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6L6 18M6 6l12 12"/></svg>
656
+ </button>
657
+ </div>
658
+ </div>
659
+ <div class="storage-tabs">
660
+ <button class="storage-tab active" data-tab="sessions" onclick="switchStorageTab('sessions')">Sessions</button>
661
+ <button class="storage-tab" data-tab="scratchpads" onclick="switchStorageTab('scratchpads')">Scratchpads</button>
662
+ <button class="storage-tab" data-tab="linked-docs" onclick="switchStorageTab('linked-docs')">Linked Docs</button>
663
+ </div>
664
+ <div class="modal-body" id="storage-modal-body" style="overflow-y:auto;min-height:200px;max-height:60vh;padding-top:16px;padding-right:8px;"></div>
665
+ <div class="modal-footer">
666
+ <button id="storage-cleanup-btn" class="btn btn-secondary" onclick="cleanupOrphanedStorage()">Clean Orphaned</button>
667
+ <button class="btn btn-primary" onclick="closeStorageManager()">Close</button>
668
+ </div>
669
+ </div>
670
+ </div>
671
+
672
+ <div id="toast" class="toast"></div>
673
+ </body>
674
+ </html>