@vheins/local-memory-mcp 0.1.44 → 0.2.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.
Files changed (67) hide show
  1. package/dist/dashboard/dashboard.test.js +11 -3
  2. package/dist/dashboard/dashboard.test.js.map +1 -1
  3. package/dist/dashboard/public/app.js +541 -93
  4. package/dist/dashboard/public/index.html +1070 -718
  5. package/dist/dashboard/server.js +110 -16
  6. package/dist/dashboard/server.js.map +1 -1
  7. package/dist/e2e.test.js +25 -7
  8. package/dist/e2e.test.js.map +1 -1
  9. package/dist/prompts/registry.d.ts +12 -0
  10. package/dist/prompts/registry.d.ts.map +1 -1
  11. package/dist/prompts/registry.js +31 -0
  12. package/dist/prompts/registry.js.map +1 -1
  13. package/dist/resources/index.d.ts.map +1 -1
  14. package/dist/resources/index.js +23 -0
  15. package/dist/resources/index.js.map +1 -1
  16. package/dist/resources/index.test.js +2 -0
  17. package/dist/resources/index.test.js.map +1 -1
  18. package/dist/router.d.ts.map +1 -1
  19. package/dist/router.js +5 -0
  20. package/dist/router.js.map +1 -1
  21. package/dist/router.test.js +1 -1
  22. package/dist/router.test.js.map +1 -1
  23. package/dist/storage/sqlite.d.ts +6 -0
  24. package/dist/storage/sqlite.d.ts.map +1 -1
  25. package/dist/storage/sqlite.js +156 -21
  26. package/dist/storage/sqlite.js.map +1 -1
  27. package/dist/storage/sqlite.test.js +2 -0
  28. package/dist/storage/sqlite.test.js.map +1 -1
  29. package/dist/tasks.e2e.test.d.ts +2 -0
  30. package/dist/tasks.e2e.test.d.ts.map +1 -0
  31. package/dist/tasks.e2e.test.js +119 -0
  32. package/dist/tasks.e2e.test.js.map +1 -0
  33. package/dist/tools/memory.store.d.ts.map +1 -1
  34. package/dist/tools/memory.store.js +2 -0
  35. package/dist/tools/memory.store.js.map +1 -1
  36. package/dist/tools/schemas.d.ts +274 -0
  37. package/dist/tools/schemas.d.ts.map +1 -1
  38. package/dist/tools/schemas.js +128 -1
  39. package/dist/tools/schemas.js.map +1 -1
  40. package/dist/tools/task.manage.d.ts +16 -0
  41. package/dist/tools/task.manage.d.ts.map +1 -0
  42. package/dist/tools/task.manage.js +128 -0
  43. package/dist/tools/task.manage.js.map +1 -0
  44. package/dist/types.d.ts +22 -0
  45. package/dist/types.d.ts.map +1 -1
  46. package/dist/utils/logger.d.ts.map +1 -1
  47. package/dist/utils/logger.js +47 -7
  48. package/dist/utils/logger.js.map +1 -1
  49. package/dist/v2-features.test.js +7 -1
  50. package/dist/v2-features.test.js.map +1 -1
  51. package/package.json +1 -1
  52. package/dist/search_memory_example.d.ts +0 -3
  53. package/dist/search_memory_example.d.ts.map +0 -1
  54. package/dist/search_memory_example.js +0 -56
  55. package/dist/search_memory_example.js.map +0 -1
  56. package/dist/server_robustness.test.d.ts +0 -2
  57. package/dist/server_robustness.test.d.ts.map +0 -1
  58. package/dist/server_robustness.test.js +0 -107
  59. package/dist/server_robustness.test.js.map +0 -1
  60. package/dist/store_memory_example.d.ts +0 -3
  61. package/dist/store_memory_example.d.ts.map +0 -1
  62. package/dist/store_memory_example.js +0 -69
  63. package/dist/store_memory_example.js.map +0 -1
  64. package/dist/test_quotes_client.d.ts +0 -3
  65. package/dist/test_quotes_client.d.ts.map +0 -1
  66. package/dist/test_quotes_client.js +0 -72
  67. package/dist/test_quotes_client.js.map +0 -1
@@ -5,6 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>MCP Memory Dashboard</title>
7
7
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.js" onerror="window.Chart = null;"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/marked@12.0.0/marked.min.js"></script>
8
9
  <script src="https://cdn.tailwindcss.com"></script>
9
10
  <script>
10
11
  tailwind.config = {
@@ -34,6 +35,11 @@
34
35
  --panel-dark-strong: rgba(6, 12, 24, 0.9);
35
36
  --panel-dark-border: rgba(148, 163, 184, 0.12);
36
37
  --panel-dark-highlight: rgba(125, 211, 252, 0.16);
38
+ --dashboard-header-offset: 0px;
39
+ --dashboard-tab-offset: 0px;
40
+ --dashboard-main-offset: 280px;
41
+ --dashboard-main-gutter: 16px;
42
+ --dashboard-left-seam: 0px;
37
43
  }
38
44
 
39
45
  html {
@@ -41,14 +47,31 @@
41
47
  radial-gradient(circle at 14% 16%, rgba(125, 211, 252, 0.4), transparent 0 24rem),
42
48
  radial-gradient(circle at 88% 12%, rgba(59, 130, 246, 0.2), transparent 0 18rem),
43
49
  radial-gradient(circle at 82% 82%, rgba(99, 102, 241, 0.14), transparent 0 20rem),
44
- linear-gradient(180deg, #f4fbff 0%, #eef5ff 38%, #f7faff 100%);
50
+ linear-gradient(180deg, #f4fbff 0%, #eef5ff 38%, #f7faff 100%) fixed;
51
+ transition: background 0.5s ease;
52
+ min-height: 100vh;
53
+ overflow-x: hidden;
54
+ }
55
+
56
+ html.dark {
57
+ background:
58
+ radial-gradient(circle at 14% 16%, rgba(14, 165, 233, 0.12), transparent 0 24rem),
59
+ radial-gradient(circle at 88% 12%, rgba(30, 58, 138, 0.1), transparent 0 18rem),
60
+ radial-gradient(circle at 82% 82%, rgba(67, 56, 202, 0.08), transparent 0 20rem),
61
+ linear-gradient(180deg, #020617 0%, #070a18 38%, #020617 100%) fixed;
45
62
  }
46
63
 
47
64
  body {
48
65
  position: relative;
49
66
  min-height: 100vh;
50
- background: transparent !important;
67
+ background: transparent;
51
68
  color: #0f172a;
69
+ transition: color 0.3s ease;
70
+ overflow-x: hidden;
71
+ }
72
+
73
+ html.dark body {
74
+ color: #f8fafc;
52
75
  }
53
76
 
54
77
  body::before,
@@ -79,32 +102,19 @@
79
102
  background: rgba(99, 102, 241, 0.12);
80
103
  }
81
104
 
82
- .dark html {
83
- background:
84
- radial-gradient(circle at 14% 18%, rgba(34, 211, 238, 0.16), transparent 0 18rem),
85
- radial-gradient(circle at 85% 12%, rgba(59, 130, 246, 0.14), transparent 0 18rem),
86
- radial-gradient(circle at 78% 84%, rgba(99, 102, 241, 0.14), transparent 0 20rem),
87
- linear-gradient(180deg, #020617 0%, #081120 34%, #0b1324 100%);
88
- }
89
-
90
- .dark body {
91
- color: #e2e8f0;
92
- }
93
-
94
- .dark body::before {
105
+ html.dark body::before {
95
106
  background: rgba(34, 211, 238, 0.14);
96
107
  opacity: 0.65;
97
108
  }
98
109
 
99
- .dark body::after {
110
+ html.dark body::after {
100
111
  background: rgba(99, 102, 241, 0.16);
101
112
  opacity: 0.55;
102
113
  }
103
114
 
104
115
  header,
105
116
  main .rounded-lg,
106
- #bulkActionBar,
107
- #memoryDrawer aside {
117
+ #bulkActionBar {
108
118
  position: relative;
109
119
  background: var(--glass-bg) !important;
110
120
  border: 1px solid var(--glass-border) !important;
@@ -113,10 +123,9 @@
113
123
  -webkit-backdrop-filter: blur(24px) saturate(1.15);
114
124
  }
115
125
 
116
- .dark header,
117
- .dark main .rounded-lg,
118
- .dark #bulkActionBar,
119
- .dark #memoryDrawer aside {
126
+ html.dark header,
127
+ html.dark main .rounded-lg,
128
+ html.dark #bulkActionBar {
120
129
  background: var(--panel-dark) !important;
121
130
  border-color: var(--panel-dark-border) !important;
122
131
  box-shadow:
@@ -124,814 +133,946 @@
124
133
  inset 0 1px 0 rgba(148, 163, 184, 0.05);
125
134
  }
126
135
 
136
+ /* Drawer: always pure white in light, dark in dark — no glass */
137
+ #memoryDrawer aside {
138
+ background: #ffffff !important;
139
+ backdrop-filter: none !important;
140
+ -webkit-backdrop-filter: none !important;
141
+ border-color: #e2e8f0 !important;
142
+ box-shadow: -20px 0 50px rgba(0,0,0,0.12) !important;
143
+ }
144
+ html.dark #memoryDrawer aside {
145
+ background: #0f172a !important;
146
+ border-color: rgba(255,255,255,0.06) !important;
147
+ }
148
+ /* Reset glass glass on all cards/elements inside the drawer */
149
+ #memoryDrawer aside .rounded-lg,
150
+ #memoryDrawer aside .rounded-xl {
151
+ background: transparent !important;
152
+ backdrop-filter: none !important;
153
+ -webkit-backdrop-filter: none !important;
154
+ box-shadow: none !important;
155
+ }
156
+ /* drawerBody itself: white bg to prevent glass bleed-through */
157
+ #drawerBody {
158
+ background: #ffffff !important;
159
+ }
160
+ html.dark #drawerBody {
161
+ background: #0f172a !important;
162
+ }
163
+
127
164
  header {
128
165
  background: var(--glass-bg-strong) !important;
129
166
  }
130
167
 
