jupyterlab_claude_code_extension 1.2.12 → 1.2.17
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/lib/widget.d.ts +1 -0
- package/lib/widget.js +23 -13
- package/package.json +1 -1
- package/src/__tests__/jupyterlab_claude_code_extension.spec.ts +20 -4
- package/src/widget.ts +25 -13
- package/style/base.css +8 -2
package/lib/widget.d.ts
CHANGED
|
@@ -149,6 +149,7 @@ export declare class ClaudeCodeSessionsWidget extends Widget {
|
|
|
149
149
|
private _commands;
|
|
150
150
|
private _contextMenu;
|
|
151
151
|
private _branchSubmenu;
|
|
152
|
+
private _branchSessionMenu;
|
|
152
153
|
private _lastBranches;
|
|
153
154
|
private _lastBranchesCurrent;
|
|
154
155
|
private _newSessionMenu;
|
package/lib/widget.js
CHANGED
|
@@ -845,12 +845,14 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
845
845
|
starFilledIcon.element({ container: star });
|
|
846
846
|
row.appendChild(star);
|
|
847
847
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
848
|
+
// Always present (empty without an mtime) so the star column keeps
|
|
849
|
+
// the same anchor across every row in the panel.
|
|
850
|
+
const time = document.createElement('span');
|
|
851
|
+
time.className = 'jp-ClaudeSessionsPanel-rowTime';
|
|
852
|
+
time.textContent = session.file_mtime
|
|
853
|
+
? this._formatRelativeTime(session.file_mtime)
|
|
854
|
+
: '';
|
|
855
|
+
row.appendChild(time);
|
|
854
856
|
row.addEventListener('click', () => {
|
|
855
857
|
if (removing) {
|
|
856
858
|
return;
|
|
@@ -1073,12 +1075,11 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
1073
1075
|
}
|
|
1074
1076
|
});
|
|
1075
1077
|
this._commands.addCommand('claude-code-sessions:branch-session', {
|
|
1076
|
-
label: '
|
|
1077
|
-
icon: branchIcon,
|
|
1078
|
+
label: 'Normal',
|
|
1078
1079
|
execute: () => void this._branchSession(false)
|
|
1079
1080
|
});
|
|
1080
1081
|
this._commands.addCommand('claude-code-sessions:branch-session-dangerous', {
|
|
1081
|
-
label: '
|
|
1082
|
+
label: 'Skip Permissions',
|
|
1082
1083
|
icon: shieldIcon,
|
|
1083
1084
|
execute: () => void this._branchSession(true)
|
|
1084
1085
|
});
|
|
@@ -1116,6 +1117,17 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
1116
1117
|
this._branchSubmenu = new Menu({ commands: this._commands });
|
|
1117
1118
|
this._branchSubmenu.addClass('jp-ClaudeSessionsContextMenu');
|
|
1118
1119
|
this._branchSubmenu.title.label = 'Switch and Manage Sessions';
|
|
1120
|
+
// Submenu grouping the two branch-session launch modes.
|
|
1121
|
+
this._branchSessionMenu = new Menu({ commands: this._commands });
|
|
1122
|
+
this._branchSessionMenu.addClass('jp-ClaudeSessionsContextMenu');
|
|
1123
|
+
this._branchSessionMenu.title.label = 'Branch Session';
|
|
1124
|
+
this._branchSessionMenu.title.icon = branchIcon;
|
|
1125
|
+
this._branchSessionMenu.addItem({
|
|
1126
|
+
command: 'claude-code-sessions:branch-session'
|
|
1127
|
+
});
|
|
1128
|
+
this._branchSessionMenu.addItem({
|
|
1129
|
+
command: 'claude-code-sessions:branch-session-dangerous'
|
|
1130
|
+
});
|
|
1119
1131
|
this._contextMenu = new Menu({ commands: this._commands });
|
|
1120
1132
|
this._contextMenu.addClass('jp-ClaudeSessionsContextMenu');
|
|
1121
1133
|
this._rebuildContextMenu(false);
|
|
@@ -1154,10 +1166,8 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
1154
1166
|
});
|
|
1155
1167
|
}
|
|
1156
1168
|
this._contextMenu.addItem({
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
this._contextMenu.addItem({
|
|
1160
|
-
command: 'claude-code-sessions:branch-session-dangerous'
|
|
1169
|
+
type: 'submenu',
|
|
1170
|
+
submenu: this._branchSessionMenu
|
|
1161
1171
|
});
|
|
1162
1172
|
this._contextMenu.addItem({
|
|
1163
1173
|
command: 'claude-code-sessions:cleanup-parallel'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jupyterlab_claude_code_extension",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.17",
|
|
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",
|
|
@@ -318,12 +318,22 @@ describe('launch spinner dismiss contract', () => {
|
|
|
318
318
|
const rowTime = (css.match(
|
|
319
319
|
/\.jp-ClaudeSessionsPanel-rowTime \{[\s\S]*?\}/
|
|
320
320
|
) ?? [''])[0];
|
|
321
|
-
expect(rowTime).toMatch(/width:
|
|
321
|
+
expect(rowTime).toMatch(/width: 4em/);
|
|
322
|
+
expect(rowTime).toMatch(/white-space: nowrap/);
|
|
322
323
|
expect(rowTime).toMatch(/text-align: right/);
|
|
323
324
|
const branchTime = (css.match(
|
|
324
325
|
/\.jp-ClaudeSessionsPanel-branchTime \{[\s\S]*?\}/
|
|
325
326
|
) ?? [''])[0];
|
|
326
|
-
expect(branchTime).toMatch(/width:
|
|
327
|
+
expect(branchTime).toMatch(/width: 4em/);
|
|
328
|
+
expect(branchTime).toMatch(/white-space: nowrap/);
|
|
329
|
+
// Stars line up vertically across the entire panel: every row keeps
|
|
330
|
+
// the time slot (empty without an mtime) and every section reserves
|
|
331
|
+
// the scrollbar gutter.
|
|
332
|
+
expect(widgetSrc).toMatch(/time\.textContent = session\.file_mtime\s*\?/);
|
|
333
|
+
const list = (css.match(/\.jp-ClaudeSessionsPanel-list \{[\s\S]*?\}/) ?? [
|
|
334
|
+
''
|
|
335
|
+
])[0];
|
|
336
|
+
expect(list).toMatch(/scrollbar-gutter: stable/);
|
|
327
337
|
expect(branchTime).toMatch(/text-align: right/);
|
|
328
338
|
});
|
|
329
339
|
|
|
@@ -337,14 +347,20 @@ describe('launch spinner dismiss contract', () => {
|
|
|
337
347
|
);
|
|
338
348
|
});
|
|
339
349
|
|
|
340
|
-
it('branch session
|
|
350
|
+
it('branch session is a submenu with normal and skip-permissions entries', () => {
|
|
341
351
|
expect(widgetSrc).toMatch(/claude-code-sessions:branch-session'/);
|
|
342
352
|
expect(widgetSrc).toMatch(
|
|
343
353
|
/claude-code-sessions:branch-session-dangerous/
|
|
344
354
|
);
|
|
345
355
|
expect(widgetSrc).toMatch(
|
|
346
|
-
/Branch Session
|
|
356
|
+
/_branchSessionMenu\.title\.label = 'Branch Session'/
|
|
357
|
+
);
|
|
358
|
+
expect(widgetSrc).toMatch(
|
|
359
|
+
/label: 'Skip Permissions',\s*icon: shieldIcon/
|
|
347
360
|
);
|
|
361
|
+
expect(widgetSrc).toMatch(/submenu: this\._branchSessionMenu/);
|
|
362
|
+
// No ellipsis on the branch-session labels.
|
|
363
|
+
expect(widgetSrc).not.toMatch(/Branch Session\.\.\./);
|
|
348
364
|
});
|
|
349
365
|
|
|
350
366
|
it('branch session asks for a name and launches a known fork id', () => {
|
package/src/widget.ts
CHANGED
|
@@ -996,12 +996,14 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
996
996
|
row.appendChild(star);
|
|
997
997
|
}
|
|
998
998
|
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
999
|
+
// Always present (empty without an mtime) so the star column keeps
|
|
1000
|
+
// the same anchor across every row in the panel.
|
|
1001
|
+
const time = document.createElement('span');
|
|
1002
|
+
time.className = 'jp-ClaudeSessionsPanel-rowTime';
|
|
1003
|
+
time.textContent = session.file_mtime
|
|
1004
|
+
? this._formatRelativeTime(session.file_mtime)
|
|
1005
|
+
: '';
|
|
1006
|
+
row.appendChild(time);
|
|
1005
1007
|
|
|
1006
1008
|
row.addEventListener('click', () => {
|
|
1007
1009
|
if (removing) {
|
|
@@ -1252,13 +1254,12 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
1252
1254
|
});
|
|
1253
1255
|
|
|
1254
1256
|
this._commands.addCommand('claude-code-sessions:branch-session', {
|
|
1255
|
-
label: '
|
|
1256
|
-
icon: branchIcon,
|
|
1257
|
+
label: 'Normal',
|
|
1257
1258
|
execute: () => void this._branchSession(false)
|
|
1258
1259
|
});
|
|
1259
1260
|
|
|
1260
1261
|
this._commands.addCommand('claude-code-sessions:branch-session-dangerous', {
|
|
1261
|
-
label: '
|
|
1262
|
+
label: 'Skip Permissions',
|
|
1262
1263
|
icon: shieldIcon,
|
|
1263
1264
|
execute: () => void this._branchSession(true)
|
|
1264
1265
|
});
|
|
@@ -1302,6 +1303,18 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
1302
1303
|
this._branchSubmenu.addClass('jp-ClaudeSessionsContextMenu');
|
|
1303
1304
|
this._branchSubmenu.title.label = 'Switch and Manage Sessions';
|
|
1304
1305
|
|
|
1306
|
+
// Submenu grouping the two branch-session launch modes.
|
|
1307
|
+
this._branchSessionMenu = new Menu({ commands: this._commands });
|
|
1308
|
+
this._branchSessionMenu.addClass('jp-ClaudeSessionsContextMenu');
|
|
1309
|
+
this._branchSessionMenu.title.label = 'Branch Session';
|
|
1310
|
+
this._branchSessionMenu.title.icon = branchIcon;
|
|
1311
|
+
this._branchSessionMenu.addItem({
|
|
1312
|
+
command: 'claude-code-sessions:branch-session'
|
|
1313
|
+
});
|
|
1314
|
+
this._branchSessionMenu.addItem({
|
|
1315
|
+
command: 'claude-code-sessions:branch-session-dangerous'
|
|
1316
|
+
});
|
|
1317
|
+
|
|
1305
1318
|
this._contextMenu = new Menu({ commands: this._commands });
|
|
1306
1319
|
this._contextMenu.addClass('jp-ClaudeSessionsContextMenu');
|
|
1307
1320
|
this._rebuildContextMenu(false);
|
|
@@ -1342,10 +1355,8 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
1342
1355
|
});
|
|
1343
1356
|
}
|
|
1344
1357
|
this._contextMenu.addItem({
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
this._contextMenu.addItem({
|
|
1348
|
-
command: 'claude-code-sessions:branch-session-dangerous'
|
|
1358
|
+
type: 'submenu',
|
|
1359
|
+
submenu: this._branchSessionMenu
|
|
1349
1360
|
});
|
|
1350
1361
|
this._contextMenu.addItem({
|
|
1351
1362
|
command: 'claude-code-sessions:cleanup-parallel'
|
|
@@ -1803,6 +1814,7 @@ export class ClaudeCodeSessionsWidget extends Widget {
|
|
|
1803
1814
|
private _commands!: CommandRegistry;
|
|
1804
1815
|
private _contextMenu!: Menu;
|
|
1805
1816
|
private _branchSubmenu!: Menu;
|
|
1817
|
+
private _branchSessionMenu!: Menu;
|
|
1806
1818
|
private _lastBranches: IBranch[] = [];
|
|
1807
1819
|
private _lastBranchesCurrent = '';
|
|
1808
1820
|
private _newSessionMenu!: Menu;
|
package/style/base.css
CHANGED
|
@@ -155,6 +155,10 @@
|
|
|
155
155
|
flex: 1 1 auto;
|
|
156
156
|
overflow-y: auto;
|
|
157
157
|
min-height: 0;
|
|
158
|
+
|
|
159
|
+
/* Reserve the scrollbar gutter in every section so star/time columns
|
|
160
|
+
line up across the entire panel, scrollbar or not. */
|
|
161
|
+
scrollbar-gutter: stable;
|
|
158
162
|
}
|
|
159
163
|
|
|
160
164
|
.jp-ClaudeSessionsPanel-row {
|
|
@@ -382,7 +386,8 @@
|
|
|
382
386
|
|
|
383
387
|
.jp-ClaudeSessionsPanel-branchTime {
|
|
384
388
|
flex: none;
|
|
385
|
-
width:
|
|
389
|
+
width: 4em;
|
|
390
|
+
white-space: nowrap;
|
|
386
391
|
text-align: right;
|
|
387
392
|
color: var(--jp-ui-font-color2);
|
|
388
393
|
font-size: var(--jp-ui-font-size0);
|
|
@@ -458,7 +463,8 @@
|
|
|
458
463
|
column so values line up across rows; the star column sits before it. */
|
|
459
464
|
.jp-ClaudeSessionsPanel-rowTime {
|
|
460
465
|
flex: 0 0 auto;
|
|
461
|
-
width:
|
|
466
|
+
width: 4em;
|
|
467
|
+
white-space: nowrap;
|
|
462
468
|
text-align: right;
|
|
463
469
|
color: var(--jp-ui-font-color2);
|
|
464
470
|
font-size: var(--jp-ui-font-size0);
|