claudeck 1.1.1 → 1.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 (37) hide show
  1. package/README.md +30 -4
  2. package/config/skillsmp-config.json +5 -0
  3. package/db.js +248 -0
  4. package/package.json +11 -2
  5. package/public/css/panels/git-panel.css +220 -0
  6. package/public/css/panels/skills-manager.css +975 -0
  7. package/public/css/ui/input-history.css +109 -0
  8. package/public/css/ui/messages.css +51 -0
  9. package/public/css/ui/notification-bell.css +421 -0
  10. package/public/css/ui/sessions.css +41 -0
  11. package/public/css/ui/worktree.css +442 -0
  12. package/public/index.html +43 -10
  13. package/public/js/core/api.js +83 -0
  14. package/public/js/core/dom.js +15 -0
  15. package/public/js/features/background-sessions.js +11 -0
  16. package/public/js/features/chat.js +501 -3
  17. package/public/js/features/input-history.js +122 -0
  18. package/public/js/features/projects.js +16 -1
  19. package/public/js/features/sessions.js +77 -30
  20. package/public/js/main.js +3 -0
  21. package/public/js/panels/git-panel.js +385 -6
  22. package/public/js/panels/skills-manager.js +1005 -0
  23. package/public/js/ui/messages.js +58 -0
  24. package/public/js/ui/notification-bell.js +240 -0
  25. package/public/js/ui/notification-history.js +210 -0
  26. package/public/js/ui/parallel.js +11 -0
  27. package/public/js/ui/tab-sdk.js +1 -1
  28. package/public/style.css +4 -0
  29. package/server/agent-loop.js +13 -0
  30. package/server/notification-logger.js +27 -0
  31. package/server/routes/notifications.js +57 -1
  32. package/server/routes/sessions.js +41 -0
  33. package/server/routes/skills.js +454 -0
  34. package/server/routes/worktrees.js +93 -0
  35. package/server/utils/git-worktree.js +297 -0
  36. package/server/ws-handler.js +708 -629
  37. package/server.js +17 -1