131
- .dark header {
168
+ html.dark header {
132
169
  background: var(--panel-dark-strong) !important;
133
170
  }
134
171
 
135
- main,
136
- header {
137
- z-index: 1;
172
+ .sticky-table-header th {
173
+ backdrop-filter: blur(12px);
174
+ -webkit-backdrop-filter: blur(12px);
175
+ background: rgba(248, 250, 252, 0.82) !important;
138
176
  }
139
177
 
140
- canvas {
141
- filter: saturate(1.08);
178
+ html.dark .sticky-table-header th {
179
+ background: rgba(15, 23, 42, 0.88) !important;
180
+ border-color: rgba(148, 163, 184, 0.1);
142
181
  }
143
182
 
144
- input,
145
- select,
146
- textarea {
147
- background: rgba(255, 255, 255, 0.68) !important;
148
- border-color: rgba(148, 163, 184, 0.24) !important;
149
- backdrop-filter: blur(14px);
150
- -webkit-backdrop-filter: blur(14px);
151
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28);
183
+ .table-animate tr {
184
+ transition: all 0.2s ease;
152
185
  }
153
186
 
154
- .dark input,
155
- .dark select,
156
- .dark textarea {
157
- background: rgba(9, 17, 31, 0.86) !important;
158
- border-color: rgba(125, 211, 252, 0.12) !important;
159
- box-shadow:
160
- inset 0 1px 0 rgba(255, 255, 255, 0.03),
161
- 0 0 0 1px rgba(2, 132, 199, 0.06);
187
+ .table-animate tr:hover {
188
+ background: rgba(241, 245, 249, 0.5) !important;
189
+ transform: scale(1.002);
162
190
  }
163
191
 
164
- button {
165
- transition: transform 160ms ease, box-shadow 160ms ease, filter 160ms ease;
192
+ html.dark .table-animate tr:hover {
193
+ background: rgba(30, 41, 59, 0.4) !important;
166
194
  }
167
195
 
168
- button:hover {
196
+ /* Glassy Futuristic Type Chips */
197
+ .table-chip {
198
+ display: inline-flex;
199
+ align-items: center;
200
+ padding: 0.2rem 0.65rem;
201
+ border-radius: 9999px;
202
+ font-size: 0.65rem;
203
+ font-weight: 700;
204
+ text-transform: uppercase;
205
+ letter-spacing: 0.06em;
206
+ backdrop-filter: blur(8px);
207
+ -webkit-backdrop-filter: blur(8px);
208
+ border: 1px solid transparent;
209
+ transition: all 0.2s ease;
210
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.18), 0 2px 8px rgba(0,0,0,0.06);
211
+ }
212
+ .table-chip:hover {
169
213
  transform: translateY(-1px);
170
- box-shadow: 0 12px 32px rgba(15, 23, 42, 0.14);
214
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), 0 4px 12px rgba(0,0,0,0.1);
171
215
  }
172
216
 
173
- .dark button:hover {
174
- box-shadow: 0 16px 36px rgba(2, 6, 23, 0.4);
217
+ .type-decision {
218
+ background: linear-gradient(135deg, rgba(33,150,243,0.12), rgba(25,118,210,0.08));
219
+ color: #1565c0;
220
+ border-color: rgba(33,150,243,0.28);
221
+ text-shadow: 0 0 12px rgba(33,150,243,0.3);
222
+ }
223
+ .type-mistake {
224
+ background: linear-gradient(135deg, rgba(244,67,54,0.12), rgba(211,47,47,0.08));
225
+ color: #c62828;
226
+ border-color: rgba(244,67,54,0.28);
227
+ text-shadow: 0 0 12px rgba(244,67,54,0.3);
228
+ }
229
+ .type-code_fact {
230
+ background: linear-gradient(135deg, rgba(156,39,176,0.12), rgba(123,31,162,0.08));
231
+ color: #6a1b9a;
232
+ border-color: rgba(156,39,176,0.28);
233
+ text-shadow: 0 0 12px rgba(156,39,176,0.3);
234
+ }
235
+ .type-pattern {
236
+ background: linear-gradient(135deg, rgba(56,142,60,0.12), rgba(27,94,32,0.08));
237
+ color: #1b5e20;
238
+ border-color: rgba(56,142,60,0.28);
239
+ text-shadow: 0 0 12px rgba(76,175,80,0.3);
175
240
  }
176
241
 
177
- button[class*="bg-blue-600"],
178
- button[class*="bg-gray-600"],
179
- button[class*="bg-red-600"] {
180
- border: 1px solid rgba(255, 255, 255, 0.16);
242
+ html.dark .type-decision {
243
+ background: linear-gradient(135deg, rgba(56,189,248,0.18), rgba(14,165,233,0.08));
244
+ color: #7dd3fc;
245
+ border-color: rgba(56,189,248,0.3);
246
+ text-shadow: 0 0 14px rgba(56,189,248,0.5);
247
+ }
248
+ html.dark .type-mistake {
249
+ background: linear-gradient(135deg, rgba(251,113,133,0.18), rgba(244,63,94,0.08));
250
+ color: #fda4af;
251
+ border-color: rgba(251,113,133,0.3);
252
+ text-shadow: 0 0 14px rgba(251,113,133,0.5);
253
+ }
254
+ html.dark .type-code_fact {
255
+ background: linear-gradient(135deg, rgba(192,132,252,0.18), rgba(167,139,250,0.08));
256
+ color: #d8b4fe;
257
+ border-color: rgba(192,132,252,0.3);
258
+ text-shadow: 0 0 14px rgba(192,132,252,0.5);
259
+ }
260
+ html.dark .type-pattern {
261
+ background: linear-gradient(135deg, rgba(52,211,153,0.18), rgba(16,185,129,0.08));
262
+ color: #6ee7b7;
263
+ border-color: rgba(52,211,153,0.3);
264
+ text-shadow: 0 0 14px rgba(52,211,153,0.5);
181
265
  }
182
266
 
183
- table {
184
- border-spacing: 0 0.35rem;
185
- border-collapse: separate;
267
+ /* Importance/Metric Badge */
268
+ .metric-badge {
269
+ display: inline-flex;
270
+ align-items: center;
271
+ justify-content: center;
272
+ padding: 0.2rem 0.6rem;
273
+ border-radius: 8px;
274
+ font-size: 0.72rem;
275
+ font-weight: 700;
276
+ letter-spacing: 0.02em;
277
+ backdrop-filter: blur(6px);
278
+ border: 1px solid transparent;
279
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.15), 0 2px 6px rgba(0,0,0,0.06);
280
+ transition: transform 0.15s ease;
186
281
  }
187
282
 
188
- tbody tr {
189
- background: rgba(255, 255, 255, 0.52);
283
+ .skeleton {
284
+ background: linear-gradient(90deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);
285
+ background-size: 200% 100%;
286
+ animation: skeleton-loading 1.5s infinite;
190
287
  }
191
288
 
192
- .dark tbody tr {
193
- background: rgba(8, 15, 28, 0.8);
194
- box-shadow: inset 0 1px 0 rgba(125, 211, 252, 0.04);
289
+ html.dark .skeleton {
290
+ background: linear-gradient(90deg, #1e293b 25%, #334155 50%, #1e293b 75%);
291
+ background-size: 200% 100%;
195
292
  }
196
293
 
197
- thead th {
198
- background: rgba(255, 255, 255, 0.72) !important;
199
- backdrop-filter: blur(18px) saturate(1.1);
200
- -webkit-backdrop-filter: blur(18px) saturate(1.1);
294
+ @keyframes skeleton-loading {
295
+ 0% { background-position: 200% 0; }
296
+ 100% { background-position: -200% 0; }
201
297
  }
202
298
 
203
- .dark thead th {
204
- background: rgba(5, 11, 22, 0.92) !important;
205
- color: #cbd5e1;
206
- border-bottom-color: rgba(125, 211, 252, 0.12);
299
+ #memoryDrawer.hidden { display: none; }
300
+ body.drawer-open { overflow: hidden; }
301
+
302
+ @keyframes fade-in {
303
+ from { opacity: 0; transform: translateY(10px); }
304
+ to { opacity: 1; transform: translateY(0); }
207
305
  }
306
+ .animate-fade-in { animation: fade-in 0.4s cubic-bezier(0.16, 1, 0.3, 1); }
208
307
 
209
- .dark [data-theme="light"] { display: none; }
210
- :not(.dark) [data-theme="dark"] { display: none; }
211
-
212
- .type-decision { background: #e3f2fd; color: #1976d2; }
213
- .type-mistake { background: #ffebee; color: #d32f2f; }
214
- .type-code_fact { background: #f3e5f5; color: #7b1fa2; }
215
- .type-pattern { background: #e8f5e9; color: #388e3c; }
216
-
217
- .dark .type-decision { background: #1a3a5c; color: #64b5f6; }
218
- .dark .type-mistake { background: #5c1a1a; color: #ef9a9a; }
219
- .dark .type-code_fact { background: #3a1a4c; color: #ce93d8; }
220
- .dark .type-pattern { background: #1a3a1a; color: #a5d6a7; }
221
308
 
222
- .countdown-fill { transition: width 1s linear; }
223
-
224
- tr.expanded { background: #f9f9f9; }
225
- .dark tr.expanded { background: #333; }
226
-
227
- tr.expanded td { border-bottom: none; }
228
-
229
- mark { background: #ffeb3b; color: #333; padding: 0 2px; border-radius: 2px; }
230
- .dark mark { background: #ffc107; color: #000; }
309
+ /* btn-open and btn-edit-light overrides for glass context */
310
+ .btn-open { background: #2563eb !important; color: #ffffff !important; }
311
+ html.dark .btn-open { background: rgba(56,189,248,0.15) !important; color: #7dd3fc !important; }
312
+ .btn-open:hover { background: #1d4ed8 !important; }
313
+ html.dark .btn-open:hover { background: rgba(56,189,248,0.25) !important; }
231
314
 
232
- @keyframes slideIn {
233
- from { transform: translateX(100%); opacity: 0; }
234
- to { transform: translateX(0); opacity: 1; }
235
- }
236
- @keyframes slideOut {
237
- from { transform: translateX(0); opacity: 1; }
238
- to { transform: translateX(100%); opacity: 0; }
239
- }
240
- .toast.removing { animation: slideOut 0.3s ease forwards; }
241
- .toast { animation: slideIn 0.3s ease; }
242
- .memory-preview {
243
- display: -webkit-box;
244
- -webkit-line-clamp: 2;
245
- -webkit-box-orient: vertical;
246
- overflow: hidden;
247
- }
248
- .table-chip {
315
+ .btn-edit-light { background: #fef3c7 !important; color: #92400e !important; }
316
+ html.dark .btn-edit-light { background: rgba(245,158,11,0.18) !important; color: #fcd34d !important; }
317
+ .btn-edit-light:hover { background: #fde68a !important; }
318
+ html.dark .btn-edit-light:hover { background: rgba(245,158,11,0.28) !important; }
319
+
320
+ /* Add Task / Refresh Tasks buttons */
321
+ .btn-add-task {
249
322
  display: inline-flex;
250
323
  align-items: center;
251
- gap: 0.35rem;
252
- border-radius: 9999px;
253
- padding: 0.2rem 0.6rem;
254
- font-size: 0.75rem;
324
+ gap: 6px;
325
+ padding: 0.45rem 1rem;
326
+ background: #6366f1 !important;
327
+ color: #ffffff !important;
328
+ border-radius: 10px;
329
+ font-size: 0.8rem;
255
330
  font-weight: 600;
256
- line-height: 1;
331
+ border: 1px solid #4f46e5;
332
+ box-shadow: 0 4px 14px rgba(99,102,241,0.35);
333
+ transition: all 0.2s ease;
257
334
  }
258
- .metric-badge {
259
- display: inline-flex;
260
- align-items: center;
261
- justify-content: center;
262
- min-width: 2rem;
263
- border-radius: 9999px;
264
- padding: 0.2rem 0.55rem;
265
- font-size: 0.75rem;
266
- font-weight: 700;
335
+ .btn-add-task:hover {
336
+ background: #4f46e5 !important;
337
+ box-shadow: 0 6px 20px rgba(99,102,241,0.45);
338
+ transform: translateY(-1px);
267
339
  }
268
- .sticky-table-header thead th {
269
- position: sticky;
270
- top: 0;
271
- z-index: 5;
340
+ html.dark .btn-add-task {
341
+ background: rgba(99,102,241,0.2) !important;
342
+ color: #a5b4fc !important;
343
+ border-color: rgba(99,102,241,0.4);
344
+ box-shadow: 0 4px 14px rgba(99,102,241,0.2);
272
345
  }
273
- .sticky-actions {
274
- position: sticky;
275
- right: 0;
276
- z-index: 4;
277
- background: rgba(255, 255, 255, 0.78);
346
+ html.dark .btn-add-task:hover {
347
+ background: rgba(99,102,241,0.32) !important;
348
+ color: #c7d2fe !important;
278
349
  }
279
- .dark .sticky-actions {
280
- background: rgba(5, 11, 22, 0.94);
350
+ .btn-refresh {
351
+ display: inline-flex;
352
+ align-items: center;
353
+ gap: 6px;
354
+ padding: 0.45rem 1rem;
355
+ background: #0ea5e9 !important;
356
+ color: #ffffff !important;
357
+ border-radius: 10px;
358
+ font-size: 0.8rem;
359
+ font-weight: 600;
360
+ border: 1px solid #0284c7;
361
+ box-shadow: 0 4px 14px rgba(14,165,233,0.3);
362
+ transition: all 0.2s ease;
281
363
  }
282
- .app-shell {
283
- position: relative;
284
- z-index: 1;
364
+ .btn-refresh:hover {
365
+ background: #0284c7 !important;
366
+ transform: translateY(-1px);
285
367
  }
286
- .app-layout {
287
- display: grid;
288
- grid-template-columns: 280px minmax(0, 1fr);
289
- gap: 1.5rem;
290
- align-items: start;
368
+ html.dark .btn-refresh {
369
+ background: rgba(14,165,233,0.15) !important;
370
+ color: #7dd3fc !important;
371
+ border-color: rgba(14,165,233,0.35);
291
372
  }
292
- .app-layout.repo-sidebar-collapsed {
293
- grid-template-columns: 88px minmax(0, 1fr);
373
+ html.dark .btn-refresh:hover {
374
+ background: rgba(14,165,233,0.28) !important;
375
+ color: #bae6fd !important;
294
376
  }
295
- .repo-sidebar {
296
- position: sticky;
297
- top: 6.5rem;
298
- max-height: calc(100vh - 8rem);
299
- display: flex;
300
- flex-direction: column;
301
- min-height: 0;
302
- transition: width 180ms ease, padding 180ms ease, transform 180ms ease;
303
- }
304
- .repo-sidebar-list {
305
- flex: 1 1 auto;
306
- min-height: 0;
307
- overflow-y: auto;
308
- padding-right: 0.35rem;
309
- scrollbar-width: thin;
310
- scrollbar-color: rgba(56, 189, 248, 0.65) rgba(255, 255, 255, 0.08);
311
- }
312
- .repo-sidebar-list::-webkit-scrollbar {
313
- width: 12px;
314
- }
315
- .repo-sidebar-list::-webkit-scrollbar-track {
316
- background: linear-gradient(180deg, rgba(255,255,255,0.16), rgba(255,255,255,0.04));
317
- border-radius: 9999px;
318
- border: 1px solid rgba(255,255,255,0.18);
319
- box-shadow: inset 0 0 0 1px rgba(255,255,255,0.05);
377
+
378
+ /* Add Memory button */
379
+ .btn-add-memory {
380
+ display: inline-flex;
381
+ align-items: center;
382
+ gap: 6px;
383
+ padding: 0.45rem 0.85rem;
384
+ background: #0ea5e9 !important;
385
+ color: #ffffff !important;
386
+ border-radius: 10px;
387
+ font-size: 0.65rem;
388
+ font-weight: 700;
389
+ text-transform: uppercase;
390
+ letter-spacing: 0.07em;
391
+ border: 1px solid #0284c7;
392
+ box-shadow: 0 4px 14px rgba(14,165,233,0.35);
393
+ transition: all 0.2s ease;
394
+ }
395
+ .btn-add-memory:hover {
396
+ background: #0284c7 !important;
397
+ box-shadow: 0 6px 20px rgba(14,165,233,0.45);
398
+ transform: translateY(-1px);
320
399
  }
321
- .repo-sidebar-list::-webkit-scrollbar-thumb {
322
- background: linear-gradient(180deg, rgba(34,211,238,0.92), rgba(59,130,246,0.78));
323
- border-radius: 9999px;
324
- border: 2px solid rgba(245, 250, 255, 0.72);
325
- box-shadow:
326
- inset 0 1px 0 rgba(255,255,255,0.42),
327
- 0 6px 18px rgba(56, 189, 248, 0.28);
400
+ html.dark .btn-add-memory {
401
+ background: rgba(14,165,233,0.2) !important;
402
+ color: #7dd3fc !important;
403
+ border-color: rgba(14,165,233,0.4);
404
+ box-shadow: 0 4px 14px rgba(14,165,233,0.2);
328
405
  }
329
- .repo-sidebar-list::-webkit-scrollbar-thumb:hover {
330
- background: linear-gradient(180deg, rgba(103,232,249,0.96), rgba(37,99,235,0.86));
406
+ html.dark .btn-add-memory:hover {
407
+ background: rgba(14,165,233,0.32) !important;
408
+ color: #bae6fd !important;
331
409
  }
332
- .repo-sidebar-list::-webkit-scrollbar-corner {
333
- background: transparent;
410
+
411
+
412
+ /* Markdown body styles for Full Content section */
413
+ .markdown-body {
414
+ font-size: 0.875rem;
415
+ line-height: 1.75;
416
+ color: #374151;
417
+ word-break: break-word;
418
+ }
419
+ html.dark .markdown-body { color: #d1d5db; }
420
+
421
+ .markdown-body h1, .markdown-body h2, .markdown-body h3,
422
+ .markdown-body h4, .markdown-body h5, .markdown-body h6 {
423
+ font-weight: 700;
424
+ line-height: 1.3;
425
+ margin: 1.2em 0 0.5em;
426
+ color: #111827;
334
427
  }
335
- .dark .repo-sidebar-list {
336
- scrollbar-color: rgba(34, 211, 238, 0.72) rgba(15, 23, 42, 0.24);
428
+ html.dark .markdown-body h1, html.dark .markdown-body h2,
429
+ html.dark .markdown-body h3, html.dark .markdown-body h4 { color: #f9fafb; }
430
+
431
+ .markdown-body h1 { font-size: 1.25rem; border-bottom: 2px solid #e5e7eb; padding-bottom: 0.4rem; }
432
+ .markdown-body h2 { font-size: 1.1rem; border-bottom: 1px solid #e5e7eb; padding-bottom: 0.3rem; }
433
+ html.dark .markdown-body h1, html.dark .markdown-body h2 { border-color: #374151; }
434
+ .markdown-body h3 { font-size: 0.95rem; }
435
+
436
+ .markdown-body p { margin: 0.6em 0; }
437
+ .markdown-body ul, .markdown-body ol {
438
+ padding-left: 1.5rem;
439
+ margin: 0.5em 0;
440
+ }
441
+ .markdown-body ul { list-style-type: disc; }
442
+ .markdown-body ol { list-style-type: decimal; }
443
+ .markdown-body li { margin: 0.25em 0; }
444
+
445
+ .markdown-body code {
446
+ font-family: 'JetBrains Mono', 'Fira Code', monospace;
447
+ font-size: 0.8rem;
448
+ background: #f3f4f6;
449
+ color: #6d28d9;
450
+ padding: 0.15em 0.4em;
451
+ border-radius: 5px;
452
+ border: 1px solid #e5e7eb;
453
+ }
454
+ html.dark .markdown-body code {
455
+ background: rgba(139,92,246,0.12);
456
+ color: #c4b5fd;
457
+ border-color: rgba(139,92,246,0.2);
458
+ }
459
+ .markdown-body pre {
460
+ background: #f8fafc;
461
+ border: 1px solid #e5e7eb;
462
+ border-radius: 10px;
463
+ padding: 1rem;
464
+ overflow-x: auto;
465
+ margin: 0.75em 0;
466
+ }
467
+ html.dark .markdown-body pre {
468
+ background: #0f172a;
469
+ border-color: #334155;
470
+ }
471
+ .markdown-body pre code {
472
+ background: none;
473
+ border: none;
474
+ padding: 0;
475
+ color: inherit;
476
+ font-size: 0.82rem;
477
+ }
478
+ .markdown-body blockquote {
479
+ border-left: 3px solid #0ea5e9;
480
+ margin: 0.75em 0;
481
+ padding: 0.5rem 1rem;
482
+ background: rgba(14,165,233,0.05);
483
+ border-radius: 0 8px 8px 0;
484
+ color: #4b5563;
485
+ font-style: italic;
486
+ }
487
+ html.dark .markdown-body blockquote {
488
+ color: #9ca3af;
489
+ background: rgba(14,165,233,0.08);
490
+ }
491
+ .markdown-body a {
492
+ color: #0ea5e9;
493
+ text-decoration: underline;
494
+ text-underline-offset: 2px;
495
+ }
496
+ .markdown-body a:hover { color: #0284c7; }
497
+ html.dark .markdown-body a { color: #38bdf8; }
498
+
499
+ .markdown-body strong { font-weight: 700; color: #111827; }
500
+ html.dark .markdown-body strong { color: #f9fafb; }
501
+ .markdown-body em { font-style: italic; }
502
+
503
+ .markdown-body hr {
504
+ border: none;
505
+ border-top: 1px solid #e5e7eb;
506
+ margin: 1rem 0;
337
507
  }
338
- .dark .repo-sidebar-list::-webkit-scrollbar-track {
339
- background: linear-gradient(180deg, rgba(15,23,42,0.72), rgba(8,15,28,0.42));
340
- border-radius: 9999px;
341
- border: 1px solid rgba(125, 211, 252, 0.08);
342
- box-shadow:
343
- inset 0 0 0 1px rgba(125, 211, 252, 0.04),
344
- inset 0 10px 24px rgba(2, 6, 23, 0.24);
508
+ html.dark .markdown-body hr { border-color: #374151; }
509
+
510
+ .markdown-body table {
511
+ width: 100%;
512
+ border-collapse: collapse;
513
+ font-size: 0.8rem;
514
+ margin: 0.75em 0;
345
515
  }
346
- .dark .repo-sidebar-list::-webkit-scrollbar-thumb {
347
- background: linear-gradient(180deg, rgba(34,211,238,0.86), rgba(79,70,229,0.72));
348
- border: 2px solid rgba(8, 15, 28, 0.86);
349
- box-shadow:
350
- inset 0 1px 0 rgba(255,255,255,0.14),
351
- 0 8px 22px rgba(34, 211, 238, 0.18);
516
+ .markdown-body th {
517
+ background: #f1f5f9;
518
+ font-weight: 700;
519
+ text-align: left;
520
+ padding: 0.5rem 0.75rem;
521
+ border: 1px solid #e5e7eb;
352
522
  }
353
- .dark .repo-sidebar-list::-webkit-scrollbar-thumb:hover {
354
- background: linear-gradient(180deg, rgba(103,232,249,0.92), rgba(99,102,241,0.82));
523
+ html.dark .markdown-body th { background: #1e293b; border-color: #334155; }
524
+ .markdown-body td {
525
+ padding: 0.4rem 0.75rem;
526
+ border: 1px solid #e5e7eb;
355
527
  }
356
- .repo-collapse-trigger {
357
- width: 2rem;
358
- height: 2rem;
359
- border-radius: 9999px;
360
- display: inline-flex;
361
- align-items: center;
362
- justify-content: center;
363
- border: 1px solid rgba(148, 163, 184, 0.2);
364
- background: rgba(255,255,255,0.42);
528
+ html.dark .markdown-body td { border-color: #334155; }
529
+ .markdown-body tr:nth-child(even) { background: #f8fafc; }
530
+ html.dark .markdown-body tr:nth-child(even) { background: rgba(30,41,59,0.4); }
531
+
532
+ /* Custom Scrollbar */
533
+ ::-webkit-scrollbar { width: 8px; height: 8px; }
534
+ ::-webkit-scrollbar-track { background: transparent; }
535
+ ::-webkit-scrollbar-thumb {
536
+ background: rgba(148, 163, 184, 0.2);
537
+ border-radius: 10px;
365
538
  }
366
- .dark .repo-collapse-trigger {
367
- background: rgba(8, 15, 28, 0.76);
368
- border-color: rgba(125, 211, 252, 0.12);
539
+ ::-webkit-scrollbar-thumb:hover {
540
+ background: rgba(148, 163, 184, 0.4);
369
541
  }
370
- .repo-collapsed-summary {
371
- display: none;
372
- align-items: center;
373
- justify-content: center;
374
- margin-bottom: 0.85rem;
542
+ html.dark ::-webkit-scrollbar-thumb {
543
+ background: rgba(51, 65, 85, 0.4);
375
544
  }
376
- .repo-collapsed-summary-button {
377
- position: relative;
378
- width: 3rem;
379
- height: 3rem;
380
- border-radius: 1rem;
381
- display: inline-flex;
382
- align-items: center;
383
- justify-content: center;
384
- color: white;
385
- font-size: 0.9rem;
386
- font-weight: 800;
387
- letter-spacing: 0.05em;
388
- background: linear-gradient(135deg, rgba(34,211,238,0.96), rgba(59,130,246,0.78));
389
- box-shadow:
390
- inset 0 1px 0 rgba(255,255,255,0.32),
391
- 0 18px 32px rgba(56, 189, 248, 0.2);
545
+
546
+ /* Repo Sidebar */
547
+ #repoSidebar {
548
+ transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
549
+ width: 280px;
550
+ }
551
+ .repo-sidebar-collapsed #repoSidebar {
552
+ width: 80px;
553
+ }
554
+ .repo-sidebar-collapsed .repo-item-copy,
555
+ .repo-sidebar-collapsed .repo-group-label,
556
+ .repo-sidebar-collapsed .repo-sidebar-header-text,
557
+ .repo-sidebar-collapsed .repo-search-container,
558
+ .repo-sidebar-collapsed .repo-item-pin {
559
+ display: none;
392
560
  }
393
- .repo-collapsed-summary-count {
394
- position: absolute;
395
- right: -0.15rem;
396
- bottom: -0.15rem;
397
- min-width: 1.15rem;
398
- height: 1.15rem;
399
- padding: 0 0.22rem;
400
- border-radius: 9999px;
401
- display: inline-flex;
402
- align-items: center;
561
+ .repo-sidebar-collapsed .repo-item {
403
562
  justify-content: center;
404
- font-size: 0.6rem;
405
- font-weight: 800;
406
- color: #0f172a;
407
- background: rgba(255,255,255,0.9);
408
- box-shadow: 0 4px 12px rgba(15, 23, 42, 0.16);
409
- }
410
- .repo-sidebar-mobile {
411
- display: none;
563
+ padding-left: 0;
564
+ padding-right: 0;
412
565
  }
413
566
  .repo-item {
414
- position: relative;
415
- width: 100%;
416
567
  display: flex;
417
568
  align-items: center;
418
- gap: 0.85rem;
419
- padding: 0.85rem 0.95rem;
420
- border-radius: 1rem;
569
+ gap: 12px;
570
+ padding: 10px 14px;
571
+ border-radius: 12px;
572
+ cursor: pointer;
573
+ transition: all 0.2s ease;
574
+ position: relative;
421
575
  border: 1px solid transparent;
422
- background: rgba(255,255,255,0.3);
423
- text-align: left;
424
576
  }
425
577
  .repo-item:hover {
426
- transform: translateY(0);
427
- border-color: rgba(125, 211, 252, 0.28);
428
- background: rgba(255,255,255,0.46);
429
- }
430
- .repo-item.active {
431
- border-color: rgba(56, 189, 248, 0.34);
432
- background: linear-gradient(135deg, rgba(56,189,248,0.16), rgba(99,102,241,0.12));
433
- box-shadow: 0 18px 42px rgba(56, 189, 248, 0.16);
434
- }
435
- .repo-item.pinned-item {
436
- cursor: grab;
437
- }
438
- .repo-item.dragging {
439
- opacity: 0.58;
440
- transform: scale(0.985);
441
- }
442
- .repo-item.drag-target {
443
- border-color: rgba(14, 165, 233, 0.42);
444
- box-shadow:
445
- inset 0 0 0 1px rgba(56, 189, 248, 0.22),
446
- 0 18px 38px rgba(56, 189, 248, 0.12);
447
- }
448
- .repo-drag-handle {
449
- display: inline-flex;
450
- align-items: center;
451
- justify-content: center;
452
- color: rgba(100, 116, 139, 0.9);
453
- cursor: grab;
454
- flex-shrink: 0;
455
- }
456
- .dark .repo-drag-handle {
457
- color: rgba(148, 163, 184, 0.82);
458
- }
459
- .repo-item-pin {
460
- position: absolute;
461
- top: 0.55rem;
462
- right: 0.55rem;
463
- width: 1.7rem;
464
- height: 1.7rem;
465
- border-radius: 9999px;
466
- display: inline-flex;
467
- align-items: center;
468
- justify-content: center;
469
- color: rgba(71, 85, 105, 0.82);
470
- background: rgba(255,255,255,0.68);
471
- border: 1px solid rgba(148, 163, 184, 0.18);
472
- opacity: 0;
473
- transition: opacity 160ms ease, transform 160ms ease, color 160ms ease, background 160ms ease;
474
- }
475
- .repo-item:hover .repo-item-pin,
476
- .repo-item-pin.pinned {
477
- opacity: 1;
478
- }
479
- .repo-item-pin:hover {
480
- transform: scale(1.05);
481
- color: #0f172a;
482
- background: rgba(255,255,255,0.92);
483
- }
484
- .repo-item-pin.pinned {
485
- color: #f59e0b;
486
- background: rgba(255,255,255,0.94);
487
- box-shadow: 0 10px 22px rgba(245, 158, 11, 0.18);
488
- }
489
- .dark .repo-item {
490
- background: rgba(8, 15, 28, 0.72);
491
- }
492
- .dark .repo-item:hover {
493
- background: rgba(10, 18, 32, 0.82);
494
- border-color: rgba(125, 211, 252, 0.16);
578
+ background: rgba(241, 245, 249, 0.8);
495
579
  }
496
- .dark .repo-item-pin {
497
- color: rgba(148, 163, 184, 0.92);
498
- background: rgba(8, 15, 28, 0.88);
499
- border-color: rgba(125, 211, 252, 0.08);
580
+ html.dark .repo-item:hover {
581
+ background: rgba(30, 41, 59, 0.6);
500
582
  }
501
- .dark .repo-item-pin:hover {
502
- color: #e2e8f0;
503
- background: rgba(15, 23, 42, 0.95);
504
- }
505
- .dark .repo-item-pin.pinned {
506
- color: #fbbf24;
507
- background: rgba(15, 23, 42, 0.96);
508
- box-shadow: 0 10px 20px rgba(245, 158, 11, 0.12);
583
+ .repo-item.active {
584
+ background: white;
585
+ border-color: rgba(14, 165, 233, 0.2);
586
+ box-shadow: 0 4px 12px rgba(15, 23, 42, 0.05);
509
587
  }
510
- .dark .repo-item.active {
511
- background: linear-gradient(135deg, rgba(14,165,233,0.2), rgba(79,70,229,0.18));
512
- border-color: rgba(125, 211, 252, 0.2);
513
- box-shadow: 0 20px 44px rgba(2, 132, 199, 0.2);
588
+ html.dark .repo-item.active {
589
+ background: rgba(30, 41, 59, 0.8);
590
+ border-color: rgba(56, 189, 248, 0.3);
591
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
514
592
  }
515
593
  .repo-avatar {
516
- width: 2.35rem;
517
- height: 2.35rem;
518
- border-radius: 0.85rem;
519
- display: inline-flex;
594
+ width: 36px;
595
+ height: 36px;
596
+ border-radius: 10px;
597
+ background: linear-gradient(135deg, #0ea5e9 0%, #6366f1 100%);
598
+ color: white;
599
+ display: flex;
520
600
  align-items: center;
521
601
  justify-content: center;
602
+ font-weight: 700;
603
+ font-size: 13px;
522
604
  flex-shrink: 0;
523
- font-size: 0.78rem;
524
- font-weight: 800;
525
- letter-spacing: 0.04em;
526
- color: white;
527
- background: linear-gradient(135deg, rgba(34,211,238,0.94), rgba(59,130,246,0.76));
528
- box-shadow: inset 0 1px 0 rgba(255,255,255,0.34);
605
+ box-shadow: 0 4px 10px rgba(14, 165, 233, 0.2);
606
+ }
607
+ .repo-group-label {
608
+ font-size: 11px;
609
+ font-weight: 700;
610
+ text-transform: uppercase;
611
+ letter-spacing: 0.05em;
612
+ color: #94a3b8;
613
+ margin: 20px 0 8px 14px;
529
614
  }
530
615
  .repo-active-dot {
531
616
  position: absolute;
532
- right: 0.72rem;
617
+ left: 4px;
533
618
  top: 50%;
534
- width: 0.55rem;
535
- height: 0.55rem;
536
- border-radius: 9999px;
537
- background: #22c55e;
538
- box-shadow:
539
- 0 0 0 3px rgba(255,255,255,0.86),
540
- 0 0 18px rgba(34, 197, 94, 0.45);
541
619
  transform: translateY(-50%);
620
+ width: 4px;
621
+ height: 16px;
622
+ background: #0ea5e9;
623
+ border-radius: 0 4px 4px 0;
542
624
  }
543
- .dark .repo-active-dot {
544
- box-shadow:
545
- 0 0 0 3px rgba(8,15,28,0.92),
546
- 0 0 18px rgba(74, 222, 128, 0.36);
547
- }
548
- .app-layout.repo-sidebar-collapsed .repo-sidebar {
549
- padding-left: 0.75rem;
550
- padding-right: 0.75rem;
551
- }
552
- .app-layout.repo-sidebar-collapsed .repo-sidebar-header-copy,
553
- .app-layout.repo-sidebar-collapsed #repoSearchInput,
554
- .app-layout.repo-sidebar-collapsed #repoCountBadge {
555
- display: none;
625
+
626
+ .repo-item-pin {
627
+ opacity: 0;
628
+ transition: opacity 0.2s ease;
629
+ color: #94a3b8;
556
630
  }
557
- .app-layout.repo-sidebar-collapsed .repo-sidebar-header {
558
- justify-content: center;
631
+ .repo-item:hover .repo-item-pin, .repo-item-pin.pinned {
632
+ opacity: 1;
559
633
  }
560
- .app-layout.repo-sidebar-collapsed .repo-collapsed-summary {
561
- display: flex;
634
+ .repo-item-pin.pinned {
635
+ color: #0ea5e9;
562
636
  }
563
- .app-layout.repo-sidebar-collapsed .repo-item {
564
- justify-content: center;
565
- padding: 0.7rem 0.4rem;
637
+ .repo-item.dragging {
638
+ opacity: 0.5;
639
+ cursor: grabbing;
566
640
  }
567
- .app-layout.repo-sidebar-collapsed .repo-item .repo-item-copy {
568
- display: none;
641
+ .repo-item.drag-target {
642
+ border-top: 2px solid #0ea5e9;
569
643
  }
570
- .app-layout.repo-sidebar-collapsed .repo-item .repo-drag-handle {
571
- display: none;
644
+
645
+ .repo-drag-handle {
646
+ cursor: grab;
647
+ color: #cbd5e1;
648
+ padding: 4px;
572
649
  }
573
- .app-layout.repo-sidebar-collapsed .repo-item .repo-item-pin {
574
- display: none;
650
+ html.dark .repo-drag-handle {
651
+ color: #475569;
575
652
  }
576
- .app-layout.repo-sidebar-collapsed .repo-item .repo-active-dot {
577
- right: 0.4rem;
578
- top: auto;
579
- bottom: 0.4rem;
580
- transform: none;
653
+
654
+ #appLayout {
655
+ min-height: 100vh;
581
656
  }
582
- .app-layout.repo-sidebar-collapsed .repo-avatar {
583
- width: 2.6rem;
584
- height: 2.6rem;
585
- border-radius: 0.95rem;
657
+ #appLayout.repo-sidebar-collapsed {
658
+ --dashboard-main-offset: 80px;
586
659
  }
587
- .app-layout.repo-sidebar-collapsed .repo-sidebar-list {
588
- padding-right: 0;
589
- scrollbar-width: none;
660
+ #mainContent {
661
+ min-width: 0;
662
+ margin-left: 280px;
663
+ transition: margin-left 0.3s cubic-bezier(0.4, 0, 0.2, 1);
590
664
  }
591
- .app-layout.repo-sidebar-collapsed .repo-sidebar-list::-webkit-scrollbar {
592
- width: 0;
665
+ #appLayout.repo-sidebar-collapsed {
593
666
  }
594
- .repo-group + .repo-group {
595
- margin-top: 1rem;
667
+ #appLayout.repo-sidebar-collapsed #mainContent {
668
+ margin-left: 80px;
596
669
  }
597
- .repo-group-label {
598
- margin-bottom: 0.45rem;
599
- padding: 0 0.35rem;
600
- font-size: 0.68rem;
601
- font-weight: 800;
602
- letter-spacing: 0.16em;
603
- text-transform: uppercase;
604
- color: rgb(100 116 139);
670
+ #repoSidebar {
671
+ position: fixed !important;
672
+ top: 0 !important;
673
+ left: 0;
674
+ height: 100dvh;
675
+ max-height: 100dvh;
676
+ overflow: hidden !important;
605
677
  }
606
- .dark .repo-group-label {
607
- color: rgb(148 163 184);
678
+ #mainTopBar {
679
+ position: fixed !important;
680
+ top: 0;
681
+ left: calc(var(--dashboard-main-offset) + var(--dashboard-left-seam));
682
+ right: 0;
683
+ margin-bottom: 0 !important;
608
684
  }
609
- .repo-pinned-mark {
610
- position: absolute;
611
- left: -0.1rem;
612
- top: -0.08rem;
613
- width: 0.95rem;
614
- height: 0.95rem;
615
- border-radius: 9999px;
616
- display: inline-flex;
617
- align-items: center;
618
- justify-content: center;
619
- font-size: 0.52rem;
620
- color: #0f172a;
621
- background: rgba(255,255,255,0.92);
622
- box-shadow: 0 6px 16px rgba(15, 23, 42, 0.14);
685
+ #dashboardShell {
686
+ padding-top: calc(var(--dashboard-header-offset) + 0.2rem);
623
687
  }
624
- @media (max-width: 1023px) {
625
- .app-layout {
626
- grid-template-columns: 1fr;
688
+
689
+ @media (max-width: 1024px) {
690
+ #appLayout {
691
+ --dashboard-main-offset: 0px;
692
+ --dashboard-left-seam: var(--dashboard-main-gutter);
627
693
  }
628
- .repo-sidebar-desktop {
694
+ #repoSidebar {
629
695
  display: none;
630
696
  }
631
- .repo-sidebar-mobile {
632
- display: block;
697
+ #mainContent {
698
+ margin-left: 0;
633
699
  }
634
700
  }
635
- .drawer-open {
636
- overflow: hidden;
701
+ @media (min-width: 768px) {
702
+ :root {
703
+ --dashboard-main-gutter: 32px;
704
+ }
705
+ }
706
+ @media (min-width: 1024px) {
707
+ :root {
708
+ --dashboard-main-gutter: 48px;
709
+ }
637
710
  }
638
- .glass-panel {
639
- animation: panelFadeIn 380ms cubic-bezier(0.2, 0.8, 0.2, 1);
711
+
712
+ /* Sticky Tab Navigation */
713
+ .sticky-tab-nav {
714
+ position: relative;
715
+ top: auto;
716
+ left: auto;
717
+ right: auto;
718
+ z-index: 30;
719
+ padding-top: 0.15rem;
720
+ padding-bottom: 0.55rem;
721
+ margin-left: 0;
722
+ margin-right: 0;
723
+ padding-left: 0;
724
+ padding-right: 0;
725
+ background: linear-gradient(180deg, rgba(244,251,255,0.97) 70%, transparent 100%);
726
+ backdrop-filter: blur(18px);
727
+ -webkit-backdrop-filter: blur(18px);
640
728
  }
641
- .table-animate tbody tr {
642
- animation: rowRise 360ms cubic-bezier(0.2, 0.8, 0.2, 1);
643
- animation-fill-mode: both;
729
+ html.dark .sticky-tab-nav {
730
+ background: linear-gradient(180deg, rgba(2,6,23,0.97) 70%, transparent 100%);
644
731
  }
645
- .table-animate tbody tr:nth-child(1) { animation-delay: 30ms; }
646
- .table-animate tbody tr:nth-child(2) { animation-delay: 60ms; }
647
- .table-animate tbody tr:nth-child(3) { animation-delay: 90ms; }
648
- .table-animate tbody tr:nth-child(4) { animation-delay: 120ms; }
649
- .table-animate tbody tr:nth-child(5) { animation-delay: 150ms; }
650
- .table-animate tbody tr:nth-child(6) { animation-delay: 180ms; }
651
- .recent-action-item {
732
+
733
+ /* Chart containers - precise height control */
734
+ .chart-donut-wrap {
652
735
  position: relative;
653
- overflow: hidden;
654
- border: 1px solid rgba(255,255,255,0.22);
655
- background: rgba(255,255,255,0.44);
656
- backdrop-filter: blur(14px);
657
- -webkit-backdrop-filter: blur(14px);
658
- }
659
- .dark .recent-action-item {
660
- background: linear-gradient(180deg, rgba(7, 15, 28, 0.84), rgba(10, 18, 32, 0.78));
661
- border-color: rgba(125, 211, 252, 0.08);
662
- box-shadow: inset 0 1px 0 rgba(125, 211, 252, 0.04);
663
- }
664
- .recent-action-item::before {
665
- content: "";
666
- position: absolute;
667
- inset: 0 auto 0 0;
668
- width: 3px;
669
- background: linear-gradient(180deg, rgba(34,211,238,0.95), rgba(56,189,248,0.25));
736
+ width: 100%;
737
+ height: 220px;
670
738
  }
671
- @keyframes panelFadeIn {
672
- from { opacity: 0; transform: translateY(10px); }
673
- to { opacity: 1; transform: translateY(0); }
739
+ .chart-line-wrap {
740
+ position: relative;
741
+ width: 100%;
742
+ height: 200px;
674
743
  }
675
- @keyframes rowRise {
676
- from { opacity: 0; transform: translateY(8px); }
677
- to { opacity: 1; transform: translateY(0); }
744
+ .chart-bar-wrap {
745
+ position: relative;
746
+ width: 100%;
747
+ height: 180px;
678
748
  }
679
- .skeleton {
749
+ .chart-scatter-wrap {
680
750
  position: relative;
681
- overflow: hidden;
682
- background: rgb(229 231 235);
683
- border-radius: 0.5rem;
751
+ width: 100%;
752
+ height: 180px;
684
753
  }
685
- .dark .skeleton {
686
- background: rgb(55 65 81);
754
+
755
+ /* Edit button - fixed contrast for dark/light */
756
+ .btn-edit-light {
757
+ padding: 0.35rem 0.75rem;
758
+ border-radius: 6px;
759
+ font-size: 0.7rem;
760
+ font-weight: 700;
761
+ background: #fef3c7;
762
+ color: #92400e;
763
+ border: 1px solid #fcd34d;
764
+ transition: all 0.2s;
765
+ }
766
+ .btn-edit-light:hover {
767
+ background: #fde68a;
768
+ color: #78350f;
769
+ }
770
+ html.dark .btn-edit-light {
771
+ background: rgba(245,158,11,0.18);
772
+ color: #fcd34d;
773
+ border-color: rgba(245,158,11,0.35);
774
+ }
775
+ html.dark .btn-edit-light:hover {
776
+ background: rgba(245,158,11,0.28);
777
+ color: #fef08a;
778
+ }
779
+ .btn-open {
780
+ padding: 0.35rem 0.75rem;
781
+ border-radius: 6px;
782
+ font-size: 0.7rem;
783
+ font-weight: 700;
784
+ background: #2563eb;
785
+ color: #ffffff;
786
+ border: 1px solid #1d4ed8;
787
+ transition: all 0.2s;
687
788
  }
688
- .skeleton::after {
689
- content: "";
690
- position: absolute;
691
- inset: 0;
692
- transform: translateX(-100%);
693
- background: linear-gradient(90deg, transparent, rgba(255,255,255,0.45), transparent);
694
- animation: shimmer 1.4s infinite;
789
+ .btn-open:hover {
790
+ background: #1d4ed8;
791
+ }
792
+ html.dark .btn-open {
793
+ background: rgba(56,189,248,0.15);
794
+ color: #7dd3fc;
795
+ border-color: rgba(56,189,248,0.3);
695
796
  }
696
- @keyframes shimmer {
697
- 100% { transform: translateX(100%); }
797
+ html.dark .btn-open:hover {
798
+ background: rgba(56,189,248,0.25);
799
+ color: #bae6fd;
698
800
  }
699
801
  </style>
700
802
  </head>
701
- <body class="bg-gray-100 dark:bg-gray-900 text-gray-800 dark:text-gray-200 transition-colors duration-300">
702
- <!-- Sticky Header -->
703
- <header class="sticky top-0 z-50 bg-white/80 dark:bg-gray-900/80 backdrop-blur-md border-b border-gray-200/50 dark:border-gray-700/50 px-4 md:px-8 py-3 shadow-sm">
704
- <div class="max-w-[1600px] mx-auto flex flex-col lg:flex-row lg:items-center justify-between gap-4">
705
-
706
- <!-- Left: Title & Main Context -->
707
- <div class="flex items-center justify-between lg:justify-start flex-wrap gap-4 lg:gap-6">
708
- <h1 class="text-xl md:text-2xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-sky-600 to-indigo-600 dark:from-sky-400 dark:to-indigo-400 drop-shadow-sm">MCP Memory</h1>
709
-
710
- <div class="flex items-center gap-2">
711
- <button id="repoNavToggle" class="lg:hidden px-3 py-1.5 rounded-full bg-sky-500/10 text-sky-600 dark:text-sky-400 border border-sky-500/20 text-sm font-medium hover:bg-sky-500/20 transition-all">
712
- Repositories
713
- </button>
714
- <!-- Mobile theme toggle -->
715
- <button id="themeToggleMobile" class="lg:hidden p-1.5 rounded-full bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 border border-slate-200 dark:border-slate-700 shadow-sm hover:scale-105 transition-transform" title="Toggle dark mode">
716
- <svg class="w-5 h-5 hidden dark:block" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path></svg>
717
- <svg class="w-5 h-5 block dark:hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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"></path></svg>
718
- </button>
803
+ <body class="bg-slate-50 dark:bg-slate-950 text-slate-900 dark:text-slate-100 min-h-screen transition-colors duration-500 font-sans selection:bg-sky-500/30">
804
+ <div id="appLayout" class="relative">
805
+ <!-- Sidebar -->
806
+ <aside id="repoSidebar" class="h-screen overflow-y-auto bg-white/40 dark:bg-slate-900/40 backdrop-blur-xl border-r border-slate-200 dark:border-slate-800 z-20 flex flex-col" style="position: sticky; top: 0;">
807
+ <div class="p-6 flex items-center justify-between repo-sidebar-header">
808
+ <div class="flex items-center gap-3 repo-sidebar-header-text">
809
+ <div class="w-8 h-8 rounded-lg bg-gradient-to-tr from-sky-500 to-indigo-600 flex items-center justify-center shadow-lg shadow-sky-500/20">
810
+ <svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"></path></svg>
811
+ </div>
812
+ <span class="font-bold text-lg tracking-tight">Contexts</span>
813
+ <span id="repoCountBadge" class="ml-auto px-2 py-0.5 rounded-full bg-slate-100 dark:bg-slate-800 text-[10px] font-bold text-slate-500 dark:text-slate-400 border border-slate-200 dark:border-slate-700">0</span>
719
814
  </div>
720
-
721
- <div class="hidden md:flex items-center gap-2 px-3 py-1.5 rounded-full bg-slate-100/60 dark:bg-slate-800/60 border border-slate-200/50 dark:border-slate-700/50 shadow-inner backdrop-blur-sm">
722
- <svg class="w-4 h-4 text-sky-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"></path></svg>
723
- <span id="currentRepoLabel" class="text-sm font-semibold text-slate-700 dark:text-slate-200">Loading...</span>
815
+ <button id="repoSidebarCollapseToggle" class="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-lg transition-colors" title="Collapse repositories">
816
+ <svg id="repoSidebarCollapseIcon" class="w-5 h-5 text-slate-500 transition-transform duration-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 19l-7-7 7-7m8 14l-7-7 7-7"></path></svg>
817
+ </button>
818
+ </div>
819
+
820
+ <!-- Collapsed Summary -->
821
+ <div id="repoCollapsedSummary" class="hidden flex-col items-center py-4 gap-4">
822
+ <button id="repoCollapsedSummaryButton" class="w-12 h-12 rounded-xl bg-sky-500/10 border border-sky-500/20 flex flex-col items-center justify-center gap-0.5 hover:bg-sky-500/20 transition-all group">
823
+ <span id="repoCollapsedSummaryInitials" class="text-xs font-bold text-sky-600 dark:text-sky-400">RP</span>
824
+ <span id="repoCollapsedSummaryCount" class="text-[10px] font-medium text-sky-500/70">0</span>
825
+ </button>
826
+ </div>
827
+
828
+ <div class="px-4 mb-6 repo-search-container">
829
+ <div class="relative group">
830
+ <input type="text" id="repoSearchInput" placeholder="Search repositories..." class="w-full pl-10 pr-4 py-2.5 bg-slate-100 dark:bg-slate-800/50 border-none rounded-xl text-sm focus:ring-2 focus:ring-sky-500/50 transition-all outline-none">
831
+ <svg class="w-4 h-4 text-slate-400 absolute left-3.5 top-3 group-focus-within:text-sky-500 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
724
832
  </div>
833
+ </div>
725
834
 
726
- <a href="/api/download-db" target="_blank" download="memory.db" class="hidden md:flex items-center gap-2 px-3 py-1.5 rounded-full bg-slate-100/60 dark:bg-slate-800/60 border border-slate-200/50 dark:border-slate-700/50 shadow-inner backdrop-blur-sm cursor-pointer group hover:bg-white/80 dark:hover:bg-slate-700/80 hover:-translate-y-0.5 transition-all outline-none focus:ring-2 focus:ring-sky-500/50" title="Click to download database file">
727
- <svg class="w-4 h-4 text-slate-400 group-hover:text-amber-500 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path></svg>
728
- <span id="dbPathLabel" class="text-xs font-medium text-slate-500 dark:text-slate-300 truncate max-w-[120px] lg:max-w-[200px]">Loading...</span>
729
- </a>
835
+ <div id="repoSidebarList" class="flex-1 overflow-y-auto px-3 space-y-1 pb-20">
836
+ <div class="text-sm text-gray-500 dark:text-gray-400 px-3 py-4 text-center">
837
+ <div class="skeleton h-8 w-full mb-2 rounded-lg"></div>
838
+ <div class="skeleton h-8 w-full mb-2 rounded-lg"></div>
839
+ <div class="skeleton h-8 w-full mb-2 rounded-lg"></div>
840
+ </div>
730
841
  </div>
731
842
 
732
- <!-- Right: Status & Actions -->
733
- <div class="flex items-center justify-between lg:justify-end flex-wrap gap-3 md:gap-4">
734
-
735
- <div class="flex flex-1 lg:flex-none items-center justify-between lg:justify-start gap-4 px-4 py-2 lg:px-3 lg:py-1.5 rounded-full bg-white/60 dark:bg-slate-800/60 border border-slate-200/50 dark:border-slate-700/50 backdrop-blur-sm shadow-sm">
736
- <div class="flex items-center gap-2">
737
- <span id="syncStatus" class="text-xs font-medium text-slate-500 dark:text-slate-400 whitespace-nowrap">Synced 0s ago</span>
738
- <div class="w-16 h-1.5 bg-slate-200 dark:bg-slate-700 rounded-full overflow-hidden shadow-inner">
739
- <div id="countdownFill" class="h-full bg-gradient-to-r from-sky-400 to-indigo-500 rounded-full" style="width: 100%"></div>
740
- </div>
741
- </div>
742
- <div class="w-px h-4 bg-slate-300 dark:bg-slate-600 hidden lg:block"></div>
743
- <div class="flex items-center gap-2">
744
- <span class="text-xs text-slate-500 dark:text-slate-400 lg:hidden">Status:</span>
745
- <div id="statusDot" class="w-2.5 h-2.5 rounded-full bg-slate-400 shadow-[0_0_8px_rgba(148,163,184,0.6)]"></div>
746
- <span id="statusText" class="text-xs font-medium text-slate-600 dark:text-slate-300">Checking...</span>
843
+ <div class="p-4 border-t border-slate-200 dark:border-slate-800 bg-white/40 dark:bg-slate-900/40 backdrop-blur-md repo-sidebar-footer">
844
+ <div class="flex items-center gap-3 px-2">
845
+ <div class="w-2 h-2 rounded-full bg-emerald-500 animate-pulse"></div>
846
+ <div class="flex-1 min-w-0">
847
+ <p class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">Active Store</p>
848
+ <p id="dbPathLabel" class="text-xs font-medium truncate text-slate-600 dark:text-slate-300">memory.db</p>
747
849
  </div>
748
850
  </div>
851
+ </div>
852
+ </aside>
749
853
 
750
- <div class="hidden lg:flex items-center gap-3">
751
- <button onclick="exportHandbook()" class="flex items-center gap-1.5 px-3 py-1.5 rounded-full bg-gradient-to-r from-sky-500 to-indigo-500 text-white font-medium text-sm shadow-[0_4px_12px_rgba(56,189,248,0.3)] hover:shadow-[0_6px_16px_rgba(56,189,248,0.4)] hover:-translate-y-0.5 transition-all">
752
- <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path></svg>
753
- Handbook
854
+ <!-- Main Content -->
855
+ <main id="mainContent" class="flex-1 p-4 md:p-8 lg:p-12 relative z-10">
856
+ <!-- Header/Navbar substitute (Sticky) -->
857
+ <div id="mainTopBar" class="z-40 flex flex-col md:flex-row md:items-center justify-between gap-6 py-6 px-4 md:px-8 lg:px-12 bg-white/60 dark:bg-slate-900/60 backdrop-blur-xl border-b border-slate-200/50 dark:border-white/5 shadow-sm">
858
+ <div>
859
+ <h1 class="text-3xl font-extrabold tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-slate-900 to-slate-600 dark:from-white dark:to-slate-400 mb-2">MCP Memory Dashboard</h1>
860
+ <div class="flex items-center gap-3">
861
+ <span id="currentRepoLabel" class="px-3 py-1 rounded-full bg-sky-500/10 text-sky-600 dark:text-sky-400 text-xs font-bold border border-sky-500/20">No repository</span>
862
+ <span id="memorySummaryLabel" class="text-slate-500 dark:text-slate-400 text-xs font-medium">0 memories indexed</span>
863
+ <span id="appVersion" class="text-[10px] font-bold text-slate-400 dark:text-slate-600 bg-slate-100 dark:bg-slate-800/50 px-2 py-0.5 rounded border border-slate-200 dark:border-slate-700/50">...</span>
864
+ </div>
865
+ </div>
866
+
867
+ <div class="flex items-center gap-3">
868
+ <button id="repoNavToggle" class="md:hidden p-2.5 bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl shadow-sm hover:shadow-md transition-all active:scale-95" title="View repositories">
869
+ <svg class="w-5 h-5 text-slate-600 dark:text-slate-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path></svg>
754
870
  </button>
755
871
 
756
- <button id="themeToggle" class="p-1.5 rounded-full bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 border border-slate-200 dark:border-slate-700 shadow-sm hover:scale-105 transition-transform" title="Toggle dark mode">
757
- <svg class="w-5 h-5 hidden dark:block" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path></svg>
758
- <svg class="w-5 h-5 block dark:hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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"></path></svg>
872
+ <div class="hidden md:flex items-center gap-2 px-4 py-2 bg-white/50 dark:bg-slate-800/50 backdrop-blur-md border border-slate-200 dark:border-slate-700 rounded-xl shadow-sm">
873
+ <div id="statusDot" class="w-2.5 h-2.5 rounded-full bg-gray-400 shadow-[0_0_8px_rgba(156,163,175,0.5)]"></div>
874
+ <span id="statusText" class="text-xs font-bold uppercase tracking-wider text-slate-600 dark:text-slate-300">Checking...</span>
875
+ </div>
876
+
877
+ <div class="h-10 w-[1px] bg-slate-200 dark:bg-slate-800 hidden md:block"></div>
878
+
879
+ <button id="themeToggle" class="p-2.5 bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl shadow-sm hover:shadow-md transition-all active:scale-95 group" title="Toggle dark mode">
880
+ <svg class="w-5 h-5 text-slate-600 dark:text-slate-300 group-hover:text-sky-500 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
881
+ <path class="dark:hidden" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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"></path>
882
+ <path class="hidden dark:block" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364-6.364l-.707.707M6.343 17.657l-.707.707m12.728 0l-.707-.707M6.343 6.343l-.707-.707M12 5a7 7 0 100 14 7 7 0 000-14z"></path>
883
+ </svg>
759
884
  </button>
760
885
  </div>
761
886
  </div>
887
+
888
+ <div id="dashboardShell" class="min-w-0">
889
+ <!-- Sticky Tab Navigation Wrapper -->
890
+ <div class="sticky-tab-nav">
891
+ <!-- Futuristic Agentic Tab Switcher -->
892
+ <div class="relative mb-0 p-1.5 bg-gray-200/30 dark:bg-gray-800/30 backdrop-blur-xl rounded-2xl border border-white/20 dark:border-white/5 shadow-2xl flex w-fit min-w-[450px] overflow-hidden group">
893
+ <!-- Active Indicator Slide Background -->
894
+ <div id="tabIndicator" class="absolute top-1.5 bottom-1.5 left-1.5 w-[calc(33.33%-4px)] bg-gradient-to-r from-sky-500 to-indigo-600 rounded-xl transition-all duration-500 ease-[cubic-bezier(0.34,1.56,0.64,1)] shadow-[0_0_20px_rgba(14,165,233,0.4)] z-0"></div>
895
+
896
+ <button onclick="switchTab('dashboard')" id="dashboardTabBtn"
897
+ class="relative z-10 flex-1 px-6 py-3.5 font-bold text-xs tracking-wider uppercase transition-all duration-300 flex items-center justify-center gap-2 text-white">
898
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"></path></svg>
899
+ Dashboard
900
+ </button>
901
+ <button onclick="switchTab('memories')" id="memoriesTabBtn"
902
+ class="relative z-10 flex-1 px-6 py-3.5 font-bold text-xs tracking-wider uppercase transition-all duration-300 flex items-center justify-center gap-2 text-gray-500 dark:text-gray-400 hover:text-sky-600 dark:hover:text-sky-400">
903
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"></path></svg>
904
+ Memories
905
+ </button>
906
+ <button onclick="switchTab('tasks')" id="tasksTabBtn"
907
+ class="relative z-10 flex-1 px-6 py-3.5 font-bold text-xs tracking-wider uppercase transition-all duration-300 flex items-center justify-center gap-2 text-gray-500 dark:text-gray-400 hover:text-sky-600 dark:hover:text-sky-400">
908
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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 2m-6 9l2 2 4-4"></path></svg>
909
+ Tasks
910
+ </button>
762
911
  </div>
763
- </header>
764
-
765
- <main class="app-shell max-w-[1600px] mx-auto px-4 md:px-8 py-6">
766
- <div id="appLayout" class="app-layout">
767
- <aside class="repo-sidebar repo-sidebar-desktop rounded-2xl p-4 glass-panel">
768
- <div class="repo-sidebar-header flex items-center justify-between mb-4 gap-3">
769
- <div class="repo-sidebar-header-copy min-w-0">
770
- <div class="text-xs uppercase tracking-[0.24em] text-gray-500 dark:text-gray-400">Repositories</div>
771
- <div class="text-lg font-semibold text-gray-900 dark:text-gray-100">Context Switcher</div>
772
- <div id="memorySummaryLabel" class="mt-1 text-xs text-gray-500 dark:text-gray-400">0 memories indexed</div>
773
- </div>
774
- <div class="flex items-center gap-2">
775
- <span id="repoCountBadge" class="px-2.5 py-1 rounded-full text-xs font-semibold bg-sky-100 text-sky-700 dark:bg-sky-900/40 dark:text-sky-200">0</span>
776
- <button id="repoSidebarCollapseToggle" class="repo-collapse-trigger" title="Collapse repositories" aria-label="Collapse repositories">
777
- <svg id="repoSidebarCollapseIcon" class="w-4 h-4 text-gray-700 dark:text-gray-200 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
778
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
779
- </svg>
780
- </button>
781
- </div>
782
- </div>
783
- <div id="repoCollapsedSummary" class="repo-collapsed-summary">
784
- <button id="repoCollapsedSummaryButton" class="repo-collapsed-summary-button" title="Active repository">
785
- <span id="repoCollapsedSummaryInitials">RP</span>
786
- <span id="repoCollapsedSummaryCount" class="repo-collapsed-summary-count">0</span>
787
- </button>
788
- </div>
789
- <input id="repoSearchInput" type="text" placeholder="Search repositories..." class="w-full px-3 py-2.5 rounded-xl text-sm mb-4">
790
- <div id="repoSidebarList" class="repo-sidebar-list space-y-2">
791
- <div class="text-sm text-gray-500 dark:text-gray-400 px-3 py-4">Loading repositories...</div>
792
- </div>
793
- </aside>
912
+ </div><!-- end sticky-tab-nav -->
794
913
 
795
- <div class="min-w-0">
914
+ <div id="dashboardContent" class="animate-fade-in mt-5">
796
915
  <!-- Summary Cards + Charts + Recent Queries (2/3 + 1/3) -->
797
916
  <div class="grid lg:grid-cols-3 gap-6 mb-6" style="min-height: 60vh;">
798
917
  <!-- Main Content: 2/3 -->
799
918
  <div class="lg:col-span-2 flex flex-col">
800
919
  <!-- Summary Cards -->
801
- <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4">
802
- <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md">
803
- <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Total Memories</div>
804
- <div id="totalCount" class="text-2xl font-bold">0</div>
805
- </div>
806
- <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md">
807
- <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Avg Importance</div>
808
- <div id="avgImportance" class="text-2xl font-bold">0</div>
809
- </div>
810
- <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md">
811
- <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Total Hits</div>
812
- <div id="totalHits" class="text-2xl font-bold">0</div>
813
- </div>
814
- <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md">
815
- <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Expiring Soon</div>
816
- <div id="expiringSoon" class="text-2xl font-bold">0</div>
817
- </div>
818
- <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md">
819
- <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Code Facts</div>
820
- <div id="codeFactCount" class="text-2xl font-bold">0</div>
821
- </div>
822
- <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md">
823
- <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Decisions</div>
824
- <div id="decisionCount" class="text-2xl font-bold">0</div>
825
- </div>
826
- <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md">
827
- <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Mistakes</div>
828
- <div id="mistakeCount" class="text-2xl font-bold">0</div>
829
- </div>
830
- <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md">
831
- <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Patterns</div>
832
- <div id="patternCount" class="text-2xl font-bold">0</div>
833
- </div>
834
- </div>
835
-
836
- <!-- Charts Row 1: 2 columns -->
837
- <div class="grid md:grid-cols-2 gap-4 mb-4 flex-1">
838
- <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md">
839
- <div class="font-semibold mb-2">Memory by Type</div>
840
- <canvas id="typeChart"></canvas>
841
- </div>
842
- <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md">
843
- <div class="font-semibold mb-2">Memories Over Time (30 days)</div>
844
- <canvas id="timeSeriesChart"></canvas>
845
- </div>
846
- </div>
920
+ <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
921
+ <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
922
+ <div class="text-xs text-gray-500 dark:text-gray-400 uppercase font-bold tracking-wider mb-1">Total Memories</div>
923
+ <div id="totalCount" class="text-2xl font-bold">0</div>
924
+ </div>
925
+ <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
926
+ <div class="text-xs text-gray-500 dark:text-gray-400 uppercase font-bold tracking-wider mb-1">Avg Importance</div>
927
+ <div id="avgImportance" class="text-2xl font-bold">0</div>
928
+ </div>
929
+ <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
930
+ <div class="text-xs text-gray-500 dark:text-gray-400 uppercase font-bold tracking-wider mb-1">Total Hits</div>
931
+ <div id="totalHits" class="text-2xl font-bold">0</div>
932
+ </div>
933
+ <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
934
+ <div class="text-xs text-gray-500 dark:text-gray-400 uppercase font-bold tracking-wider mb-1">Expiring Soon</div>
935
+ <div id="expiringSoon" class="text-2xl font-bold text-orange-500">0</div>
936
+ </div>
937
+ </div>
847
938
 
848
- <!-- Charts Row 2: 2 columns -->
849
- <div class="grid md:grid-cols-2 gap-4 flex-1">
850
- <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md">
851
- <div class="font-semibold mb-2">Importance vs Hit Count</div>
852
- <canvas id="scatterChart"></canvas>
853
- </div>
854
- <div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md">
855
- <div class="font-semibold mb-2">Top 10 Memories by Importance</div>
856
- <canvas id="topMemoriesChart"></canvas>
857
- </div>
858
- </div>
939
+ <!-- Charts Section -->
940
+ <div class="grid md:grid-cols-2 gap-6 flex-1">
941
+ <div class="bg-white dark:bg-gray-800 p-4 md:p-5 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
942
+ <h3 class="text-xs font-bold text-gray-500 dark:text-gray-400 uppercase tracking-widest mb-3">Memory by Type</h3>
943
+ <div class="chart-donut-wrap">
944
+ <canvas id="typeChart"></canvas>
945
+ </div>
946
+ <div class="grid grid-cols-2 gap-1.5 mt-3 text-[10px]">
947
+ <div class="flex items-center gap-1.5"><span class="w-2 h-2 rounded-full bg-rose-400 flex-shrink-0"></span> <span class="text-gray-500 dark:text-gray-400">Decision:</span> <span id="decisionCount" class="font-bold">0</span></div>
948
+ <div class="flex items-center gap-1.5"><span class="w-2 h-2 rounded-full bg-violet-400 flex-shrink-0"></span> <span class="text-gray-500 dark:text-gray-400">Mistake:</span> <span id="mistakeCount" class="font-bold">0</span></div>
949
+ <div class="flex items-center gap-1.5"><span class="w-2 h-2 rounded-full bg-sky-400 flex-shrink-0"></span> <span class="text-gray-500 dark:text-gray-400">Code Fact:</span> <span id="codeFactCount" class="font-bold">0</span></div>
950
+ <div class="flex items-center gap-1.5"><span class="w-2 h-2 rounded-full bg-emerald-400 flex-shrink-0"></span> <span class="text-gray-500 dark:text-gray-400">Pattern:</span> <span id="patternCount" class="font-bold">0</span></div>
951
+ </div>
952
+ </div>
953
+ <div class="bg-white dark:bg-gray-800 p-4 md:p-5 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
954
+ <h3 class="text-xs font-bold text-gray-500 dark:text-gray-400 uppercase tracking-widest mb-3">Activity Over Time (30 days)</h3>
955
+ <div class="chart-line-wrap">
956
+ <canvas id="timeSeriesChart"></canvas>
957
+ </div>
958
+ </div>
959
+ <div class="bg-white dark:bg-gray-800 p-4 md:p-5 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
960
+ <h3 class="text-xs font-bold text-gray-500 dark:text-gray-400 uppercase tracking-widest mb-3">Importance vs Hit Count</h3>
961
+ <div class="chart-scatter-wrap">
962
+ <canvas id="scatterChart"></canvas>
963
+ </div>
964
+ </div>
965
+ <div class="bg-white dark:bg-gray-800 p-4 md:p-5 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
966
+ <h3 class="text-xs font-bold text-gray-500 dark:text-gray-400 uppercase tracking-widest mb-3">Top 10 by Hit Count</h3>
967
+ <div class="chart-bar-wrap">
968
+ <canvas id="topMemoriesChart"></canvas>
969
+ </div>
970
+ </div>
971
+ </div>
859
972
  </div>
860
973
 
861
- <!-- Sidebar: 1/3 - Recent Queries (Full Height) -->
862
- <div class="lg:col-span-1 flex flex-col">
863
- <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-4 flex-1 overflow-hidden flex flex-col">
864
- <h3 class="font-semibold mb-4 text-lg">Recent Actions</h3>
865
- <div id="recentQueries" class="flex-1 space-y-2 overflow-y-auto">
866
- <div class="text-gray-500 text-sm">No recent queries</div>
974
+ <!-- Recent Actions Sidebar: 1/3 -->
975
+ <div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 flex flex-col max-h-[85vh]">
976
+ <div class="p-4 border-b border-gray-100 dark:border-gray-700 flex items-center justify-between">
977
+ <h3 class="text-sm font-bold text-gray-500 dark:text-gray-400 uppercase tracking-widest">Recent Actions</h3>
978
+ <div class="w-8 h-8 rounded-full bg-slate-50 dark:bg-slate-900 flex items-center justify-center text-slate-400">
979
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
867
980
  </div>
868
- <div id="recentActionsPagination"></div>
869
981
  </div>
982
+ <div id="recentQueries" class="flex-1 overflow-y-auto p-4 custom-scrollbar">
983
+ <div class="text-gray-400 text-sm text-center py-6">Loading actions...</div>
984
+ </div>
985
+ <div id="recentActionsPagination" class="p-3 bg-gray-50 dark:bg-gray-900/50 rounded-b-lg"></div>
870
986
  </div>
871
987
  </div>
988
+ </div>
872
989
 
873
- <!-- Memory Table Full Width -->
874
- <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-4 md:p-6 mb-6">
875
- <div class="flex flex-wrap gap-3 mb-4">
876
- <input type="text" id="searchInput" placeholder="Search title, content, or ID..." class="px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-sm w-60">
877
-
878
- <div class="flex items-center gap-2">
879
- <label class="text-sm text-gray-600 dark:text-gray-400">Type:</label>
880
- <select id="typeFilter" class="px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-sm">
881
- <option value="">All Types</option>
882
- <option value="decision">Decision</option>
883
- <option value="mistake">Mistake</option>
884
- <option value="code_fact">Code Fact</option>
885
- <option value="pattern">Pattern</option>
886
- </select>
887
- </div>
888
-
889
- <div class="flex items-center gap-2">
890
- <label class="text-sm text-gray-600 dark:text-gray-400">Min Importance:</label>
891
- <select id="minImportanceFilter" class="px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-sm">
892
- <option value="">Any</option>
893
- <option value="1">1+</option>
894
- <option value="2">2+</option>
895
- <option value="3">3+</option>
896
- <option value="4">4+</option>
897
- <option value="5">5</option>
898
- </select>
899
- </div>
900
-
901
- <div class="flex items-center gap-2">
902
- <label class="text-sm text-gray-600 dark:text-gray-400">Max Importance:</label>
903
- <select id="maxImportanceFilter" class="px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-sm">
904
- <option value="">Any</option>
905
- <option value="1">1</option>
906
- <option value="2">2</option>
907
- <option value="3">3</option>
908
- <option value="4">4</option>
909
- <option value="5">5 or less</option>
910
- </select>
990
+ <div id="memoriesContent" class="hidden animate-fade-in mt-5">
991
+ <!-- Filters and Table Full Width -->
992
+ <div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 mb-6 relative overflow-hidden">
993
+ <div id="syncProgress" class="absolute top-0 left-0 h-0.5 bg-sky-500 transition-all duration-300 z-50" style="width: 0%"></div>
994
+
995
+ <div class="p-4 md:p-6 border-b border-gray-100 dark:border-gray-700 bg-gray-50/50 dark:bg-gray-900/20">
996
+ <div class="flex flex-col lg:flex-row lg:items-center justify-between gap-4">
997
+ <div class="flex-1 max-w-xl">
998
+ <div class="relative group">
999
+ <input type="text" id="searchInput" placeholder="Search title, content, or ID..." class="w-full pl-10 pr-4 py-2.5 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-xl text-sm focus:ring-2 focus:ring-sky-500/50 transition-all outline-none">
1000
+ <svg class="w-4 h-4 text-gray-400 absolute left-3.5 top-3 group-focus-within:text-sky-500 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
1001
+ </div>
1002
+ </div>
1003
+
1004
+ <div class="flex flex-wrap items-center gap-3">
1005
+ <div class="flex items-center gap-2">
1006
+ <span class="text-xs font-bold text-gray-400 uppercase tracking-wider">Type:</span>
1007
+ <select id="typeFilter" class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-xs p-2 outline-none focus:ring-2 focus:ring-sky-500/50">
1008
+ <option value="">All Types</option>
1009
+ <option value="decision">Decision</option>
1010
+ <option value="mistake">Mistake</option>
1011
+ <option value="code_fact">Code Fact</option>
1012
+ <option value="pattern">Pattern</option>
1013
+ </select>
1014
+ </div>
1015
+
1016
+ <div class="flex items-center gap-2">
1017
+ <span class="text-xs font-bold text-gray-400 uppercase tracking-wider">Min Importance:</span>
1018
+ <select id="minImportanceFilter" class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-xs p-2 outline-none focus:ring-2 focus:ring-sky-500/50">
1019
+ <option value="">Any</option>
1020
+ <option value="1">1+</option>
1021
+ <option value="2">2+</option>
1022
+ <option value="3">3+</option>
1023
+ <option value="4">4+</option>
1024
+ <option value="5">5</option>
1025
+ </select>
1026
+ </div>
1027
+
1028
+ <div class="flex items-center gap-2">
1029
+ <span class="text-xs font-bold text-gray-400 uppercase tracking-wider">Max Importance:</span>
1030
+ <select id="maxImportanceFilter" class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-xs p-2 outline-none focus:ring-2 focus:ring-sky-500/50">
1031
+ <option value="">Any</option>
1032
+ <option value="1">1</option>
1033
+ <option value="2">2</option>
1034
+ <option value="3">3</option>
1035
+ <option value="4">4</option>
1036
+ <option value="5">5 or less</option>
1037
+ </select>
1038
+ </div>
1039
+
1040
+ <div class="flex items-center gap-2 ml-2">
1041
+ <button onclick="showAddMemoryModal()" class="btn-add-memory" title="Add memory manually">
1042
+ <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 4v16m8-8H4"></path></svg>
1043
+ <span>Add Memory</span>
1044
+ </button>
1045
+ <button onclick="loadData()" class="p-2 text-gray-500 hover:text-sky-600 hover:bg-sky-50 dark:hover:bg-sky-900/20 rounded-lg transition-all" title="Refresh data">
1046
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path></svg>
1047
+ </button>
1048
+ <button onclick="exportData('json')" class="text-[10px] font-bold uppercase tracking-widest px-3 py-2 bg-slate-100 dark:bg-slate-700 text-slate-600 dark:text-slate-300 rounded-lg hover:bg-slate-200 dark:hover:bg-slate-600 transition-all">Export JSON</button>
1049
+ <button onclick="exportData('csv')" class="text-[10px] font-bold uppercase tracking-widest px-3 py-2 bg-slate-100 dark:bg-slate-700 text-slate-600 dark:text-slate-300 rounded-lg hover:bg-slate-200 dark:hover:bg-slate-600 transition-all">Export CSV</button>
1050
+ <button onclick="archiveExpired()" class="text-[10px] font-bold uppercase tracking-widest px-3 py-2 bg-amber-500/10 text-amber-600 border border-amber-500/20 rounded-lg hover:bg-amber-500/20 transition-all">Archive Expired</button>
1051
+ </div>
1052
+ </div>
911
1053
  </div>
912
-
913
- <button onclick="loadData()" class="px-4 py-2 bg-gray-600 hover:bg-gray-700 text-white rounded-md text-sm transition-colors">Refresh</button>
914
- <button onclick="exportData('json')" class="px-4 py-2 bg-gray-600 hover:bg-gray-700 text-white rounded-md text-sm transition-colors">Export JSON</button>
915
- <button onclick="exportData('csv')" class="px-4 py-2 bg-gray-600 hover:bg-gray-700 text-white rounded-md text-sm transition-colors">Export CSV</button>
916
- <button onclick="archiveExpired()" class="px-4 py-2 bg-gray-600 hover:bg-gray-700 text-white rounded-md text-sm transition-colors">Archive Expired</button>
917
1054
  </div>
918
1055
 
919
1056
  <div id="errorMessage"></div>
920
- <div id="tableContainer" class="text-center py-8 text-gray-500">Loading memories...</div>
921
-
922
- <!-- Pagination -->
923
- <div class="flex flex-wrap justify-between items-center mt-4 pt-4 border-t border-gray-200 dark:border-gray-700 gap-4">
924
- <div id="paginationInfo" class="text-sm text-gray-600 dark:text-gray-400"></div>
1057
+ <div id="tableContainer" class="p-0">
1058
+ <div class="text-gray-500 py-12 text-center">Loading memories...</div>
1059
+ </div>
1060
+
1061
+ <!-- Footer / Pagination -->
1062
+ <div class="p-4 border-t border-gray-100 dark:border-gray-700 bg-gray-50/30 dark:bg-gray-900/10 flex flex-col md:flex-row items-center justify-between gap-4">
1063
+ <div id="paginationInfo" class="text-xs font-medium text-gray-500 dark:text-gray-400">Showing 0-0 of 0</div>
925
1064
  <div class="flex items-center gap-2">
926
- <button id="firstPageBtn" onclick="goToPage(1)" class="px-3 py-1 border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed text-sm">First</button>
927
- <button id="prevPageBtn" onclick="goToPage(currentPage - 1)" class="px-3 py-1 border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed text-sm">Prev</button>
928
- <span id="pageNumbers"></span>
929
- <button id="nextPageBtn" onclick="goToPage(currentPage + 1)" class="px-3 py-1 border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed text-sm">Next</button>
930
- <button id="lastPageBtn" onclick="goToPage(totalPages)" class="px-3 py-1 border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed text-sm">Last</button>
1065
+ <button id="firstPageBtn" onclick="goToPage(1)" class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 disabled:opacity-30 transition-all">First</button>
1066
+ <button id="prevPageBtn" onclick="goToPage(currentPage-1)" class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 disabled:opacity-30 transition-all">Prev</button>
1067
+ <div id="pageIndicator" class="flex items-center gap-1">
1068
+ <!-- Dynamic page buttons -->
1069
+ </div>
1070
+ <button id="nextPageBtn" onclick="goToPage(currentPage+1)" class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 disabled:opacity-30 transition-all">Next</button>
1071
+ <button id="lastPageBtn" onclick="goToPage(totalPages)" class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 disabled:opacity-30 transition-all">Last</button>
931
1072
  </div>
932
1073
  <div class="flex items-center gap-2">
933
- <label class="text-sm text-gray-600 dark:text-gray-400">Per page:</label>
934
- <select id="pageSizeSelect" onchange="changePageSize()" class="px-2 py-1 border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-sm">
1074
+ <span class="text-xs font-bold text-gray-400 uppercase tracking-wider">Per page:</span>
1075
+ <select id="pageSizeSelect" onchange="changePageSize()" class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-xs p-1.5 outline-none focus:ring-2 focus:ring-sky-500/50">
935
1076
  <option value="10">10</option>
936
1077
  <option value="25">25</option>
937
1078
  <option value="50">50</option>
@@ -939,60 +1080,271 @@
939
1080
  </select>
940
1081
  </div>
941
1082
  </div>
1083
+ </div>
1084
+ </div>
1085
+
1086
+ <div id="tasksContent" class="hidden animate-fade-in mt-5">
1087
+ <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-4 md:p-6 mb-6">
1088
+ <div class="flex items-center justify-between mb-6">
1089
+ <h2 class="text-xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-sky-600 to-indigo-600 dark:from-sky-400 dark:to-indigo-400">Project Tasks</h2>
1090
+ <div class="flex items-center gap-2">
1091
+ <button onclick="showAddTaskModal()" class="btn-add-task">
1092
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path></svg>
1093
+ Add Task
1094
+ </button>
1095
+ <button onclick="loadTasks()" class="btn-refresh">Refresh Tasks</button>
1096
+ </div>
1097
+ </div>
1098
+ <div id="taskBoard" class="grid grid-cols-1 md:grid-cols-3 gap-6">
1099
+ <!-- Column: Todo -->
1100
+ <div class="flex flex-col gap-4">
1101
+ <div class="flex items-center justify-between px-2">
1102
+ <h3 class="font-bold text-gray-500 uppercase tracking-wider text-xs">To Do</h3>
1103
+ <span id="todoCount" class="bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-400 px-2 py-0.5 rounded-full text-[10px] font-bold">0</span>
1104
+ </div>
1105
+ <div id="todoTasks" class="space-y-4 min-h-[200px]"></div>
1106
+ </div>
1107
+ <!-- Column: In Progress -->
1108
+ <div class="flex flex-col gap-4">
1109
+ <div class="flex items-center justify-between px-2">
1110
+ <h3 class="font-bold text-sky-500 uppercase tracking-wider text-xs">In Progress</h3>
1111
+ <span id="inProgressCount" class="bg-sky-100 dark:bg-sky-900/40 text-sky-600 dark:text-sky-400 px-2 py-0.5 rounded-full text-[10px] font-bold">0</span>
1112
+ </div>
1113
+ <div id="inProgressTasks" class="space-y-4 min-h-[200px]"></div>
1114
+ </div>
1115
+ <!-- Column: Completed -->
1116
+ <div class="flex flex-col gap-4">
1117
+ <div class="flex items-center justify-between px-2">
1118
+ <h3 class="font-bold text-emerald-500 uppercase tracking-wider text-xs">Completed</h3>
1119
+ <span id="completedCount" class="bg-emerald-100 dark:bg-emerald-900/40 text-emerald-600 dark:text-emerald-400 px-2 py-0.5 rounded-full text-[10px] font-bold">0</span>
1120
+ </div>
1121
+ <div id="completedTasks" class="space-y-4 min-h-[200px]"></div>
1122
+ </div>
1123
+ </div>
1124
+ </div>
942
1125
  </div>
943
1126
  </div>
1127
+ </main>
1128
+ </div>
1129
+
1130
+ <!-- Floating Selection Bar -->
1131
+ <div id="bulkActionBar" class="fixed bottom-8 left-1/2 transform -translate-x-1/2 z-50 bg-slate-900/90 dark:bg-white/90 backdrop-blur-md text-white dark:text-slate-900 px-6 py-4 rounded-2xl shadow-2xl border border-white/10 dark:border-slate-200 hidden flex items-center gap-6 animate-fade-in">
1132
+ <div class="flex flex-col">
1133
+ <span id="selectedCount" class="text-sm font-bold">0 selected</span>
1134
+ <span class="text-[10px] uppercase tracking-widest text-slate-400 dark:text-slate-500">Bulk Actions</span>
1135
+ </div>
1136
+ <div class="h-8 w-[1px] bg-white/10 dark:bg-slate-200"></div>
1137
+ <div class="flex items-center gap-3">
1138
+ <span class="text-xs font-bold text-slate-400 dark:text-slate-500 uppercase">Set Priority:</span>
1139
+ <select id="bulkImportanceSelect" class="bg-white/10 dark:bg-slate-100 border border-white/20 dark:border-slate-300 rounded-lg text-xs p-1.5 outline-none focus:ring-2 focus:ring-sky-500/50">
1140
+ <option value="1">1 (Minor)</option>
1141
+ <option value="2">2 (Low)</option>
1142
+ <option value="3">3 (Medium)</option>
1143
+ <option value="4">4 (High)</option>
1144
+ <option value="5">5 (Critical)</option>
1145
+ </select>
1146
+ <button onclick="bulkUpdateImportance()" class="px-4 py-2 bg-sky-500 hover:bg-sky-600 text-white rounded-lg text-xs font-bold transition-all shadow-lg shadow-sky-500/20">Apply</button>
944
1147
  </div>
945
- </main>
1148
+ <div class="h-8 w-[1px] bg-white/10 dark:bg-slate-200"></div>
1149
+ <button onclick="showBulkDeleteConfirm()" class="px-4 py-2 bg-rose-500 hover:bg-rose-600 text-white rounded-lg text-xs font-bold transition-all shadow-lg shadow-rose-500/20">Delete</button>
1150
+ <button onclick="clearSelection()" class="px-4 py-2 bg-white/10 dark:bg-slate-200 hover:bg-white/20 dark:hover:bg-slate-300 text-white dark:text-slate-900 rounded-lg text-xs font-bold transition-all">Clear</button>
1151
+ </div>
946
1152
 
947
- <div id="memoryDrawer" class="hidden fixed inset-0 z-40">
948
- <div class="absolute inset-0 bg-black/40" onclick="closeDrawer()"></div>
949
- <aside class="absolute right-0 top-0 h-full w-full max-w-xl bg-white dark:bg-gray-800 shadow-2xl border-l border-gray-200 dark:border-gray-700 overflow-y-auto">
950
- <div class="sticky top-0 z-10 bg-white/95 dark:bg-gray-800/95 backdrop-blur border-b border-gray-200 dark:border-gray-700 px-6 py-4 flex items-center justify-between">
951
- <div>
952
- <div class="text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400">Memory Details</div>
953
- <h2 id="drawerTitle" class="text-lg font-semibold text-gray-900 dark:text-gray-100">Loading...</h2>
1153
+ <!-- Sync Indicator -->
1154
+ <div class="fixed bottom-6 right-6 z-30">
1155
+ <div class="bg-white/80 dark:bg-slate-900/80 backdrop-blur-md p-3 rounded-2xl shadow-xl border border-slate-200 dark:border-slate-800 flex flex-col gap-2 min-w-[160px]">
1156
+ <div class="flex items-center justify-between">
1157
+ <span id="syncStatus" class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">Synced 0s ago</span>
1158
+ <div class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></div>
1159
+ </div>
1160
+ <div class="w-full h-1 bg-slate-100 dark:bg-slate-800 rounded-full overflow-hidden">
1161
+ <div id="countdownFill" class="h-full bg-sky-500 transition-all duration-1000 ease-linear" style="width: 100%"></div>
1162
+ </div>
1163
+ </div>
1164
+ </div>
1165
+
1166
+ <!-- Toast Container -->
1167
+ <div id="toastContainer" class="fixed top-24 right-6 z-[60] flex flex-col gap-3 pointer-events-none"></div>
1168
+
1169
+ <!-- Mobile Repo Sidebar Drawer -->
1170
+ <div id="repoSidebarDrawer" class="hidden fixed inset-0 z-50">
1171
+ <div class="absolute inset-0 bg-slate-950/40 backdrop-blur-sm transition-opacity" onclick="closeRepoSidebarDrawer()"></div>
1172
+ <aside class="absolute left-0 top-0 h-full w-full max-w-[280px] bg-white dark:bg-slate-900 shadow-2xl border-r border-slate-200 dark:border-slate-800 flex flex-col transform transition-transform duration-300">
1173
+ <div class="p-6 border-b border-slate-100 dark:border-slate-800 flex items-center justify-between">
1174
+ <div class="flex items-center gap-3">
1175
+ <div class="w-8 h-8 rounded-lg bg-gradient-to-tr from-sky-500 to-indigo-600 flex items-center justify-center">
1176
+ <svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"></path></svg>
1177
+ </div>
1178
+ <span class="font-bold text-lg">Contexts</span>
954
1179
  </div>
955
- <button onclick="closeDrawer()" class="text-2xl text-gray-500 hover:text-gray-700 dark:hover:text-gray-300">&times;</button>
1180
+ <button onclick="closeRepoSidebarDrawer()" class="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-lg">
1181
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>
1182
+ </button>
1183
+ </div>
1184
+ <div class="px-4 py-4">
1185
+ <div class="relative group">
1186
+ <input type="text" id="repoSearchInputMobile" placeholder="Search repositories..." class="w-full pl-10 pr-4 py-2.5 bg-slate-100 dark:bg-slate-800/50 border-none rounded-xl text-sm focus:ring-2 focus:ring-sky-500/50 transition-all outline-none">
1187
+ <svg class="w-4 h-4 text-slate-400 absolute left-3.5 top-3 group-focus-within:text-sky-500 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
1188
+ </div>
1189
+ </div>
1190
+ <div id="repoSidebarListMobile" class="flex-1 overflow-y-auto px-3 space-y-1 pb-10">
1191
+ <!-- Mobile repo list items -->
956
1192
  </div>
957
- <div id="drawerBody" class="p-6"></div>
958
1193
  </aside>
959
1194
  </div>
960
1195
 
961
- <div id="repoSidebarDrawer" class="hidden fixed inset-0 z-40 repo-sidebar-mobile">
962
- <div class="absolute inset-0 bg-black/40" onclick="closeRepoSidebarDrawer()"></div>
963
- <aside class="absolute left-0 top-0 h-full w-full max-w-sm bg-white dark:bg-gray-900 shadow-2xl border-r border-gray-200 dark:border-gray-700 overflow-y-auto">
964
- <div class="sticky top-0 z-10 bg-white/95 dark:bg-gray-900/95 backdrop-blur border-b border-gray-200 dark:border-gray-700 px-5 py-4 flex items-center justify-between">
965
- <div>
966
- <div class="text-xs uppercase tracking-[0.24em] text-gray-500 dark:text-gray-400">Repositories</div>
967
- <div class="text-lg font-semibold text-gray-900 dark:text-gray-100">Context Switcher</div>
1196
+ <!-- Detail Drawer -->
1197
+ <div id="memoryDrawer" class="hidden fixed inset-0 z-50 overflow-hidden">
1198
+ <div class="absolute inset-0 bg-slate-950/40 backdrop-blur-sm transition-opacity" onclick="closeDrawer()"></div>
1199
+ <aside class="absolute right-0 top-0 h-full w-full lg:w-1/2 bg-white dark:bg-slate-900 shadow-[-20px_0_50px_rgba(0,0,0,0.15)] border-l border-slate-200 dark:border-white/5 flex flex-col transform transition-transform duration-500 ease-[cubic-bezier(0.34,1.56,0.64,1)] translate-x-full" id="drawerAside">
1200
+ <div class="p-6 border-b border-slate-100 dark:border-slate-800 flex items-center justify-between bg-white dark:bg-slate-900">
1201
+ <div class="flex items-center gap-4">
1202
+ <button onclick="closeDrawer()" class="p-2.5 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-xl transition-all active:scale-95">
1203
+ <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>
1204
+ </button>
1205
+ <h2 id="drawerTitle" class="text-2xl font-black tracking-tight truncate max-w-md bg-clip-text text-transparent bg-gradient-to-r from-slate-900 to-slate-600 dark:from-white dark:to-slate-400">Memory Detail</h2>
1206
+ </div>
1207
+ <div class="flex items-center gap-3">
1208
+ <button onclick="exportHandbook()" class="px-4 py-2 bg-sky-500 hover:bg-sky-600 text-white text-xs font-bold uppercase tracking-widest rounded-lg transition-all shadow-lg shadow-sky-500/20 flex items-center gap-2">
1209
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path></svg>
1210
+ Handbook
1211
+ </button>
968
1212
  </div>
969
- <button onclick="closeRepoSidebarDrawer()" class="text-2xl text-gray-500 hover:text-gray-700 dark:hover:text-gray-300">&times;</button>
970
1213
  </div>
971
- <div class="p-4">
972
- <input id="repoSearchInputMobile" type="text" placeholder="Search repositories..." class="w-full px-3 py-2.5 rounded-xl text-sm mb-4">
973
- <div id="repoSidebarListMobile" class="repo-sidebar-list space-y-2"></div>
1214
+ <div id="drawerBody" class="flex-1 overflow-y-auto p-8 lg:p-12 custom-scrollbar">
1215
+ <!-- Content injected via JS -->
974
1216
  </div>
975
1217
  </aside>
976
1218
  </div>
977
1219
 
978
- <!-- Toast Container -->
979
- <div id="toastContainer" class="fixed bottom-5 right-5 z-[100] flex flex-col gap-2"></div>
980
-
981
- <!-- Bulk Action Bar -->
982
- <div id="bulkActionBar" class="hidden fixed bottom-5 left-1/2 -translate-x-1/2 bg-white dark:bg-gray-800 px-6 py-4 rounded-lg shadow-xl z-[90] gap-4 items-center">
983
- <span id="selectedCount" class="font-semibold">0 selected</span>
984
- <select id="bulkImportanceSelect" class="px-3 py-2 border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700">
985
- <option value="1">Importance 1</option>
986
- <option value="2">Importance 2</option>
987
- <option value="3" selected>Importance 3</option>
988
- <option value="4">Importance 4</option>
989
- <option value="5">Importance 5</option>
990
- </select>
991
- <button onclick="bulkUpdateImportance()" class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded transition-colors">Update</button>
992
- <button onclick="showBulkDeleteConfirm()" class="px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded transition-colors">Delete</button>
993
- <button onclick="clearSelection()" class="px-4 py-2 bg-gray-600 hover:bg-gray-700 text-white rounded transition-colors">Clear</button>
1220
+ <!-- Add Memory Modal -->
1221
+ <div id="addMemoryModal" class="hidden fixed inset-0 z-[100] flex items-center justify-center p-4">
1222
+ <div class="absolute inset-0 bg-slate-950/60 backdrop-blur-md" onclick="hideAddMemoryModal()"></div>
1223
+ <div class="relative bg-white dark:bg-slate-900 w-full max-w-xl rounded-2xl shadow-2xl border border-slate-200 dark:border-slate-800 overflow-hidden animate-fade-in">
1224
+ <div class="p-6 border-b border-slate-100 dark:border-slate-800 flex items-center justify-between">
1225
+ <h3 class="text-xl font-bold">Add New Memory</h3>
1226
+ <button onclick="hideAddMemoryModal()" class="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-lg">
1227
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>
1228
+ </button>
1229
+ </div>
1230
+ <form id="addMemoryForm" onsubmit="handleMemorySubmit(event)" class="p-6 space-y-4">
1231
+ <div class="grid grid-cols-2 gap-4">
1232
+ <div>
1233
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Type</label>
1234
+ <select name="type" required class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50">
1235
+ <option value="code_fact">Code Fact</option>
1236
+ <option value="decision">Decision</option>
1237
+ <option value="mistake">Mistake</option>
1238
+ <option value="pattern">Pattern</option>
1239
+ </select>
1240
+ </div>
1241
+ <div>
1242
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Importance</label>
1243
+ <select name="importance" required class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50">
1244
+ <option value="1">1 (Minor)</option>
1245
+ <option value="2">2 (Low)</option>
1246
+ <option value="3" selected>3 (Medium)</option>
1247
+ <option value="4">4 (High)</option>
1248
+ <option value="5">5 (Critical)</option>
1249
+ </select>
1250
+ </div>
1251
+ </div>
1252
+ <div class="grid grid-cols-2 gap-4">
1253
+ <div>
1254
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Agent</label>
1255
+ <input type="text" name="agent" required placeholder="e.g. Gemini CLI" value="Manual User" class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50">
1256
+ </div>
1257
+ <div>
1258
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Model</label>
1259
+ <input type="text" name="model" required placeholder="e.g. gemini-2.0-flash" value="Human" class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50">
1260
+ </div>
1261
+ </div>
1262
+ <div>
1263
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Title</label>
1264
+ <input type="text" name="title" placeholder="Short descriptive title" class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50">
1265
+ </div>
1266
+ <div>
1267
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Content</label>
1268
+ <textarea name="content" required rows="4" placeholder="What should be remembered?" class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50 resize-none"></textarea>
1269
+ </div>
1270
+ <div>
1271
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Tags (comma separated)</label>
1272
+ <input type="text" name="tags" placeholder="react, hooks, performance" class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50">
1273
+ </div>
1274
+ <div class="flex items-center gap-2">
1275
+ <input type="checkbox" name="is_global" id="is_global_check" class="w-4 h-4 rounded border-slate-300 text-sky-600 focus:ring-sky-500">
1276
+ <label for="is_global_check" class="text-sm text-slate-600 dark:text-slate-400">Mark as global (available in all repos)</label>
1277
+ </div>
1278
+ <div class="pt-4 flex gap-3">
1279
+ <button type="button" onclick="hideAddMemoryModal()" class="flex-1 px-6 py-3 bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 font-bold rounded-xl hover:bg-slate-200 dark:hover:bg-slate-700 transition-all">Cancel</button>
1280
+ <button type="submit" class="flex-1 px-6 py-3 bg-sky-500 hover:bg-sky-600 text-white font-bold rounded-xl shadow-lg shadow-sky-500/20 transition-all">Save Memory</button>
1281
+ </div>
1282
+ </form>
1283
+ </div>
1284
+ </div>
1285
+
1286
+ <!-- Add Task Modal -->
1287
+ <div id="addTaskModal" class="hidden fixed inset-0 z-[100] flex items-center justify-center p-4">
1288
+ <div class="absolute inset-0 bg-slate-950/60 backdrop-blur-md" onclick="hideAddTaskModal()"></div>
1289
+ <div class="relative bg-white dark:bg-slate-900 w-full max-w-xl rounded-2xl shadow-2xl border border-slate-200 dark:border-slate-800 overflow-hidden animate-fade-in">
1290
+ <div class="p-6 border-b border-slate-100 dark:border-slate-800 flex items-center justify-between">
1291
+ <h3 class="text-xl font-bold">Create New Task</h3>
1292
+ <button onclick="hideAddTaskModal()" class="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-lg">
1293
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>
1294
+ </button>
1295
+ </div>
1296
+ <form id="addTaskForm" onsubmit="handleTaskSubmit(event)" class="p-6 space-y-4">
1297
+ <div class="grid grid-cols-2 gap-4">
1298
+ <div>
1299
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Task Code</label>
1300
+ <input type="text" name="task_code" required placeholder="e.g. TASK-001" class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50">
1301
+ </div>
1302
+ <div>
1303
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Phase</label>
1304
+ <input type="text" name="phase" required placeholder="e.g. implementation" class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50">
1305
+ </div>
1306
+ </div>
1307
+ <div>
1308
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Title</label>
1309
+ <input type="text" name="title" required placeholder="Task headline" class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50">
1310
+ </div>
1311
+ <div>
1312
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Description</label>
1313
+ <textarea name="description" rows="3" placeholder="Detailed objective..." class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50 resize-none"></textarea>
1314
+ </div>
1315
+ <div class="grid grid-cols-2 gap-4">
1316
+ <div>
1317
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Priority</label>
1318
+ <select name="priority" class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50">
1319
+ <option value="1">1 (Minor)</option>
1320
+ <option value="2">2 (Low)</option>
1321
+ <option value="3" selected>3 (Medium)</option>
1322
+ <option value="4">4 (High)</option>
1323
+ <option value="5">5 (Critical)</option>
1324
+ </select>
1325
+ </div>
1326
+ <div>
1327
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Status</label>
1328
+ <select name="status" class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50">
1329
+ <option value="pending" selected>To Do</option>
1330
+ <option value="in_progress">In Progress</option>
1331
+ <option value="completed">Completed</option>
1332
+ <option value="blocked">Blocked</option>
1333
+ </select>
1334
+ </div>
1335
+ </div>
1336
+ <div>
1337
+ <label class="block text-xs font-bold text-slate-400 uppercase mb-1">Depends On (ID)</label>
1338
+ <input type="text" name="depends_on" placeholder="Optional parent task ID" class="w-full bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-sky-500/50">
1339
+ </div>
1340
+ <div class="pt-4 flex gap-3">
1341
+ <button type="button" onclick="hideAddTaskModal()" class="flex-1 px-6 py-3 bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 font-bold rounded-xl hover:bg-slate-200 dark:hover:bg-slate-700 transition-all">Cancel</button>
1342
+ <button type="submit" class="flex-1 px-6 py-3 bg-indigo-500 hover:bg-indigo-600 text-white font-bold rounded-xl shadow-lg shadow-indigo-500/20 transition-all">Create Task</button>
1343
+ </div>
1344
+ </form>
1345
+ </div>
994
1346
  </div>
995
1347
 
996
- <script src="/app.js"></script>
1348
+ <script src="/app.js"></script>
997
1349
  </body>
998
1350
  </html>