jupyterlab_claude_code_extension 1.0.50 → 1.0.54
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 +9 -10
- package/lib/index.js +21 -2
- package/lib/types.d.ts +1 -0
- package/lib/widget.d.ts +8 -1
- package/lib/widget.js +37 -12
- package/package.json +1 -1
- package/src/__tests__/jupyterlab_claude_code_extension.spec.ts +1 -0
- package/src/index.ts +24 -2
- package/src/types.ts +1 -0
- package/src/widget.ts +42 -12
- package/style/base.css +6 -3
package/README.md
CHANGED
|
@@ -8,21 +8,20 @@
|
|
|
8
8
|
[](https://kolomolo.com)
|
|
9
9
|
[](https://www.paypal.com/donate/?hosted_button_id=B4KPBJDLLXTSA)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Browse, resume, and manage your Claude Code sessions from a JupyterLab side panel. One click reactivates the right terminal, no duplicate tabs, with a live indicator showing which sessions are currently active.
|
|
12
12
|
|
|
13
13
|

|
|
14
14
|
|
|
15
15
|
## Features
|
|
16
16
|
|
|
17
|
-
- **Three-section side panel** -
|
|
18
|
-
- **Live
|
|
19
|
-
- **One-click resume** - click a row to
|
|
20
|
-
- **
|
|
21
|
-
- **
|
|
22
|
-
- **
|
|
23
|
-
- **
|
|
24
|
-
- **Auto-disabled** when the
|
|
25
|
-
- **Hover tooltip** with relative path (vs JL root), last activity, message count, branch, first prompt, session id
|
|
17
|
+
- **Three-section side panel** - Favorites, Recent, and All projects, each scrolling independently
|
|
18
|
+
- **Live indicator** - a green dot marks sessions that are currently running somewhere
|
|
19
|
+
- **One-click resume** - click a row to jump back into that session in a terminal. If a terminal for the project is already open, it's reused instead of duplicated
|
|
20
|
+
- **Favorites** - star projects you keep coming back to via the right-click menu
|
|
21
|
+
- **Search** - fuzzy filter at the top of the panel
|
|
22
|
+
- **Presentation modes** - label rows by session name, folder name, or path relative to the JupyterLab root
|
|
23
|
+
- **Hover tooltip** with project path, last activity, message count, branch, and session id
|
|
24
|
+
- **Auto-disabled** when the Claude Code CLI is not installed
|
|
26
25
|
|
|
27
26
|
## Requirements
|
|
28
27
|
|
package/lib/index.js
CHANGED
|
@@ -7,7 +7,7 @@ const PLUGIN_ID = 'jupyterlab_claude_code_extension:plugin';
|
|
|
7
7
|
const WIDGET_ID = 'jupyterlab-claude-code-extension';
|
|
8
8
|
const plugin = {
|
|
9
9
|
id: PLUGIN_ID,
|
|
10
|
-
description: 'Side panel listing Claude Code sessions per project folder, with remote-control indicator,
|
|
10
|
+
description: 'Side panel listing Claude Code sessions per project folder, with remote-control indicator, favorites, and one-click resume in a terminal.',
|
|
11
11
|
autoStart: true,
|
|
12
12
|
requires: [ILabShell],
|
|
13
13
|
optional: [ILayoutRestorer, ISettingRegistry, ITerminalTracker],
|
|
@@ -26,10 +26,17 @@ const plugin = {
|
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
28
|
const widget = new ClaudeCodeSessionsWidget(app, status.root_dir || '', terminalTracker);
|
|
29
|
-
|
|
29
|
+
// Read the sidebar setting before docking so we add the widget to the
|
|
30
|
+
// user's preferred side on first paint. Default to left.
|
|
31
|
+
let currentSidebar = 'left';
|
|
30
32
|
if (settingRegistry) {
|
|
31
33
|
try {
|
|
32
34
|
const settings = await settingRegistry.load(PLUGIN_ID);
|
|
35
|
+
const initialSidebar = settings.get('sidebar').composite;
|
|
36
|
+
if (initialSidebar === 'left' || initialSidebar === 'right') {
|
|
37
|
+
currentSidebar = initialSidebar;
|
|
38
|
+
}
|
|
39
|
+
labShell.add(widget, currentSidebar, { rank: 600 });
|
|
33
40
|
const apply = () => {
|
|
34
41
|
const mode = settings.get('presentationMode').composite;
|
|
35
42
|
if (mode === 'session' || mode === 'folder' || mode === 'path') {
|
|
@@ -42,14 +49,26 @@ const plugin = {
|
|
|
42
49
|
const dangerous = settings.get('dangerouslySkipPermissions')
|
|
43
50
|
.composite;
|
|
44
51
|
widget.setDangerouslySkipPermissions(!!dangerous);
|
|
52
|
+
const sidebar = settings.get('sidebar').composite;
|
|
53
|
+
if ((sidebar === 'left' || sidebar === 'right') &&
|
|
54
|
+
sidebar !== currentSidebar) {
|
|
55
|
+
currentSidebar = sidebar;
|
|
56
|
+
// Lumino re-parents the widget cleanly when add() is called
|
|
57
|
+
// against a different area.
|
|
58
|
+
labShell.add(widget, sidebar, { rank: 600 });
|
|
59
|
+
}
|
|
45
60
|
};
|
|
46
61
|
apply();
|
|
47
62
|
settings.changed.connect(apply);
|
|
48
63
|
}
|
|
49
64
|
catch (err) {
|
|
50
65
|
console.warn('[jupyterlab_claude_code_extension] failed to load settings; using defaults', err);
|
|
66
|
+
labShell.add(widget, currentSidebar, { rank: 600 });
|
|
51
67
|
}
|
|
52
68
|
}
|
|
69
|
+
else {
|
|
70
|
+
labShell.add(widget, currentSidebar, { rank: 600 });
|
|
71
|
+
}
|
|
53
72
|
// Register with the layout restorer so JL remembers whether the panel
|
|
54
73
|
// was active/visible across browser reloads and restarts.
|
|
55
74
|
if (restorer) {
|
package/lib/types.d.ts
CHANGED
package/lib/widget.d.ts
CHANGED
|
@@ -49,7 +49,14 @@ export declare class ClaudeCodeSessionsWidget extends Widget {
|
|
|
49
49
|
* handled separately in ``_disambiguate``). */
|
|
50
50
|
private _displayName;
|
|
51
51
|
private _basename;
|
|
52
|
-
/** Walk path tails until every name in a colliding group is unique.
|
|
52
|
+
/** Walk path tails until every name in a colliding group is unique.
|
|
53
|
+
*
|
|
54
|
+
* User-set rename names (``name_source === 'rename'``) survive
|
|
55
|
+
* disambiguation untouched: a Claude ``/rename`` should never be rolled
|
|
56
|
+
* back to a path tail just because some other row happens to share its
|
|
57
|
+
* folder basename. Basename-derived rows in the same group get the path
|
|
58
|
+
* tail suffix, picked so it stays distinct from every rename label too.
|
|
59
|
+
*/
|
|
53
60
|
private _disambiguate;
|
|
54
61
|
private _render;
|
|
55
62
|
private _renderSection;
|
package/lib/widget.js
CHANGED
|
@@ -8,7 +8,7 @@ const DEFAULT_RECENT_LIMIT = 10;
|
|
|
8
8
|
const EXPANDED_STORAGE_KEY = 'jupyterlab_claude_code_extension:expanded';
|
|
9
9
|
const DEFAULT_PRESENTATION_MODE = 'session';
|
|
10
10
|
const SECTION_LABELS = {
|
|
11
|
-
favourites: '
|
|
11
|
+
favourites: 'Favorites',
|
|
12
12
|
recent: 'Recent',
|
|
13
13
|
all: 'All'
|
|
14
14
|
};
|
|
@@ -472,7 +472,14 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
472
472
|
const parts = p.split('/').filter(Boolean);
|
|
473
473
|
return parts[parts.length - 1] || '';
|
|
474
474
|
}
|
|
475
|
-
/** Walk path tails until every name in a colliding group is unique.
|
|
475
|
+
/** Walk path tails until every name in a colliding group is unique.
|
|
476
|
+
*
|
|
477
|
+
* User-set rename names (``name_source === 'rename'``) survive
|
|
478
|
+
* disambiguation untouched: a Claude ``/rename`` should never be rolled
|
|
479
|
+
* back to a path tail just because some other row happens to share its
|
|
480
|
+
* folder basename. Basename-derived rows in the same group get the path
|
|
481
|
+
* tail suffix, picked so it stays distinct from every rename label too.
|
|
482
|
+
*/
|
|
476
483
|
_disambiguate(rows) {
|
|
477
484
|
var _a;
|
|
478
485
|
const out = new Map();
|
|
@@ -486,20 +493,38 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
486
493
|
out.set(group[0].project_path, name);
|
|
487
494
|
continue;
|
|
488
495
|
}
|
|
489
|
-
const
|
|
496
|
+
const renames = group.filter(r => r.name_source === 'rename');
|
|
497
|
+
const basenames = group.filter(r => r.name_source !== 'rename');
|
|
498
|
+
// Rename rows win unchanged. The ``taken`` set guards basename
|
|
499
|
+
// disambiguation from colliding back into a rename's label.
|
|
500
|
+
const taken = new Set();
|
|
501
|
+
for (const r of renames) {
|
|
502
|
+
out.set(r.project_path, r.name);
|
|
503
|
+
taken.add(r.name);
|
|
504
|
+
}
|
|
505
|
+
if (basenames.length === 0) {
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
// Walk path tails for basename rows: tail must be unique among
|
|
509
|
+
// basenames AND not equal to any rename label already taken.
|
|
510
|
+
const segs = basenames.map(r => r.project_path.split('/').filter(Boolean));
|
|
490
511
|
const max = Math.max(...segs.map(s => s.length));
|
|
491
512
|
let depth = 1;
|
|
513
|
+
let resolved = false;
|
|
492
514
|
while (depth <= max) {
|
|
493
515
|
const tails = segs.map(s => s.slice(-depth).join('/'));
|
|
494
|
-
|
|
495
|
-
|
|
516
|
+
const unique = new Set(tails).size === tails.length;
|
|
517
|
+
const noConflict = tails.every(t => !taken.has(t));
|
|
518
|
+
if (unique && noConflict) {
|
|
519
|
+
basenames.forEach((r, i) => out.set(r.project_path, tails[i]));
|
|
520
|
+
resolved = true;
|
|
496
521
|
break;
|
|
497
522
|
}
|
|
498
523
|
depth += 1;
|
|
499
524
|
}
|
|
500
|
-
if (!
|
|
525
|
+
if (!resolved) {
|
|
501
526
|
// Fallback to absolute path
|
|
502
|
-
|
|
527
|
+
basenames.forEach(r => out.set(r.project_path, r.project_path));
|
|
503
528
|
}
|
|
504
529
|
}
|
|
505
530
|
return out;
|
|
@@ -582,7 +607,7 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
582
607
|
const empty = document.createElement('div');
|
|
583
608
|
empty.className = 'jp-ClaudeSessionsPanel-emptySection';
|
|
584
609
|
empty.textContent =
|
|
585
|
-
key === 'favourites' ? 'No
|
|
610
|
+
key === 'favourites' ? 'No favorites yet.' : 'Empty.';
|
|
586
611
|
list.appendChild(empty);
|
|
587
612
|
}
|
|
588
613
|
else {
|
|
@@ -623,12 +648,12 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
623
648
|
name.className = 'jp-ClaudeSessionsPanel-name';
|
|
624
649
|
name.textContent = this._lookupName(session);
|
|
625
650
|
row.appendChild(name);
|
|
626
|
-
// No star in the
|
|
651
|
+
// No star in the Favorites section - every row there is a favorite
|
|
627
652
|
// by definition; stars are an indicator only useful in Recent/All.
|
|
628
653
|
if (session.favourite && sectionKey !== 'favourites') {
|
|
629
654
|
const star = document.createElement('span');
|
|
630
655
|
star.className = 'jp-ClaudeSessionsPanel-favStar';
|
|
631
|
-
star.title = '
|
|
656
|
+
star.title = 'Favorite';
|
|
632
657
|
starFilledIcon.element({ container: star });
|
|
633
658
|
row.appendChild(star);
|
|
634
659
|
}
|
|
@@ -726,8 +751,8 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
726
751
|
label: () => {
|
|
727
752
|
var _a;
|
|
728
753
|
return ((_a = this._activeSession) === null || _a === void 0 ? void 0 : _a.favourite)
|
|
729
|
-
? 'Remove from
|
|
730
|
-
: 'Add to
|
|
754
|
+
? 'Remove from Favorites'
|
|
755
|
+
: 'Add to Favorites';
|
|
731
756
|
},
|
|
732
757
|
execute: () => {
|
|
733
758
|
if (this._activeSession) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jupyterlab_claude_code_extension",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.54",
|
|
4
4
|
"description": "Browse, resume, and manage your Claude Code CLI sessions from a JupyterLab side panel. One click reactivates the right terminal - no duplicate tabs, live remote-control indicator, and favourites for the projects you keep coming back to.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jupyter",
|
package/src/index.ts
CHANGED
|
@@ -17,7 +17,7 @@ const WIDGET_ID = 'jupyterlab-claude-code-extension';
|
|
|
17
17
|
const plugin: JupyterFrontEndPlugin<void> = {
|
|
18
18
|
id: PLUGIN_ID,
|
|
19
19
|
description:
|
|
20
|
-
'Side panel listing Claude Code sessions per project folder, with remote-control indicator,
|
|
20
|
+
'Side panel listing Claude Code sessions per project folder, with remote-control indicator, favorites, and one-click resume in a terminal.',
|
|
21
21
|
autoStart: true,
|
|
22
22
|
requires: [ILabShell],
|
|
23
23
|
optional: [ILayoutRestorer, ISettingRegistry, ITerminalTracker],
|
|
@@ -53,11 +53,20 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
53
53
|
status.root_dir || '',
|
|
54
54
|
terminalTracker
|
|
55
55
|
);
|
|
56
|
-
|
|
56
|
+
|
|
57
|
+
// Read the sidebar setting before docking so we add the widget to the
|
|
58
|
+
// user's preferred side on first paint. Default to left.
|
|
59
|
+
let currentSidebar: 'left' | 'right' = 'left';
|
|
57
60
|
|
|
58
61
|
if (settingRegistry) {
|
|
59
62
|
try {
|
|
60
63
|
const settings = await settingRegistry.load(PLUGIN_ID);
|
|
64
|
+
const initialSidebar = settings.get('sidebar').composite as string;
|
|
65
|
+
if (initialSidebar === 'left' || initialSidebar === 'right') {
|
|
66
|
+
currentSidebar = initialSidebar;
|
|
67
|
+
}
|
|
68
|
+
labShell.add(widget, currentSidebar, { rank: 600 });
|
|
69
|
+
|
|
61
70
|
const apply = (): void => {
|
|
62
71
|
const mode = settings.get('presentationMode').composite as string;
|
|
63
72
|
if (mode === 'session' || mode === 'folder' || mode === 'path') {
|
|
@@ -70,6 +79,16 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
70
79
|
const dangerous = settings.get('dangerouslySkipPermissions')
|
|
71
80
|
.composite as boolean;
|
|
72
81
|
widget.setDangerouslySkipPermissions(!!dangerous);
|
|
82
|
+
const sidebar = settings.get('sidebar').composite as string;
|
|
83
|
+
if (
|
|
84
|
+
(sidebar === 'left' || sidebar === 'right') &&
|
|
85
|
+
sidebar !== currentSidebar
|
|
86
|
+
) {
|
|
87
|
+
currentSidebar = sidebar;
|
|
88
|
+
// Lumino re-parents the widget cleanly when add() is called
|
|
89
|
+
// against a different area.
|
|
90
|
+
labShell.add(widget, sidebar, { rank: 600 });
|
|
91
|
+
}
|
|
73
92
|
};
|
|
74
93
|
apply();
|
|
75
94
|
settings.changed.connect(apply);
|
|
@@ -78,7 +97,10 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
78
97
|
'[jupyterlab_claude_code_extension] failed to load settings; using defaults',
|
|
79
98
|
err
|
|
80
99
|
);
|
|
100
|
+
labShell.add(widget, currentSidebar, { rank: 600 });
|
|
81
101
|
}
|
|
102
|
+
} else {
|
|
103
|
+
labShell.add(widget, currentSidebar, { rank: 600 });
|
|
82
104
|
}
|
|
83
105
|
|
|
84
106
|
// Register with the layout restorer so JL remembers whether the panel
|
package/src/types.ts
CHANGED
package/src/widget.ts
CHANGED
|
@@ -33,7 +33,7 @@ export type PresentationMode = 'session' | 'folder' | 'path';
|
|
|
33
33
|
const DEFAULT_PRESENTATION_MODE: PresentationMode = 'session';
|
|
34
34
|
|
|
35
35
|
const SECTION_LABELS: Record<SectionKey, string> = {
|
|
36
|
-
favourites: '
|
|
36
|
+
favourites: 'Favorites',
|
|
37
37
|
recent: 'Recent',
|
|
38
38
|
all: 'All'
|
|
39
39
|
};
|
|
@@ -566,7 +566,14 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
566
566
|
return parts[parts.length - 1] || '';
|
|
567
567
|
}
|
|
568
568
|
|
|
569
|
-
/** Walk path tails until every name in a colliding group is unique.
|
|
569
|
+
/** Walk path tails until every name in a colliding group is unique.
|
|
570
|
+
*
|
|
571
|
+
* User-set rename names (``name_source === 'rename'``) survive
|
|
572
|
+
* disambiguation untouched: a Claude ``/rename`` should never be rolled
|
|
573
|
+
* back to a path tail just because some other row happens to share its
|
|
574
|
+
* folder basename. Basename-derived rows in the same group get the path
|
|
575
|
+
* tail suffix, picked so it stays distinct from every rename label too.
|
|
576
|
+
*/
|
|
570
577
|
private _disambiguate(rows: ISession[]): Map<string, string> {
|
|
571
578
|
const out = new Map<string, string>();
|
|
572
579
|
const groups = new Map<string, ISession[]>();
|
|
@@ -579,20 +586,43 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
579
586
|
out.set(group[0].project_path, name);
|
|
580
587
|
continue;
|
|
581
588
|
}
|
|
582
|
-
|
|
589
|
+
|
|
590
|
+
const renames = group.filter(r => r.name_source === 'rename');
|
|
591
|
+
const basenames = group.filter(r => r.name_source !== 'rename');
|
|
592
|
+
|
|
593
|
+
// Rename rows win unchanged. The ``taken`` set guards basename
|
|
594
|
+
// disambiguation from colliding back into a rename's label.
|
|
595
|
+
const taken = new Set<string>();
|
|
596
|
+
for (const r of renames) {
|
|
597
|
+
out.set(r.project_path, r.name);
|
|
598
|
+
taken.add(r.name);
|
|
599
|
+
}
|
|
600
|
+
if (basenames.length === 0) {
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// Walk path tails for basename rows: tail must be unique among
|
|
605
|
+
// basenames AND not equal to any rename label already taken.
|
|
606
|
+
const segs = basenames.map(r =>
|
|
607
|
+
r.project_path.split('/').filter(Boolean)
|
|
608
|
+
);
|
|
583
609
|
const max = Math.max(...segs.map(s => s.length));
|
|
584
610
|
let depth = 1;
|
|
611
|
+
let resolved = false;
|
|
585
612
|
while (depth <= max) {
|
|
586
613
|
const tails = segs.map(s => s.slice(-depth).join('/'));
|
|
587
|
-
|
|
588
|
-
|
|
614
|
+
const unique = new Set(tails).size === tails.length;
|
|
615
|
+
const noConflict = tails.every(t => !taken.has(t));
|
|
616
|
+
if (unique && noConflict) {
|
|
617
|
+
basenames.forEach((r, i) => out.set(r.project_path, tails[i]));
|
|
618
|
+
resolved = true;
|
|
589
619
|
break;
|
|
590
620
|
}
|
|
591
621
|
depth += 1;
|
|
592
622
|
}
|
|
593
|
-
if (!
|
|
623
|
+
if (!resolved) {
|
|
594
624
|
// Fallback to absolute path
|
|
595
|
-
|
|
625
|
+
basenames.forEach(r => out.set(r.project_path, r.project_path));
|
|
596
626
|
}
|
|
597
627
|
}
|
|
598
628
|
return out;
|
|
@@ -694,7 +724,7 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
694
724
|
const empty = document.createElement('div');
|
|
695
725
|
empty.className = 'jp-ClaudeSessionsPanel-emptySection';
|
|
696
726
|
empty.textContent =
|
|
697
|
-
key === 'favourites' ? 'No
|
|
727
|
+
key === 'favourites' ? 'No favorites yet.' : 'Empty.';
|
|
698
728
|
list.appendChild(empty);
|
|
699
729
|
} else {
|
|
700
730
|
for (const item of items) {
|
|
@@ -741,12 +771,12 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
741
771
|
name.textContent = this._lookupName(session);
|
|
742
772
|
row.appendChild(name);
|
|
743
773
|
|
|
744
|
-
// No star in the
|
|
774
|
+
// No star in the Favorites section - every row there is a favorite
|
|
745
775
|
// by definition; stars are an indicator only useful in Recent/All.
|
|
746
776
|
if (session.favourite && sectionKey !== 'favourites') {
|
|
747
777
|
const star = document.createElement('span');
|
|
748
778
|
star.className = 'jp-ClaudeSessionsPanel-favStar';
|
|
749
|
-
star.title = '
|
|
779
|
+
star.title = 'Favorite';
|
|
750
780
|
starFilledIcon.element({ container: star });
|
|
751
781
|
row.appendChild(star);
|
|
752
782
|
}
|
|
@@ -853,8 +883,8 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
853
883
|
this._commands.addCommand('claude-code-sessions:toggle-favourite', {
|
|
854
884
|
label: () =>
|
|
855
885
|
this._activeSession?.favourite
|
|
856
|
-
? 'Remove from
|
|
857
|
-
: 'Add to
|
|
886
|
+
? 'Remove from Favorites'
|
|
887
|
+
: 'Add to Favorites',
|
|
858
888
|
execute: () => {
|
|
859
889
|
if (this._activeSession) {
|
|
860
890
|
void this._toggleFavourite(this._activeSession);
|
package/style/base.css
CHANGED
|
@@ -24,13 +24,16 @@
|
|
|
24
24
|
min-height: 24px;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/* The panel title and section headers mirror the file browser's headers
|
|
28
|
+
(jp-Favorites-header / jp-FileBrowser-header) so the sidebar reads
|
|
29
|
+
uniformly: 600 weight, uppercase, ui-font-size0, 1px tracking. */
|
|
27
30
|
.jp-ClaudeSessionsPanel-title {
|
|
28
31
|
flex: 1 1 auto;
|
|
29
32
|
font-weight: 600;
|
|
30
|
-
letter-spacing:
|
|
33
|
+
letter-spacing: 1px;
|
|
31
34
|
text-transform: uppercase;
|
|
32
35
|
font-size: var(--jp-ui-font-size0);
|
|
33
|
-
color: var(--jp-ui-font-
|
|
36
|
+
color: var(--jp-ui-font-color1);
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
.jp-ClaudeSessionsPanel-iconButton {
|
|
@@ -123,7 +126,7 @@
|
|
|
123
126
|
font-family: inherit;
|
|
124
127
|
font-size: var(--jp-ui-font-size0);
|
|
125
128
|
font-weight: 600;
|
|
126
|
-
letter-spacing:
|
|
129
|
+
letter-spacing: 1px;
|
|
127
130
|
text-transform: uppercase;
|
|
128
131
|
}
|
|
129
132
|
|