claude-relay 2.3.1 → 2.4.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 (52) hide show
  1. package/README.md +20 -5
  2. package/bin/cli.js +206 -8
  3. package/lib/cli-sessions.js +270 -0
  4. package/lib/daemon.js +40 -0
  5. package/lib/project.js +121 -1
  6. package/lib/public/app.js +385 -76
  7. package/lib/public/css/base.css +41 -7
  8. package/lib/public/css/diff.css +6 -6
  9. package/lib/public/css/filebrowser.css +34 -54
  10. package/lib/public/css/highlight.css +144 -0
  11. package/lib/public/css/input.css +9 -9
  12. package/lib/public/css/menus.css +82 -23
  13. package/lib/public/css/messages.css +178 -34
  14. package/lib/public/css/overlays.css +166 -50
  15. package/lib/public/css/rewind.css +17 -17
  16. package/lib/public/css/sidebar.css +210 -137
  17. package/lib/public/index.html +73 -40
  18. package/lib/public/modules/filebrowser.js +2 -1
  19. package/lib/public/modules/markdown.js +10 -10
  20. package/lib/public/modules/notifications.js +38 -1
  21. package/lib/public/modules/sidebar.js +109 -31
  22. package/lib/public/modules/terminal.js +11 -23
  23. package/lib/public/modules/theme.js +622 -0
  24. package/lib/public/modules/tools.js +245 -4
  25. package/lib/public/modules/utils.js +21 -5
  26. package/lib/public/style.css +1 -0
  27. package/lib/sdk-bridge.js +95 -0
  28. package/lib/server.js +41 -0
  29. package/lib/sessions.js +16 -3
  30. package/lib/themes/ayu-light.json +9 -0
  31. package/lib/themes/catppuccin-latte.json +9 -0
  32. package/lib/themes/catppuccin-mocha.json +9 -0
  33. package/lib/themes/claude-light.json +9 -0
  34. package/lib/themes/claude.json +9 -0
  35. package/lib/themes/dracula.json +9 -0
  36. package/lib/themes/everforest-light.json +9 -0
  37. package/lib/themes/everforest.json +9 -0
  38. package/lib/themes/github-light.json +9 -0
  39. package/lib/themes/gruvbox-dark.json +9 -0
  40. package/lib/themes/gruvbox-light.json +9 -0
  41. package/lib/themes/monokai.json +9 -0
  42. package/lib/themes/nord-light.json +9 -0
  43. package/lib/themes/nord.json +9 -0
  44. package/lib/themes/one-dark.json +9 -0
  45. package/lib/themes/one-light.json +9 -0
  46. package/lib/themes/rose-pine-dawn.json +9 -0
  47. package/lib/themes/rose-pine.json +9 -0
  48. package/lib/themes/solarized-dark.json +9 -0
  49. package/lib/themes/solarized-light.json +9 -0
  50. package/lib/themes/tokyo-night-light.json +9 -0
  51. package/lib/themes/tokyo-night.json +9 -0
  52. package/package.json +2 -1
@@ -9,13 +9,13 @@
9
9
  box-sizing: border-box;
10
10
  -webkit-tap-highlight-color: transparent;
11
11
  scrollbar-width: thin;
12
- scrollbar-color: rgba(255,255,255,0.15) transparent;
12
+ scrollbar-color: rgba(var(--overlay-rgb),0.15) transparent;
13
13
  }
14
14
 
15
15
  ::-webkit-scrollbar { width: 6px; height: 6px; }
16
16
  ::-webkit-scrollbar-track { background: transparent; }
17
- ::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 3px; }
18
- ::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.25); }
17
+ ::-webkit-scrollbar-thumb { background: rgba(var(--overlay-rgb),0.15); border-radius: 3px; }
18
+ ::-webkit-scrollbar-thumb:hover { background: rgba(var(--overlay-rgb),0.25); }
19
19
 