@@ -0,0 +1,109 @@
1
+ /* ── Input History Popover ────────────────────────────── */
2
+ .history-popover {
3
+ position: absolute;
4
+ bottom: 100%;
5
+ right: 24px;
6
+ width: 380px;
7
+ max-width: calc(100% - 48px);
8
+ background: var(--bg-secondary);
9
+ border: 1px solid var(--border);
10
+ border-radius: var(--radius);
11
+ box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.5), var(--glow);
12
+ max-height: 300px;
13
+ overflow-y: auto;
14
+ z-index: 51;
15
+ animation: slideUp 0.1s ease;
16
+ }
17
+
18
+ .history-popover-header {
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: space-between;
22
+ padding: 8px 12px;
23
+ border-bottom: 1px solid var(--border-subtle);
24
+ font-size: 11px;
25
+ font-weight: 600;
26
+ text-transform: uppercase;
27
+ letter-spacing: 0.4px;
28
+ color: var(--text-dim);
29
+ }
30
+
31
+ .history-popover-clear {
32
+ background: none;
33
+ border: none;
34
+ color: var(--text-dim);
35
+ font-size: 11px;
36
+ cursor: pointer;
37
+ padding: 2px 6px;
38
+ border-radius: 3px;
39
+ transition: color 0.15s, background 0.15s;
40
+ }
41
+
42
+ .history-popover-clear:hover {
43
+ color: var(--error);
44
+ background: rgba(248, 81, 73, 0.1);
45
+ }
46
+
47
+ .history-popover-item {
48
+ display: flex;
49
+ align-items: center;
50
+ padding: 8px 12px;
51
+ cursor: pointer;
52
+ transition: background 0.08s;
53
+ gap: 8px;
54
+ }
55
+
56
+ .history-popover-item:hover {
57
+ background: var(--accent-dim);
58
+ }
59
+
60
+ .history-popover-item-text {
61
+ font-size: 13px;
62
+ color: var(--text);
63
+ white-space: nowrap;
64
+ overflow: hidden;
65
+ text-overflow: ellipsis;
66
+ flex: 1;
67
+ font-family: var(--font-mono);
68
+ }
69
+
70
+ .history-popover-item-text.is-slash {
71
+ color: var(--accent);
72
+ }
73
+
74
+ .history-popover-empty {
75
+ padding: 16px 12px;
76
+ text-align: center;
77
+ font-size: 12px;
78
+ color: var(--text-dim);
79
+ }
80
+
81
+ /* ── Send + History vertical group ────────────────────── */
82
+ .send-history-group {
83
+ display: flex;
84
+ flex-direction: column;
85
+ align-items: center;
86
+ gap: 4px;
87
+ }
88
+
89
+ #history-btn {
90
+ background: none;
91
+ border: none;
92
+ color: var(--text-dim);
93
+ cursor: pointer;
94
+ padding: 2px;
95
+ border-radius: 4px;
96
+ transition: color 0.15s, background 0.15s;
97
+ display: flex;
98
+ align-items: center;
99
+ justify-content: center;
100
+ }
101
+
102
+ #history-btn:hover {
103
+ color: var(--accent);
104
+ background: var(--accent-dim);
105
+ }
106
+
107
+ #history-btn.hidden {
108
+ display: none;
109
+ }
@@ -951,3 +951,54 @@ html[data-theme="light"] .msg-user {
951
951
  .shortcuts-table td:last-child {
952
952
  color: var(--text-secondary);
953
953
  }
954
+
955
+ /* ── Fork Button ─────────────────────────────────────── */
956
+ .fork-btn {
957
+ position: absolute;
958
+ right: 8px;
959
+ bottom: 8px;
960
+ opacity: 0;
961
+ background: var(--bg-tertiary);
962
+ border: 1px solid var(--border);
963
+ border-radius: var(--radius-sm, 4px);
964
+ padding: 4px 6px;
965
+ cursor: pointer;
966
+ color: var(--text-secondary);
967
+ display: flex;
968
+ align-items: center;
969
+ gap: 4px;
970
+ font-size: 11px;
971
+ transition: opacity 0.15s, background 0.15s, color 0.15s;
972
+ z-index: 2;
973
+ }
974
+
975
+ .msg-assistant,
976
+ .msg:has(.fork-btn) {
977
+ position: relative;
978
+ }
979
+
980
+ .msg-assistant:hover > .fork-btn,
981
+ .msg:hover > .fork-btn {
982
+ opacity: 1;
983
+ }
984
+
985
+ .fork-btn:hover {
986
+ background: var(--accent-dim);
987
+ color: var(--accent);
988
+ border-color: var(--accent);
989
+ }
990
+
991
+ .fork-btn.fork-loading {
992
+ opacity: 1;
993
+ pointer-events: none;
994
+ color: var(--text-secondary);
995
+ }
996
+
997
+ .fork-btn.fork-loading svg {
998
+ animation: spin 1s linear infinite;
999
+ }
1000
+
1001
+ @keyframes spin {
1002
+ from { transform: rotate(0deg); }
1003
+ to { transform: rotate(360deg); }
1004
+ }
@@ -0,0 +1,421 @@
1
+ /* ── Notification Bell ─────────────────────────────────── */
2
+ .notif-bell {
3
+ position: relative;
4
+ }
5
+
6
+ .notif-bell-btn {
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ background: none;
11
+ border: 1px solid var(--border);
12
+ border-radius: var(--radius);
13
+ color: var(--text-dim);
14
+ cursor: pointer;
15
+ width: 26px;
16
+ height: 26px;
17
+ padding: 0;
18
+ transition: all 0.2s var(--ease-smooth);
19
+ position: relative;
20
+ }
21
+
22
+ .notif-bell-btn:hover {
23
+ color: var(--text);
24
+ border-color: var(--text-dim);
25
+ background: var(--accent-dim);
26
+ }
27
+
28
+ .notif-bell-btn.has-unread {
29
+ color: var(--accent);
30
+ border-color: var(--accent-mid);
31
+ }
32
+
33
+ .notif-badge {
34
+ position: absolute;
35
+ top: -5px;
36
+ right: -5px;
37
+ min-width: 16px;
38
+ height: 16px;
39
+ background: var(--error);
40
+ color: #fff;
41
+ font-family: var(--font-mono);
42
+ font-size: 9px;
43
+ font-weight: 700;
44
+ line-height: 16px;
45
+ text-align: center;
46
+ border-radius: 8px;
47
+ padding: 0 4px;
48
+ pointer-events: none;
49
+ box-shadow: 0 0 6px rgba(237, 51, 59, 0.4);
50
+ }
51
+
52
+ /* ── Dropdown ─────────────────────────────────────────── */
53
+ .notif-dropdown {
54
+ position: absolute;
55
+ top: calc(100% + 6px);
56
+ right: 0;
57
+ width: 360px;
58
+ max-height: 440px;
59
+ background: var(--bg-secondary);
60
+ border: 1px solid var(--border);
61
+ border-radius: var(--radius-md);
62
+ box-shadow: var(--shadow-md);
63
+ z-index: 200;
64
+ display: flex;
65
+ flex-direction: column;
66
+ overflow: hidden;
67
+ }
68
+
69
+ .notif-dropdown-header {
70
+ display: flex;
71
+ align-items: center;
72
+ justify-content: space-between;
73
+ padding: 10px 14px;
74
+ border-bottom: 1px solid var(--border);
75
+ font-family: var(--font-display);
76
+ font-size: 12px;
77
+ font-weight: 600;
78
+ color: var(--text);
79
+ letter-spacing: 0.04em;
80
+ text-transform: uppercase;
81
+ }
82
+
83
+ .notif-dropdown-header span {
84
+ color: var(--text-dim);
85
+ font-weight: 400;
86
+ font-size: 10px;
87
+ text-transform: none;
88
+ }
89
+
90
+ .notif-list {
91
+ flex: 1;
92
+ overflow-y: auto;
93
+ overscroll-behavior: contain;
94
+ }
95
+
96
+ .notif-list::-webkit-scrollbar { width: 4px; }
97
+ .notif-list::-webkit-scrollbar-track { background: transparent; }
98
+ .notif-list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
99
+
100
+ /* ── Notification Item ────────────────────────────────── */
101
+ .notif-item {
102
+ display: flex;
103
+ align-items: flex-start;
104
+ gap: 10px;
105
+ padding: 10px 14px;
106
+ border-bottom: 1px solid var(--border-subtle);
107
+ cursor: pointer;
108
+ transition: background 0.15s;
109
+ position: relative;
110
+ }
111
+
112
+ .notif-item:hover {
113
+ background: var(--bg-tertiary);
114
+ }
115
+
116
+ .notif-item:last-child {
117
+ border-bottom: none;
118
+ }
119
+
120
+ .notif-item.unread {
121
+ background: var(--accent-dim);
122
+ }
123
+
124
+ .notif-item.unread:hover {
125
+ background: var(--accent-mid);
126
+ }
127
+
128
+ .notif-dot {
129
+ width: 8px;
130
+ height: 8px;
131
+ border-radius: 50%;
132
+ flex-shrink: 0;
133
+ margin-top: 4px;
134
+ cursor: pointer;
135
+ transition: opacity 0.2s;
136
+ }
137
+
138
+ .notif-dot.unread {
139
+ background: var(--accent);
140
+ box-shadow: 0 0 6px var(--accent-glow);
141
+ }
142
+
143
+ .notif-dot.read {
144
+ background: var(--border);
145
+ opacity: 0.5;
146
+ }
147
+
148
+ .notif-content {
149
+ flex: 1;
150
+ min-width: 0;
151
+ }
152
+
153
+ .notif-icon {
154
+ font-size: 14px;
155
+ flex-shrink: 0;
156
+ margin-top: 1px;
157
+ width: 18px;
158
+ text-align: center;
159
+ }
160
+
161
+ .notif-title {
162
+ font-family: var(--font-sans);
163
+ font-size: 12px;
164
+ font-weight: 500;
165
+ color: var(--text);
166
+ line-height: 1.3;
167
+ overflow: hidden;
168
+ text-overflow: ellipsis;
169
+ white-space: nowrap;
170
+ }
171
+
172
+ .notif-body {
173
+ font-family: var(--font-mono);
174
+ font-size: 10px;
175
+ color: var(--text-secondary);
176
+ margin-top: 2px;
177
+ line-height: 1.4;
178
+ overflow: hidden;
179
+ text-overflow: ellipsis;
180
+ white-space: nowrap;
181
+ }
182
+
183
+ .notif-time {
184
+ font-family: var(--font-mono);
185
+ font-size: 9px;
186
+ color: var(--text-dim);
187
+ flex-shrink: 0;
188
+ margin-top: 2px;
189
+ white-space: nowrap;
190
+ }
191
+
192
+ /* ── Footer ───────────────────────────────────────────── */
193
+ .notif-footer {
194
+ display: flex;
195
+ align-items: center;
196
+ justify-content: space-between;
197
+ padding: 8px 14px;
198
+ border-top: 1px solid var(--border);
199
+ font-family: var(--font-mono);
200
+ font-size: 10px;
201
+ }
202
+
203
+ .notif-footer-btn {
204
+ background: none;
205
+ border: none;
206
+ color: var(--accent);
207
+ cursor: pointer;
208
+ font-family: inherit;
209
+ font-size: inherit;
210
+ padding: 2px 4px;
211
+ border-radius: var(--radius);
212
+ transition: background 0.15s;
213
+ }
214
+
215
+ .notif-footer-btn:hover {
216
+ background: var(--accent-dim);
217
+ }
218
+
219
+ /* ── Empty State ──────────────────────────────────────── */
220
+ .notif-empty {
221
+ display: flex;
222
+ flex-direction: column;
223
+ align-items: center;
224
+ justify-content: center;
225
+ padding: 32px 14px;
226
+ color: var(--text-dim);
227
+ font-family: var(--font-mono);
228
+ font-size: 11px;
229
+ text-align: center;
230
+ gap: 8px;
231
+ }
232
+
233
+ .notif-empty svg {
234
+ opacity: 0.3;
235
+ }
236
+
237
+ /* ── History Modal ────────────────────────────────────── */
238
+ .notif-history-overlay {
239
+ position: fixed;
240
+ inset: 0;
241
+ background: rgba(0, 0, 0, 0.6);
242
+ z-index: 500;
243
+ display: flex;
244
+ align-items: center;
245
+ justify-content: center;
246
+ backdrop-filter: blur(4px);
247
+ }
248
+
249
+ .notif-history-modal {
250
+ width: 90vw;
251
+ max-width: 680px;
252
+ max-height: 80vh;
253
+ background: var(--bg-secondary);
254
+ border: 1px solid var(--border);
255
+ border-radius: var(--radius-lg);
256
+ box-shadow: var(--shadow-lg);
257
+ display: flex;
258
+ flex-direction: column;
259
+ overflow: hidden;
260
+ }
261
+
262
+ .notif-history-header {
263
+ display: flex;
264
+ align-items: center;
265
+ justify-content: space-between;
266
+ padding: 14px 18px;
267
+ border-bottom: 1px solid var(--border);
268
+ }
269
+
270
+ .notif-history-header h2 {
271
+ font-family: var(--font-display);
272
+ font-size: 14px;
273
+ font-weight: 600;
274
+ color: var(--text);
275
+ letter-spacing: 0.06em;
276
+ text-transform: uppercase;
277
+ margin: 0;
278
+ }
279
+
280
+ .notif-history-close {
281
+ background: none;
282
+ border: none;
283
+ color: var(--text-dim);
284
+ cursor: pointer;
285
+ font-size: 18px;
286
+ padding: 2px 6px;
287
+ border-radius: var(--radius);
288
+ transition: color 0.15s;
289
+ }
290
+
291
+ .notif-history-close:hover {
292
+ color: var(--text);
293
+ }
294
+
295
+ /* Filter bar */
296
+ .notif-history-filters {
297
+ display: flex;
298
+ align-items: center;
299
+ gap: 8px;
300
+ padding: 10px 18px;
301
+ border-bottom: 1px solid var(--border-subtle);
302
+ flex-wrap: wrap;
303
+ }
304
+
305
+ .notif-filter-select {
306
+ background: var(--bg);
307
+ border: 1px solid var(--border);
308
+ border-radius: var(--radius);
309
+ color: var(--text-secondary);
310
+ font-family: var(--font-mono);
311
+ font-size: 10px;
312
+ padding: 4px 8px;
313
+ height: 26px;
314
+ cursor: pointer;
315
+ }
316
+
317
+ .notif-filter-select:focus {
318
+ outline: none;
319
+ border-color: var(--accent);
320
+ }
321
+
322
+ .notif-bulk-actions {
323
+ margin-left: auto;
324
+ display: flex;
325
+ gap: 6px;
326
+ }
327
+
328
+ .notif-bulk-btn {
329
+ background: none;
330
+ border: 1px solid var(--border);
331
+ border-radius: var(--radius);
332
+ color: var(--text-dim);
333
+ cursor: pointer;
334
+ font-family: var(--font-mono);
335
+ font-size: 10px;
336
+ padding: 4px 10px;
337
+ height: 26px;
338
+ transition: all 0.15s;
339
+ }
340
+
341
+ .notif-bulk-btn:hover {
342
+ color: var(--text);
343
+ border-color: var(--text-dim);
344
+ }
345
+
346
+ .notif-bulk-btn.danger:hover {
347
+ color: var(--error);
348
+ border-color: var(--error);
349
+ }
350
+
351
+ /* History list */
352
+ .notif-history-list {
353
+ flex: 1;
354
+ overflow-y: auto;
355
+ overscroll-behavior: contain;
356
+ }
357
+
358
+ .notif-history-list::-webkit-scrollbar { width: 4px; }
359
+ .notif-history-list::-webkit-scrollbar-track { background: transparent; }
360
+ .notif-history-list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
361
+
362
+ /* History item extends dropdown item with checkbox */
363
+ .notif-history-item {
364
+ display: flex;
365
+ align-items: flex-start;
366
+ gap: 10px;
367
+ padding: 10px 18px;
368
+ border-bottom: 1px solid var(--border-subtle);
369
+ transition: background 0.15s;
370
+ }
371
+
372
+ .notif-history-item:hover {
373
+ background: var(--bg-tertiary);
374
+ }
375
+
376
+ .notif-history-item.unread {
377
+ background: var(--accent-dim);
378
+ }
379
+
380
+ .notif-history-item input[type="checkbox"] {
381
+ margin-top: 4px;
382
+ accent-color: var(--accent);
383
+ cursor: pointer;
384
+ }
385
+
386
+ .notif-history-item .notif-content {
387
+ flex: 1;
388
+ min-width: 0;
389
+ }
390
+
391
+ .notif-history-item .notif-body {
392
+ white-space: normal;
393
+ display: -webkit-box;
394
+ -webkit-line-clamp: 2;
395
+ -webkit-box-orient: vertical;
396
+ }
397
+
398
+ /* Load more */
399
+ .notif-load-more {
400
+ display: flex;
401
+ justify-content: center;
402
+ padding: 12px;
403
+ border-top: 1px solid var(--border-subtle);
404
+ }
405
+
406
+ .notif-load-more-btn {
407
+ background: none;
408
+ border: 1px solid var(--border);
409
+ border-radius: var(--radius);
410
+ color: var(--text-secondary);
411
+ cursor: pointer;
412
+ font-family: var(--font-mono);
413
+ font-size: 10px;
414
+ padding: 6px 16px;
415
+ transition: all 0.15s;
416
+ }
417
+
418
+ .notif-load-more-btn:hover {
419
+ color: var(--text);
420
+ border-color: var(--text-dim);
421
+ }
@@ -687,3 +687,44 @@
687
687
  opacity: 0.5;
688
688
  line-height: 1.5;
689
689
  }
690
+
691
+ /* ── Fork Badge ──────────────────────────────────────── */
692
+ .session-fork-badge {
693
+ display: inline-flex;
694
+ align-items: center;
695
+ margin-right: 4px;
696
+ color: var(--accent);
697
+ vertical-align: middle;
698
+ opacity: 0.8;
699
+ }
700
+
701
+ /* ── View Forks — back header ────────────────────────── */
702
+ .session-forks-back {
703
+ display: flex;
704
+ flex-direction: column;
705
+ gap: 4px;
706
+ padding: 8px 12px;
707
+ border-bottom: 1px solid var(--border);
708
+ margin-bottom: 4px;
709
+ }
710
+
711
+ .session-forks-back-btn {
712
+ background: none;
713
+ border: none;
714
+ color: var(--accent);
715
+ cursor: pointer;
716
+ font-size: 12px;
717
+ padding: 0;
718
+ text-align: left;
719
+ font-family: var(--font-sans);
720
+ }
721
+
722
+ .session-forks-back-btn:hover {
723
+ text-decoration: underline;
724
+ }
725
+
726
+ .session-forks-label {
727
+ font-size: 11px;
728
+ color: var(--text-secondary);
729
+ font-family: var(--font-sans);
730
+ }