claudeck 1.4.0 → 1.4.2
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.
- package/README.md +6 -8
- package/package.json +1 -1
- package/plugins/claude-editor/manifest.json +10 -0
- package/plugins/repos/manifest.json +10 -0
- package/public/css/core/theme.css +6 -21
- package/public/css/core/variables.css +2 -0
- package/public/css/features/message-queue.css +348 -0
- package/public/css/ui/commands.css +4 -4
- package/public/css/ui/messages.css +310 -78
- package/public/css/ui/right-panel.css +207 -0
- package/public/css/ui/sessions.css +173 -0
- package/public/css/ui/settings.css +75 -0
- package/public/index.html +10 -2
- package/public/js/components/add-project-modal.js +14 -0
- package/public/js/components/jump-to-latest.js +42 -0
- package/public/js/components/queue-stop-modal.js +23 -0
- package/public/js/components/settings-modal.js +65 -0
- package/public/js/core/api.js +15 -43
- package/public/js/core/dom.js +17 -0
- package/public/js/core/events.js +11 -0
- package/public/js/core/plugin-loader.js +96 -11
- package/public/js/core/store.js +11 -0
- package/public/js/core/utils.js +38 -2
- package/public/js/features/chat.js +49 -1
- package/public/js/features/message-queue.js +423 -0
- package/public/js/features/projects.js +185 -3
- package/public/js/main.js +4 -1
- package/public/js/panels/assistant-bot.js +16 -0
- package/public/js/panels/dev-docs.js +2 -2
- package/public/js/panels/memory.js +1 -0
- package/public/js/ui/context-gauge.js +10 -1
- package/public/js/ui/formatting.js +65 -11
- package/public/js/ui/header-dropdowns.js +30 -0
- package/public/js/ui/input-meta.js +13 -6
- package/public/js/ui/max-turns.js +6 -3
- package/public/js/ui/messages.js +97 -1
- package/public/js/ui/model-selector.js +1 -0
- package/public/js/ui/parallel.js +32 -2
- package/public/js/ui/permissions.js +1 -0
- package/public/js/ui/right-panel.js +0 -8
- package/public/js/ui/tab-sdk.js +395 -176
- package/public/style.css +2 -0
- package/server/memory-optimizer.js +17 -13
- package/server/routes/marketplace.js +316 -0
- package/server/routes/projects.js +0 -0
- package/server/ws-handler.js +22 -15
- package/server.js +18 -0
- package/plugins/event-stream/client.css +0 -207
- package/plugins/event-stream/client.js +0 -271
- package/plugins/linear/client.css +0 -345
- package/plugins/linear/client.js +0 -380
- package/plugins/linear/config.json +0 -5
- package/plugins/linear/server.js +0 -312
- package/plugins/sudoku/client.css +0 -196
- package/plugins/sudoku/client.js +0 -329
- package/plugins/tasks/client.css +0 -414
- package/plugins/tasks/client.js +0 -394
- package/plugins/tasks/server.js +0 -116
- package/plugins/tic-tac-toe/client.css +0 -167
- package/plugins/tic-tac-toe/client.js +0 -241
- package/public/js/components/linear-create-modal.js +0 -43
|
@@ -486,3 +486,210 @@
|
|
|
486
486
|
filter: brightness(1.1);
|
|
487
487
|
box-shadow: var(--glow-strong);
|
|
488
488
|
}
|
|
489
|
+
|
|
490
|
+
/* ── Marketplace tabs ── */
|
|
491
|
+
|
|
492
|
+
.marketplace-tabs {
|
|
493
|
+
display: flex;
|
|
494
|
+
gap: 4px;
|
|
495
|
+
margin-top: 12px;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
.marketplace-tab {
|
|
499
|
+
padding: 6px 16px;
|
|
500
|
+
border-radius: var(--radius-md);
|
|
501
|
+
font-size: 12px;
|
|
502
|
+
font-weight: 500;
|
|
503
|
+
font-family: var(--font-sans);
|
|
504
|
+
cursor: pointer;
|
|
505
|
+
transition: all 0.2s var(--ease-smooth);
|
|
506
|
+
border: 1px solid transparent;
|
|
507
|
+
background: none;
|
|
508
|
+
color: var(--text-dim);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
.marketplace-tab:hover {
|
|
512
|
+
color: var(--text);
|
|
513
|
+
background: var(--bg-tertiary);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
.marketplace-tab.active {
|
|
517
|
+
color: var(--accent);
|
|
518
|
+
background: var(--accent-dim);
|
|
519
|
+
border-color: var(--accent);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
.marketplace-tab-content {
|
|
523
|
+
flex: 1;
|
|
524
|
+
overflow-y: auto;
|
|
525
|
+
display: flex;
|
|
526
|
+
flex-direction: column;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.marketplace-tab-content::-webkit-scrollbar {
|
|
530
|
+
width: 4px;
|
|
531
|
+
}
|
|
532
|
+
.marketplace-tab-content::-webkit-scrollbar-thumb {
|
|
533
|
+
background: var(--border);
|
|
534
|
+
border-radius: 2px;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
.marketplace-tab-content > .marketplace-subtitle {
|
|
538
|
+
padding: 12px 16px 4px;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
.marketplace-tab-content > .marketplace-list {
|
|
542
|
+
flex: 1;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.marketplace-tab-content > .marketplace-empty {
|
|
546
|
+
flex: 1;
|
|
547
|
+
display: flex;
|
|
548
|
+
flex-direction: column;
|
|
549
|
+
align-items: center;
|
|
550
|
+
justify-content: center;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
.marketplace-tab-content > .marketplace-empty a {
|
|
554
|
+
color: var(--accent);
|
|
555
|
+
text-decoration: none;
|
|
556
|
+
margin-top: 8px;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
.marketplace-tab-content > .marketplace-empty a:hover {
|
|
560
|
+
text-decoration: underline;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/* ── Community plugin items ── */
|
|
564
|
+
|
|
565
|
+
.marketplace-community-item {
|
|
566
|
+
cursor: default;
|
|
567
|
+
padding: 12px;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
.marketplace-item-meta {
|
|
571
|
+
display: flex;
|
|
572
|
+
gap: 8px;
|
|
573
|
+
margin-top: 4px;
|
|
574
|
+
font-size: 10px;
|
|
575
|
+
color: var(--text-dim);
|
|
576
|
+
font-family: var(--font-mono);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
.marketplace-author {
|
|
580
|
+
opacity: 0.7;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
.marketplace-version {
|
|
584
|
+
opacity: 0.5;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
.marketplace-version-old {
|
|
588
|
+
opacity: 0.4;
|
|
589
|
+
text-decoration: line-through;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.marketplace-source {
|
|
593
|
+
font-size: 9px;
|
|
594
|
+
font-family: var(--font-display);
|
|
595
|
+
padding: 1px 6px;
|
|
596
|
+
border-radius: 4px;
|
|
597
|
+
text-transform: uppercase;
|
|
598
|
+
letter-spacing: 0.06em;
|
|
599
|
+
vertical-align: middle;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
.marketplace-source.community {
|
|
603
|
+
color: var(--purple);
|
|
604
|
+
background: color-mix(in srgb, var(--purple) 15%, transparent);
|
|
605
|
+
border: 1px solid color-mix(in srgb, var(--purple) 30%, transparent);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
.marketplace-source.server {
|
|
609
|
+
color: var(--orange, #f0a040);
|
|
610
|
+
background: color-mix(in srgb, var(--orange, #f0a040) 15%, transparent);
|
|
611
|
+
border: 1px solid color-mix(in srgb, var(--orange, #f0a040) 30%, transparent);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/* ── Action buttons (install / uninstall / update) ── */
|
|
615
|
+
|
|
616
|
+
.marketplace-item-actions {
|
|
617
|
+
flex-shrink: 0;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
.marketplace-action-btn {
|
|
621
|
+
padding: 5px 14px;
|
|
622
|
+
border-radius: var(--radius-md);
|
|
623
|
+
font-size: 11px;
|
|
624
|
+
font-weight: 500;
|
|
625
|
+
font-family: var(--font-sans);
|
|
626
|
+
cursor: pointer;
|
|
627
|
+
transition: all 0.2s var(--ease-smooth);
|
|
628
|
+
border: 1px solid var(--border);
|
|
629
|
+
white-space: nowrap;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
.marketplace-action-btn:disabled {
|
|
633
|
+
opacity: 0.5;
|
|
634
|
+
cursor: not-allowed;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
.marketplace-install-btn {
|
|
638
|
+
background: var(--accent);
|
|
639
|
+
color: #fff;
|
|
640
|
+
border-color: var(--accent);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
.marketplace-install-btn:hover:not(:disabled) {
|
|
644
|
+
filter: brightness(1.1);
|
|
645
|
+
box-shadow: var(--glow);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
.marketplace-uninstall-btn {
|
|
649
|
+
background: none;
|
|
650
|
+
color: var(--text-dim);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
.marketplace-uninstall-btn:hover:not(:disabled) {
|
|
654
|
+
color: var(--red, #e54);
|
|
655
|
+
border-color: var(--red, #e54);
|
|
656
|
+
background: color-mix(in srgb, var(--red, #e54) 10%, transparent);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
.marketplace-update-btn {
|
|
660
|
+
background: var(--purple);
|
|
661
|
+
color: #fff;
|
|
662
|
+
border-color: var(--purple);
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
.marketplace-update-btn:hover:not(:disabled) {
|
|
666
|
+
filter: brightness(1.1);
|
|
667
|
+
box-shadow: 0 0 8px color-mix(in srgb, var(--purple) 40%, transparent);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/* ── Loading state ── */
|
|
671
|
+
|
|
672
|
+
.marketplace-loading {
|
|
673
|
+
display: flex;
|
|
674
|
+
flex-direction: column;
|
|
675
|
+
align-items: center;
|
|
676
|
+
justify-content: center;
|
|
677
|
+
gap: 12px;
|
|
678
|
+
padding: 48px 16px;
|
|
679
|
+
color: var(--text-dim);
|
|
680
|
+
font-size: 12px;
|
|
681
|
+
font-family: var(--font-sans);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
.marketplace-spinner {
|
|
685
|
+
width: 24px;
|
|
686
|
+
height: 24px;
|
|
687
|
+
border: 2px solid var(--border);
|
|
688
|
+
border-top-color: var(--accent);
|
|
689
|
+
border-radius: 50%;
|
|
690
|
+
animation: spin 0.8s linear infinite;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
@keyframes spin {
|
|
694
|
+
to { transform: rotate(360deg); }
|
|
695
|
+
}
|
|
@@ -287,6 +287,179 @@
|
|
|
287
287
|
font-family: var(--font-mono);
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
+
/* Typed path row */
|
|
291
|
+
.folder-path-row {
|
|
292
|
+
display: flex;
|
|
293
|
+
gap: 6px;
|
|
294
|
+
align-items: center;
|
|
295
|
+
margin-bottom: 8px;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.folder-path-row input {
|
|
299
|
+
flex: 1;
|
|
300
|
+
padding: 8px 10px;
|
|
301
|
+
font-size: 12px;
|
|
302
|
+
font-family: var(--font-mono);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.folder-path-go {
|
|
306
|
+
flex-shrink: 0;
|
|
307
|
+
padding: 7px 14px;
|
|
308
|
+
font-size: 11px;
|
|
309
|
+
font-family: var(--font-mono);
|
|
310
|
+
background: var(--bg);
|
|
311
|
+
color: var(--text-secondary);
|
|
312
|
+
border: 1px solid var(--border);
|
|
313
|
+
border-radius: var(--radius-md);
|
|
314
|
+
cursor: pointer;
|
|
315
|
+
transition: all 0.15s;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.folder-path-go:hover {
|
|
319
|
+
color: var(--accent);
|
|
320
|
+
border-color: var(--accent);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/* Recents row */
|
|
324
|
+
.folder-recents {
|
|
325
|
+
display: flex;
|
|
326
|
+
align-items: center;
|
|
327
|
+
flex-wrap: wrap;
|
|
328
|
+
gap: 6px;
|
|
329
|
+
padding: 6px 0 10px;
|
|
330
|
+
border-bottom: 1px solid var(--border-subtle);
|
|
331
|
+
margin-bottom: 6px;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.folder-recents-label {
|
|
335
|
+
font-size: 10px;
|
|
336
|
+
text-transform: uppercase;
|
|
337
|
+
letter-spacing: 0.5px;
|
|
338
|
+
color: var(--text-dim);
|
|
339
|
+
margin-right: 2px;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.folder-recent-chip {
|
|
343
|
+
padding: 3px 8px;
|
|
344
|
+
font-size: 11px;
|
|
345
|
+
font-family: var(--font-mono);
|
|
346
|
+
color: var(--text-secondary);
|
|
347
|
+
background: var(--bg);
|
|
348
|
+
border: 1px solid var(--border);
|
|
349
|
+
border-radius: 999px;
|
|
350
|
+
cursor: pointer;
|
|
351
|
+
transition: all 0.15s;
|
|
352
|
+
max-width: 160px;
|
|
353
|
+
overflow: hidden;
|
|
354
|
+
text-overflow: ellipsis;
|
|
355
|
+
white-space: nowrap;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.folder-recent-chip:hover {
|
|
359
|
+
color: var(--accent);
|
|
360
|
+
border-color: var(--accent);
|
|
361
|
+
background: var(--accent-dim);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/* New folder row */
|
|
365
|
+
.folder-new-toggle-row {
|
|
366
|
+
margin: 4px 0 8px;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.folder-new-toggle {
|
|
370
|
+
background: none;
|
|
371
|
+
border: 1px dashed var(--border);
|
|
372
|
+
border-radius: var(--radius-md);
|
|
373
|
+
color: var(--text-dim);
|
|
374
|
+
font-family: var(--font-mono);
|
|
375
|
+
font-size: 11px;
|
|
376
|
+
padding: 6px 10px;
|
|
377
|
+
width: 100%;
|
|
378
|
+
cursor: pointer;
|
|
379
|
+
transition: all 0.15s;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.folder-new-toggle:hover {
|
|
383
|
+
color: var(--accent);
|
|
384
|
+
border-color: var(--accent);
|
|
385
|
+
background: var(--accent-dim);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.folder-new-row {
|
|
389
|
+
display: flex;
|
|
390
|
+
gap: 6px;
|
|
391
|
+
align-items: center;
|
|
392
|
+
margin: 4px 0 8px;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.folder-new-row input {
|
|
396
|
+
flex: 1;
|
|
397
|
+
padding: 8px 10px;
|
|
398
|
+
font-size: 12px;
|
|
399
|
+
font-family: var(--font-mono);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.modal-btn-cancel {
|
|
403
|
+
flex-shrink: 0;
|
|
404
|
+
padding: 7px 12px;
|
|
405
|
+
font-size: 11px;
|
|
406
|
+
font-family: var(--font-mono);
|
|
407
|
+
background: transparent;
|
|
408
|
+
color: var(--text-dim);
|
|
409
|
+
border: 1px solid var(--border);
|
|
410
|
+
border-radius: var(--radius-md);
|
|
411
|
+
cursor: pointer;
|
|
412
|
+
transition: all 0.15s;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
.modal-btn-cancel:hover {
|
|
416
|
+
color: var(--text);
|
|
417
|
+
border-color: var(--text-dim);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/* Inline message area (error / success) */
|
|
421
|
+
.add-project-message {
|
|
422
|
+
display: flex;
|
|
423
|
+
align-items: center;
|
|
424
|
+
justify-content: space-between;
|
|
425
|
+
gap: 8px;
|
|
426
|
+
padding: 8px 12px;
|
|
427
|
+
margin-bottom: 10px;
|
|
428
|
+
border-radius: var(--radius-md);
|
|
429
|
+
font-size: 12px;
|
|
430
|
+
font-family: var(--font-mono);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
.add-project-message-error {
|
|
434
|
+
background: rgba(255, 80, 80, 0.08);
|
|
435
|
+
color: #ff8080;
|
|
436
|
+
border: 1px solid rgba(255, 80, 80, 0.3);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.add-project-message-success {
|
|
440
|
+
background: rgba(80, 200, 120, 0.08);
|
|
441
|
+
color: #6ad48a;
|
|
442
|
+
border: 1px solid rgba(80, 200, 120, 0.3);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
.add-project-message-action {
|
|
446
|
+
flex-shrink: 0;
|
|
447
|
+
padding: 3px 10px;
|
|
448
|
+
font-size: 11px;
|
|
449
|
+
font-family: var(--font-mono);
|
|
450
|
+
background: transparent;
|
|
451
|
+
color: inherit;
|
|
452
|
+
border: 1px solid currentColor;
|
|
453
|
+
border-radius: var(--radius-md);
|
|
454
|
+
cursor: pointer;
|
|
455
|
+
opacity: 0.85;
|
|
456
|
+
transition: opacity 0.15s;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.add-project-message-action:hover {
|
|
460
|
+
opacity: 1;
|
|
461
|
+
}
|
|
462
|
+
|
|
290
463
|
/* Sessions */
|
|
291
464
|
.sessions-section {
|
|
292
465
|
flex: 1;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
.settings-modal {
|
|
2
|
+
width: 380px;
|
|
3
|
+
max-width: 90vw;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.settings-list {
|
|
7
|
+
padding: 16px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.settings-row {
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
justify-content: space-between;
|
|
14
|
+
gap: 12px;
|
|
15
|
+
padding: 10px 0;
|
|
16
|
+
cursor: pointer;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.settings-row + .settings-row {
|
|
20
|
+
border-top: 1px solid var(--border);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.settings-label {
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
gap: 2px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.settings-label strong {
|
|
30
|
+
font-size: 13px;
|
|
31
|
+
color: var(--text-primary);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.settings-label small {
|
|
35
|
+
font-size: 11px;
|
|
36
|
+
color: var(--text-secondary);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.settings-toggle {
|
|
40
|
+
appearance: none;
|
|
41
|
+
width: 36px;
|
|
42
|
+
height: 20px;
|
|
43
|
+
background: var(--bg-tertiary);
|
|
44
|
+
border-radius: 10px;
|
|
45
|
+
position: relative;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
flex-shrink: 0;
|
|
48
|
+
transition: background 0.2s;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.settings-toggle:focus-visible {
|
|
52
|
+
outline: 2px solid var(--accent);
|
|
53
|
+
outline-offset: 2px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.settings-toggle::after {
|
|
57
|
+
content: '';
|
|
58
|
+
position: absolute;
|
|
59
|
+
top: 2px;
|
|
60
|
+
left: 2px;
|
|
61
|
+
width: 16px;
|
|
62
|
+
height: 16px;
|
|
63
|
+
border-radius: 50%;
|
|
64
|
+
background: var(--text-secondary);
|
|
65
|
+
transition: transform 0.2s, background 0.2s;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.settings-toggle:checked {
|
|
69
|
+
background: var(--accent);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.settings-toggle:checked::after {
|
|
73
|
+
transform: translateX(16px);
|
|
74
|
+
background: #fff;
|
|
75
|
+
}
|
package/public/index.html
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<link rel="apple-touch-icon" href="/icons/icon-192.png">
|
|
13
13
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
14
14
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
15
|
-
<link href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@400;500;600;700&family=Outfit:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
15
|
+
<link href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@400;500;600;700&family=Source+Serif+4:ital,opsz,wght@0,8..60,400;0,8..60,500;0,8..60,600;0,8..60,700;1,8..60,400;1,8..60,500&family=Outfit:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
16
16
|
<link rel="stylesheet" href="style.css">
|
|
17
17
|
<link id="hljs-theme" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
|
|
18
18
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/driver.js@1.3.6/dist/driver.css">
|
|
@@ -166,6 +166,12 @@
|
|
|
166
166
|
<span id="telegram-label">Telegram</span>
|
|
167
167
|
</button>
|
|
168
168
|
<div style="height:1px;background:var(--border);margin:4px 8px;"></div>
|
|
169
|
+
<button class="header-dropdown-item" id="settings-btn" title="Settings">
|
|
170
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
171
|
+
<line x1="4" y1="21" x2="4" y2="14"/><line x1="4" y1="10" x2="4" y2="3"/><line x1="12" y1="21" x2="12" y2="12"/><line x1="12" y1="8" x2="12" y2="3"/><line x1="20" y1="21" x2="20" y2="16"/><line x1="20" y1="12" x2="20" y2="3"/><line x1="1" y1="14" x2="7" y2="14"/><line x1="9" y1="8" x2="15" y2="8"/><line x1="17" y1="16" x2="23" y2="16"/>
|
|
172
|
+
</svg>
|
|
173
|
+
<span>Settings</span>
|
|
174
|
+
</button>
|
|
169
175
|
<button class="header-dropdown-item" id="dev-docs-btn" title="Developer Documentation">
|
|
170
176
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
171
177
|
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>
|
|
@@ -318,6 +324,7 @@
|
|
|
318
324
|
<span class="input-waiting-dot"></span>
|
|
319
325
|
<span class="input-waiting-text">Claude is waiting for your response</span>
|
|
320
326
|
</div>
|
|
327
|
+
<claudeck-jump-to-latest></claudeck-jump-to-latest>
|
|
321
328
|
<div class="input-bar">
|
|
322
329
|
<div class="input-textarea-wrap">
|
|
323
330
|
<textarea id="message-input" placeholder="> type a message or / for commands..." rows="1"></textarea>
|
|
@@ -515,10 +522,11 @@
|
|
|
515
522
|
<claudeck-shortcuts-modal></claudeck-shortcuts-modal>
|
|
516
523
|
<claudeck-cost-dashboard></claudeck-cost-dashboard>
|
|
517
524
|
<claudeck-bg-confirm></claudeck-bg-confirm>
|
|
525
|
+
<claudeck-queue-stop></claudeck-queue-stop>
|
|
518
526
|
<claudeck-permission-modal></claudeck-permission-modal>
|
|
519
|
-
<claudeck-linear-create></claudeck-linear-create>
|
|
520
527
|
<claudeck-telegram-modal></claudeck-telegram-modal>
|
|
521
528
|
<claudeck-mcp-modal></claudeck-mcp-modal>
|
|
529
|
+
<claudeck-settings-modal></claudeck-settings-modal>
|
|
522
530
|
<claudeck-add-project></claudeck-add-project>
|
|
523
531
|
|
|
524
532
|
<!-- Status Bar (Web Component) -->
|
|
@@ -8,8 +8,22 @@ class AddProjectModal extends HTMLElement {
|
|
|
8
8
|
<button id="add-project-close" class="modal-close">×</button>
|
|
9
9
|
</div>
|
|
10
10
|
<div class="add-project-body">
|
|
11
|
+
<div class="folder-path-row">
|
|
12
|
+
<input id="folder-path-input" type="text" placeholder="Type a path (e.g. ~/code/my-app) and press Enter" autocomplete="off" spellcheck="false">
|
|
13
|
+
<button id="folder-path-go" class="folder-path-go" title="Go to path">Go</button>
|
|
14
|
+
</div>
|
|
15
|
+
<div id="folder-recents" class="folder-recents hidden"></div>
|
|
11
16
|
<div id="folder-breadcrumb" class="folder-breadcrumb"></div>
|
|
12
17
|
<div id="folder-list" class="folder-list"></div>
|
|
18
|
+
<div id="folder-new-row" class="folder-new-row hidden">
|
|
19
|
+
<input id="folder-new-name" type="text" placeholder="New folder name" autocomplete="off" spellcheck="false">
|
|
20
|
+
<button id="folder-new-create" class="modal-btn-save">Create</button>
|
|
21
|
+
<button id="folder-new-cancel" class="modal-btn-cancel">Cancel</button>
|
|
22
|
+
</div>
|
|
23
|
+
<div id="folder-new-toggle-row" class="folder-new-toggle-row">
|
|
24
|
+
<button id="folder-new-toggle" class="folder-new-toggle" type="button">+ New folder here</button>
|
|
25
|
+
</div>
|
|
26
|
+
<div id="add-project-message" class="add-project-message hidden"></div>
|
|
13
27
|
<div class="folder-select-row">
|
|
14
28
|
<input id="add-project-name" type="text" placeholder="Project name" autocomplete="off">
|
|
15
29
|
<button id="add-project-confirm" class="modal-btn-save">Add</button>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Jump-to-latest pill — shown when new content arrives while the user has
|
|
2
|
+
// scrolled up. Click to force-scroll to the bottom and re-engage stick-to-bottom.
|
|
3
|
+
class JumpToLatest extends HTMLElement {
|
|
4
|
+
connectedCallback() {
|
|
5
|
+
this.innerHTML = `
|
|
6
|
+
<button id="jump-to-latest-btn" class="jump-to-latest hidden" type="button" aria-label="Jump to latest message">
|
|
7
|
+
<svg width="14" height="14" viewBox="0 0 20 20" fill="none" aria-hidden="true">
|
|
8
|
+
<path d="M5 8l5 5 5-5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
9
|
+
</svg>
|
|
10
|
+
<span class="jump-to-latest-label">New messages</span>
|
|
11
|
+
</button>`;
|
|
12
|
+
|
|
13
|
+
this._btn = this.querySelector('#jump-to-latest-btn');
|
|
14
|
+
this._onState = (e) => {
|
|
15
|
+
// Only react to the active (single-mode) pane for now. In parallel mode
|
|
16
|
+
// each pane handles its own scroll independently and the global pill stays hidden.
|
|
17
|
+
const detail = e.detail || {};
|
|
18
|
+
if (detail.chatId != null) return;
|
|
19
|
+
if (detail.hasNewBelow) {
|
|
20
|
+
this._btn.classList.remove('hidden');
|
|
21
|
+
} else {
|
|
22
|
+
this._btn.classList.add('hidden');
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
window.addEventListener('claudeck:scroll-state', this._onState);
|
|
26
|
+
|
|
27
|
+
this._btn.addEventListener('click', async () => {
|
|
28
|
+
// Lazy import to avoid pulling parallel.js into component init.
|
|
29
|
+
const [{ getPane }, { scrollToBottom }] = await Promise.all([
|
|
30
|
+
import('../ui/parallel.js'),
|
|
31
|
+
import('../core/utils.js'),
|
|
32
|
+
]);
|
|
33
|
+
const pane = getPane(null);
|
|
34
|
+
if (pane) scrollToBottom(pane, { force: true });
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
disconnectedCallback() {
|
|
39
|
+
if (this._onState) window.removeEventListener('claudeck:scroll-state', this._onState);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
customElements.define('claudeck-jump-to-latest', JumpToLatest);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Web Component: Queue Stop Confirmation Dialog
|
|
2
|
+
class ClaudeckQueueStop extends HTMLElement {
|
|
3
|
+
connectedCallback() {
|
|
4
|
+
this.innerHTML = `
|
|
5
|
+
<div id="queue-stop-modal" class="modal-overlay hidden" data-persistent>
|
|
6
|
+
<div class="modal queue-stop-modal">
|
|
7
|
+
<div class="modal-header">
|
|
8
|
+
<h3>Queue Active</h3>
|
|
9
|
+
</div>
|
|
10
|
+
<p class="queue-stop-text">You have queued messages. What would you like to do?</p>
|
|
11
|
+
<div class="mq-queue-preview" id="queue-stop-preview"></div>
|
|
12
|
+
<div class="modal-actions queue-stop-actions">
|
|
13
|
+
<button id="queue-stop-all" class="modal-btn-cancel queue-stop-terminate">Terminate All</button>
|
|
14
|
+
<button id="queue-stop-skip" class="modal-btn-cancel">Skip to Next</button>
|
|
15
|
+
<button id="queue-stop-pause" class="modal-btn-save">Just Stop Current</button>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
`;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
customElements.define('claudeck-queue-stop', ClaudeckQueueStop);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Web Component: Settings Modal
|
|
2
|
+
const SETTINGS_KEY = 'claudeck-settings';
|
|
3
|
+
|
|
4
|
+
function loadSettings() {
|
|
5
|
+
try { return JSON.parse(localStorage.getItem(SETTINGS_KEY) || '{}'); } catch { return {}; }
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function saveSettings(s) {
|
|
9
|
+
localStorage.setItem(SETTINGS_KEY, JSON.stringify(s));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function getSetting(key, fallback = true) {
|
|
13
|
+
const s = loadSettings();
|
|
14
|
+
return s[key] !== undefined ? s[key] : fallback;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class ClaudeckSettingsModal extends HTMLElement {
|
|
18
|
+
connectedCallback() {
|
|
19
|
+
this.innerHTML = `
|
|
20
|
+
<div id="settings-modal" class="modal-overlay hidden">
|
|
21
|
+
<div class="modal settings-modal">
|
|
22
|
+
<div class="modal-header">
|
|
23
|
+
<h3>Settings</h3>
|
|
24
|
+
<button id="settings-modal-close" class="modal-close">×</button>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="settings-list">
|
|
27
|
+
<label class="settings-row">
|
|
28
|
+
<span class="settings-label">
|
|
29
|
+
<strong>Assistant Bot</strong>
|
|
30
|
+
<small>Show the floating assistant bot bubble</small>
|
|
31
|
+
</span>
|
|
32
|
+
<input type="checkbox" id="setting-assistant-bot" class="settings-toggle">
|
|
33
|
+
</label>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
const overlay = this.querySelector('#settings-modal');
|
|
40
|
+
const closeBtn = this.querySelector('#settings-modal-close');
|
|
41
|
+
const botToggle = this.querySelector('#setting-assistant-bot');
|
|
42
|
+
|
|
43
|
+
// Init toggle state
|
|
44
|
+
botToggle.checked = getSetting('assistantBot', true);
|
|
45
|
+
|
|
46
|
+
closeBtn.addEventListener('click', () => overlay.classList.add('hidden'));
|
|
47
|
+
overlay.addEventListener('click', (e) => { if (e.target === overlay) overlay.classList.add('hidden'); });
|
|
48
|
+
|
|
49
|
+
botToggle.addEventListener('change', () => {
|
|
50
|
+
const s = loadSettings();
|
|
51
|
+
s.assistantBot = botToggle.checked;
|
|
52
|
+
saveSettings(s);
|
|
53
|
+
// Dispatch event so the bot module can react
|
|
54
|
+
window.dispatchEvent(new CustomEvent('setting:assistantBot', { detail: botToggle.checked }));
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Open from settings button
|
|
58
|
+
document.getElementById('settings-btn')?.addEventListener('click', () => {
|
|
59
|
+
botToggle.checked = getSetting('assistantBot', true);
|
|
60
|
+
overlay.classList.remove('hidden');
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
customElements.define('claudeck-settings-modal', ClaudeckSettingsModal);
|