20
20
  :root {
21
21
  --bg: #2F2E2B;
@@ -34,6 +34,40 @@
34
34
  --user-bubble: #46423A;
35
35
  --error: #E5534B;
36
36
  --success: #57AB5A;
37
+ --warning: #E5A84B;
38
+ --accent-8: rgba(218, 119, 86, 0.08);
39
+ --accent-12: rgba(218, 119, 86, 0.12);
40
+ --accent-15: rgba(218, 119, 86, 0.15);
41
+ --accent-20: rgba(218, 119, 86, 0.20);
42
+ --accent-25: rgba(218, 119, 86, 0.25);
43
+ --accent-30: rgba(218, 119, 86, 0.30);
44
+ --error-8: rgba(229, 83, 75, 0.08);
45
+ --error-12: rgba(229, 83, 75, 0.12);
46
+ --error-15: rgba(229, 83, 75, 0.15);
47
+ --error-25: rgba(229, 83, 75, 0.25);
48
+ --success-8: rgba(87, 171, 90, 0.08);
49
+ --success-12: rgba(87, 171, 90, 0.12);
50
+ --success-15: rgba(87, 171, 90, 0.15);
51
+ --success-25: rgba(87, 171, 90, 0.25);
52
+ --warning-bg: rgba(229, 168, 75, 0.12);
53
+ --overlay-rgb: 255,255,255;
54
+ --shadow-rgb: 0,0,0;
55
+ --hl-comment: #6D6860;
56
+ --hl-keyword: #C586C0;
57
+ --hl-string: #57AB5A;
58
+ --hl-number: #DA7756;
59
+ --hl-function: #569CD6;
60
+ --hl-variable: #E5534B;
61
+ --hl-type: #E5A84B;
62
+ --hl-constant: #DA7756;
63
+ --hl-tag: #E5534B;
64
+ --hl-attr: #569CD6;
65
+ --hl-regexp: #4EC9B0;
66
+ --hl-meta: #D7BA7D;
67
+ --hl-builtin: #DA7756;
68
+ --hl-symbol: #D7BA7D;
69
+ --hl-addition: #57AB5A;
70
+ --hl-deletion: #E5534B;
37
71
  --sidebar-bg: #262522;
38
72
  --sidebar-hover: #302E2A;
39
73
  --sidebar-active: #3A3834;
@@ -96,7 +130,7 @@ html, body {
96
130
  opacity: 0;
97
131
  transition: opacity 0.2s, transform 0.2s;
98
132
  pointer-events: none;
99
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
133
+ box-shadow: 0 4px 20px rgba(var(--shadow-rgb), 0.3);
100
134
  }
101
135
 
102
136
  .toast.visible {
@@ -104,8 +138,8 @@ html, body {
104
138
  transform: translateX(-50%) translateY(0);
105
139
  }
106
140
  .toast.toast-warn {
107
- background: #3a2a00;
108
- border-color: #7a5a00;
109
- color: #ffc107;
141
+ background: var(--warning-bg);
142
+ border-color: var(--warning);
143
+ color: var(--warning);
110
144
  }
111
145
 
@@ -51,19 +51,19 @@
51
51
 
52
52
  /* --- Unified diff row colors --- */
53
53
  .diff-row-remove {
54
- background: rgba(229, 83, 75, 0.12);
54
+ background: var(--error-12);
55
55
  }
56
56
 
57
57
  .diff-row-remove .diff-marker {
58
- color: var(--diff-remove, #E5534B);
58
+ color: var(--error);
59
59
  }
60
60
 
61
61
  .diff-row-add {
62
- background: rgba(87, 171, 90, 0.12);
62
+ background: var(--success-12);
63
63
  }
64
64
 
65
65
  .diff-row-add .diff-marker {
66
- color: var(--diff-add, #57AB5A);
66
+ color: var(--success);
67
67
  }
68
68
 
69
69
  /* --- Hunk header row (patch diffs) --- */
@@ -92,12 +92,12 @@
92
92
  /* Split: change rows */
93
93
  .diff-row-change .diff-code-old,
94
94
  .diff-row-remove .diff-code-old {
95
- background: rgba(229, 83, 75, 0.12);
95
+ background: var(--error-12);
96
96
  }
97
97
 
98
98
  .diff-row-change .diff-code-new,
99
99
  .diff-row-add .diff-code-new {
100
- background: rgba(87, 171, 90, 0.12);
100
+ background: var(--success-12);
101
101
  }
102
102
 
103
103
  /* Empty cells in split view */
@@ -32,50 +32,12 @@
32
32
  .sidebar-panel { flex: 1; overflow-y: auto; min-height: 0; }
33
33
  .sidebar-panel.hidden { display: none; }
34
34
 
35
- /* --- File panel header --- */
36
- #file-panel-header {
37
- display: flex;
38
- align-items: center;
39
- padding: 4px 8px;
40
- }
41
-
42
- #file-panel-back {
43
- display: flex;
44
- align-items: center;
45
- gap: 8px;
46
- padding: 8px 12px;
47
- border-radius: 10px;
48
- border: none;
49
- background: transparent;
50
- color: var(--text-secondary);
51
- font-family: inherit;
52
- font-size: 14px;
53
- font-weight: 400;
54
- cursor: pointer;
55
- flex: 1;
56
- transition: background 0.15s, color 0.15s;
57
- }
58
-
59
- #file-panel-back .lucide { width: 16px; height: 16px; flex-shrink: 0; }
60
- #file-panel-back:hover { background: var(--sidebar-hover); color: var(--text); }
61
-
62
- #file-panel-refresh {
63
- display: flex;
64
- align-items: center;
65
- justify-content: center;
66
- width: 32px;
67
- height: 32px;
68
- border-radius: 8px;
69
- border: none;
70
- background: transparent;
71
- color: var(--text-muted);
72
- cursor: pointer;
73
- flex-shrink: 0;
74
- transition: background 0.15s, color 0.15s, transform 0.3s;
35
+ /* --- File browser header --- */
36
+ #sessions-header-content.hidden,
37
+ #files-header-content.hidden {
38
+ display: none;
75
39
  }
76
40
 
77
- #file-panel-refresh .lucide { width: 14px; height: 14px; }
78
- #file-panel-refresh:hover { background: var(--sidebar-hover); color: var(--text); }
79
41
  #file-panel-refresh.spinning { animation: spin-once 0.5s ease; }
80
42
  @keyframes spin-once { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
81
43
 
@@ -414,7 +376,6 @@
414
376
 
415
377
  .terminal-tabs {
416
378
  display: flex;
417
- flex: 1;
418
379
  overflow-x: auto;
419
380
  -webkit-overflow-scrolling: touch;
420
381
  gap: 0;
@@ -424,6 +385,25 @@
424
385
 
425
386
  .terminal-tabs::-webkit-scrollbar { display: none; }
426
387
 
388
+ .terminal-new-tab-btn {
389
+ display: flex;
390
+ align-items: center;
391
+ justify-content: center;
392
+ width: 28px;
393
+ height: 28px;
394
+ flex-shrink: 0;
395
+ border: none;
396
+ background: transparent;
397
+ color: var(--text-muted);
398
+ cursor: pointer;
399
+ border-radius: 6px;
400
+ padding: 0;
401
+ margin: 4px 2px;
402
+ transition: background 0.15s, color 0.15s;
403
+ }
404
+ .terminal-new-tab-btn:hover { background: rgba(var(--overlay-rgb),0.08); color: var(--text); }
405
+ .terminal-new-tab-btn .lucide { width: 14px; height: 14px; }
406
+
427
407
  .terminal-tab {
428
408
  display: flex;
429
409
  align-items: center;
@@ -461,7 +441,7 @@
461
441
 
462
442
  .terminal-tab:hover .terminal-tab-close,
463
443
  .terminal-tab.active .terminal-tab-close { display: flex; }
464
- .terminal-tab-close:hover { background: rgba(255,255,255,0.1); color: var(--text); }
444
+ .terminal-tab-close:hover { background: rgba(var(--overlay-rgb),0.1); color: var(--text); }
465
445
 
466
446
  .terminal-tab-label { cursor: default; }
467
447
 
@@ -483,6 +463,7 @@
483
463
  gap: 2px;
484
464
  padding: 0 8px;
485
465
  flex-shrink: 0;
466
+ margin-left: auto;
486
467
  }
487
468
 
488
469
  /* Wide screens: split panel beside #app */
@@ -517,7 +498,6 @@
517
498
 
518
499
  #terminal-body {
519
500
  flex: 1;
520
- background: #1a1a1a;
521
501
  min-height: 0;
522
502
  overflow: hidden;
523
503
  position: relative;
@@ -526,7 +506,7 @@
526
506
  .terminal-tab-body {
527
507
  position: absolute;
528
508
  inset: 0;
529
- padding: 4px;
509
+ padding: 4px 0 0 4px;
530
510
  }
531
511
 
532
512
  .terminal-tab-body .xterm {
@@ -606,7 +586,7 @@
606
586
  border-radius: 10px;
607
587
  padding: 4px 0;
608
588
  min-width: 160px;
609
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
589
+ box-shadow: 0 4px 16px rgba(var(--shadow-rgb), 0.4);
610
590
  z-index: 500;
611
591
  }
612
592
 
@@ -626,7 +606,7 @@
626
606
  }
627
607
 
628
608
  .term-ctx-item .lucide { width: 14px; height: 14px; flex-shrink: 0; }
629
- .term-ctx-item:hover { background: rgba(255, 255, 255, 0.05); }
609
+ .term-ctx-item:hover { background: rgba(var(--overlay-rgb), 0.05); }
630
610
 
631
611
  /* --- File Edit History --- */
632
612
 
@@ -727,7 +707,7 @@
727
707
  }
728
708
 
729
709
  .file-history-badge.badge-commit {
730
- background: rgba(255,255,255,0.06);
710
+ background: rgba(var(--overlay-rgb),0.06);
731
711
  color: var(--text-muted);
732
712
  }
733
713
 
@@ -737,7 +717,7 @@
737
717
  color: var(--text-muted);
738
718
  margin-top: 4px;
739
719
  padding: 2px 6px;
740
- background: rgba(255, 255, 255, 0.04);
720
+ background: rgba(var(--overlay-rgb), 0.04);
741
721
  border-radius: 3px;
742
722
  overflow: hidden;
743
723
  text-overflow: ellipsis;
@@ -811,7 +791,7 @@
811
791
  padding: 10px 12px;
812
792
  margin-bottom: 8px;
813
793
  border-radius: 8px;
814
- background: rgba(255, 255, 255, 0.04);
794
+ background: rgba(var(--overlay-rgb), 0.04);
815
795
  border: 1px solid var(--border);
816
796
  }
817
797
 
@@ -846,11 +826,11 @@
846
826
  flex: 1;
847
827
  min-width: 0;
848
828
  padding: 7px 10px;
849
- border: 1.5px dashed rgba(255, 255, 255, 0.15);
829
+ border: 1.5px dashed rgba(var(--overlay-rgb), 0.15);
850
830
  border-radius: 6px;
851
831
  font-size: 11px;
852
832
  color: var(--text-muted);
853
- background: rgba(255, 255, 255, 0.02);
833
+ background: rgba(var(--overlay-rgb), 0.02);
854
834
  transition: border-color 0.15s, background 0.15s;
855
835
  }
856
836
 
@@ -871,7 +851,7 @@
871
851
  font-size: 10px;
872
852
  font-weight: 700;
873
853
  flex-shrink: 0;
874
- background: rgba(255, 255, 255, 0.1);
854
+ background: rgba(var(--overlay-rgb), 0.1);
875
855
  color: var(--text-muted);
876
856
  }
877
857
 
@@ -0,0 +1,144 @@
1
+ /* ==========================================================================
2
+ Syntax Highlighting (highlight.js) — base16 CSS-variable driven
3
+ Replaces CDN github-dark-dimmed.min.css
4
+ ========================================================================== */
5
+
6
+ .hljs {
7
+ color: var(--text);
8
+ background: var(--code-bg);
9
+ }
10
+
11
+ /* --- Comments --- */
12
+ .hljs-comment,
13
+ .hljs-quote {
14
+ color: var(--hl-comment);
15
+ font-style: italic;
16
+ }
17
+
18
+ /* --- Keywords / control flow --- */
19
+ .hljs-keyword,
20
+ .hljs-selector-tag,
21
+ .hljs-selector-id {
22
+ color: var(--hl-keyword);
23
+ }
24
+
25
+ /* --- Strings / template literals --- */
26
+ .hljs-string,
27
+ .hljs-doctag,
28
+ .hljs-selector-class {
29
+ color: var(--hl-string);
30
+ }
31
+
32
+ /* --- Numbers / booleans / null --- */
33
+ .hljs-number,
34
+ .hljs-literal {
35
+ color: var(--hl-number);
36
+ }
37
+
38
+ /* --- Functions / method calls --- */
39
+ .hljs-title,
40
+ .hljs-title.function_,
41
+ .hljs-section {
42
+ color: var(--hl-function);
43
+ }
44
+
45
+ /* --- Variables / params --- */
46
+ .hljs-variable,
47
+ .hljs-template-variable,
48
+ .hljs-params {
49
+ color: var(--hl-variable);
50
+ }
51
+
52
+ /* --- Types / classes --- */
53
+ .hljs-type,
54
+ .hljs-title.class_,
55
+ .hljs-title.class_.inherited__ {
56
+ color: var(--hl-type);
57
+ }
58
+
59
+ /* --- Constants / built-ins --- */
60
+ .hljs-built_in {
61
+ color: var(--hl-builtin);
62
+ }
63
+
64
+ /* --- Tags (HTML/XML) --- */
65
+ .hljs-tag,
66
+ .hljs-name {
67
+ color: var(--hl-tag);
68
+ }
69
+
70
+ /* --- Attributes --- */
71
+ .hljs-attr,
72
+ .hljs-attribute {
73
+ color: var(--hl-attr);
74
+ }
75
+
76
+ /* --- Regexp / links --- */
77
+ .hljs-regexp,
78
+ .hljs-link {
79
+ color: var(--hl-regexp);
80
+ }
81
+
82
+ /* --- Meta / preprocessor --- */
83
+ .hljs-meta,
84
+ .hljs-meta .hljs-keyword,
85
+ .hljs-meta .hljs-string {
86
+ color: var(--hl-meta);
87
+ }
88
+
89
+ /* --- Symbols / special --- */
90
+ .hljs-symbol,
91
+ .hljs-bullet {
92
+ color: var(--hl-symbol);
93
+ }
94
+
95
+ /* --- Diff additions / deletions --- */
96
+ .hljs-addition {
97
+ color: var(--hl-addition);
98
+ background: var(--success-8);
99
+ }
100
+
101
+ .hljs-deletion {
102
+ color: var(--hl-deletion);
103
+ background: var(--error-8);
104
+ }
105
+
106
+ /* --- Emphasis / strong --- */
107
+ .hljs-emphasis {
108
+ font-style: italic;
109
+ }
110
+
111
+ .hljs-strong {
112
+ font-weight: 700;
113
+ }
114
+
115
+ /* --- Subst / interpolation --- */
116
+ .hljs-subst {
117
+ color: var(--text);
118
+ }
119
+
120
+ /* --- Selector --- */
121
+ .hljs-selector-attr,
122
+ .hljs-selector-pseudo {
123
+ color: var(--hl-keyword);
124
+ }
125
+
126
+ /* --- Property (CSS, JSON keys) --- */
127
+ .hljs-property {
128
+ color: var(--hl-attr);
129
+ }
130
+
131
+ /* --- Punctuation (brackets etc.) --- */
132
+ .hljs-punctuation {
133
+ color: var(--text-secondary);
134
+ }
135
+
136
+ /* --- Operator --- */
137
+ .hljs-operator {
138
+ color: var(--hl-keyword);
139
+ }
140
+
141
+ /* --- Char / escape sequences --- */
142
+ .hljs-char.escape_ {
143
+ color: var(--hl-regexp);
144
+ }
@@ -12,7 +12,7 @@
12
12
  display: inline-flex;
13
13
  align-items: center;
14
14
  gap: 8px;
15
- background: rgba(255, 255, 255, 0.06);
15
+ background: rgba(var(--overlay-rgb), 0.06);
16
16
  border: 1px solid var(--border);
17
17
  border-radius: 10px;
18
18
  padding: 8px 12px;
@@ -23,7 +23,7 @@
23
23
 
24
24
  .bubble-paste:hover {
25
25
  border-color: var(--text-dimmer);
26
- background: rgba(255, 255, 255, 0.1);
26
+ background: rgba(var(--overlay-rgb), 0.1);
27
27
  }
28
28
 
29
29
  .bubble-paste-preview {
@@ -90,7 +90,7 @@
90
90
  }
91
91
 
92
92
  .pasted-chip-remove .lucide { width: 12px; height: 12px; }
93
- .pasted-chip-remove:hover { color: var(--text); background: rgba(255, 255, 255, 0.1); }
93
+ .pasted-chip-remove:hover { color: var(--text); background: rgba(var(--overlay-rgb), 0.1); }
94
94
 
95
95
  /* --- Paste viewer modal --- */
96
96
  #paste-modal { position: fixed; inset: 0; z-index: 300; display: flex; align-items: center; justify-content: center; }
@@ -133,7 +133,7 @@
133
133
  transition: color 0.15s, background 0.15s;
134
134
  }
135
135
 
136
- .paste-modal-close:hover { color: var(--text); background: rgba(255, 255, 255, 0.06); }
136
+ .paste-modal-close:hover { color: var(--text); background: rgba(var(--overlay-rgb), 0.06); }
137
137
 
138
138
  .paste-modal-body {
139
139
  margin: 0;
@@ -288,7 +288,7 @@
288
288
  }
289
289
 
290
290
  #attach-btn .lucide { width: 20px; height: 20px; }
291
- #attach-btn:hover { background: rgba(255, 255, 255, 0.06); color: var(--text); }
291
+ #attach-btn:hover { background: rgba(var(--overlay-rgb), 0.06); color: var(--text); }
292
292
 
293
293
  #attach-menu {
294
294
  position: absolute;
@@ -298,7 +298,7 @@
298
298
  background: var(--bg-alt);
299
299
  border: 1px solid var(--border);
300
300
  border-radius: 14px;
301
- box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.4);
301
+ box-shadow: 0 -4px 24px rgba(var(--shadow-rgb), 0.4);
302
302
  z-index: 10;
303
303
  overflow: hidden;
304
304
  }
@@ -325,7 +325,7 @@
325
325
  }
326
326
 
327
327
  .attach-menu-item:hover {
328
- background: rgba(255, 255, 255, 0.05);
328
+ background: rgba(var(--overlay-rgb), 0.05);
329
329
  color: var(--text);
330
330
  }
331
331
 
@@ -381,7 +381,7 @@
381
381
  border: 1px solid var(--border);
382
382
  border-radius: 14px;
383
383
  margin-bottom: 8px;
384
- box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.4);
384
+ box-shadow: 0 -4px 24px rgba(var(--shadow-rgb), 0.4);
385
385
  z-index: 10;
386
386
  }
387
387
 
@@ -400,7 +400,7 @@
400
400
 
401
401
  .slash-item:hover,
402
402
  .slash-item.active {
403
- background: rgba(255, 255, 255, 0.05);
403
+ background: rgba(var(--overlay-rgb), 0.05);
404
404
  }
405
405
 
406
406
  .slash-item .slash-cmd {