jupyterlab_claude_code_extension 1.0.32 → 1.0.37

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/index.js CHANGED
@@ -31,9 +31,10 @@ const plugin = {
31
31
  try {
32
32
  const settings = await settingRegistry.load(PLUGIN_ID);
33
33
  const apply = () => {
34
- const resolve = settings.get('resolveSessionNames')
35
- .composite;
36
- widget.setResolveSessionNames(resolve !== false);
34
+ const mode = settings.get('presentationMode').composite;
35
+ if (mode === 'session' || mode === 'folder' || mode === 'path') {
36
+ widget.setPresentationMode(mode);
37
+ }
37
38
  const limit = settings.get('recentLimit').composite;
38
39
  if (typeof limit === 'number') {
39
40
  widget.setRecentLimit(limit);
package/lib/widget.d.ts CHANGED
@@ -2,11 +2,12 @@ import { JupyterFrontEnd } from '@jupyterlab/application';
2
2
  import { ITerminalTracker } from '@jupyterlab/terminal';
3
3
  import { Widget } from '@lumino/widgets';
4
4
  import { Message } from '@lumino/messaging';
5
+ export type PresentationMode = 'session' | 'folder' | 'path';
5
6
  export declare class ClaudeCodeSessionsWidget extends Widget {
6
7
  constructor(app: JupyterFrontEnd, rootDir: string, terminalTracker?: ITerminalTracker | null);
7
8
  refresh(): void;
8
- /** Toggle whether explicit ``/rename`` names are honoured. */
9
- setResolveSessionNames(on: boolean): void;
9
+ /** Choose how rows are labelled: by session name, folder name, or path. */
10
+ setPresentationMode(mode: PresentationMode): void;
10
11
  /** Set how many rows the Recent section displays. */
11
12
  setRecentLimit(n: number): void;
12
13
  /** Toggle the --dangerously-skip-permissions flag on launched sessions. */
@@ -40,7 +41,8 @@ export declare class ClaudeCodeSessionsWidget extends Widget {
40
41
  private _findTerminalForCwd;
41
42
  private _showCloseExistingDialog;
42
43
  private _wireTerminalDisposal;
43
- /** Apply the resolve-names setting + path-segment disambiguation. */
44
+ /** Apply the presentation-mode setting (path-segment disambiguation is
45
+ * handled separately in ``_disambiguate``). */
44
46
  private _displayName;
45
47
  private _basename;
46
48
  /** Walk path tails until every name in a colliding group is unique. */
@@ -74,7 +76,7 @@ export declare class ClaudeCodeSessionsWidget extends Widget {
74
76
  private readonly _terminalsByPath;
75
77
  private readonly _pendingByPath;
76
78
  private readonly _rootDir;
77
- private _resolveNames;
79
+ private _presentationMode;
78
80
  private _recentLimit;
79
81
  private _dangerouslySkip;
80
82
  private _displayNames;
package/lib/widget.js CHANGED
@@ -6,6 +6,7 @@ import { claudeIcon, refreshIcon, removeIcon, shieldIcon, starFilledIcon } from
6
6
  const POLL_INTERVAL_MS = 10000;
7
7
  const DEFAULT_RECENT_LIMIT = 10;
8
8
  const EXPANDED_STORAGE_KEY = 'jupyterlab_claude_code_extension:expanded';
9
+ const DEFAULT_PRESENTATION_MODE = 'session';
9
10
  const SECTION_LABELS = {
10
11
  favourites: 'Favourites',
11
12
  recent: 'Recent',
@@ -65,7 +66,7 @@ export class ClaudeCodeSessionsWidget extends Widget {
65
66
  this._removingPaths = new Set();
66
67
  this._terminalsByPath = new Map();
67
68
  this._pendingByPath = new Map();
68
- this._resolveNames = true;
69
+ this._presentationMode = DEFAULT_PRESENTATION_MODE;
69
70
  this._recentLimit = DEFAULT_RECENT_LIMIT;
70
71
  this._dangerouslySkip = false;
71
72
  this._displayNames = new Map();
@@ -88,12 +89,12 @@ export class ClaudeCodeSessionsWidget extends Widget {
88
89
  .catch(err => this._showError(err))
89
90
  .finally(() => this._setRefreshSpinning(false));
90
91
  }
91
- /** Toggle whether explicit ``/rename`` names are honoured. */
92
- setResolveSessionNames(on) {
93
- if (this._resolveNames === on) {
92
+ /** Choose how rows are labelled: by session name, folder name, or path. */
93
+ setPresentationMode(mode) {
94
+ if (this._presentationMode === mode) {
94
95
  return;
95
96
  }
96
- this._resolveNames = on;
97
+ this._presentationMode = mode;
97
98
  this._render();
98
99
  }
99
100
  /** Set how many rows the Recent section displays. */
@@ -417,12 +418,19 @@ export class ClaudeCodeSessionsWidget extends Widget {
417
418
  });
418
419
  }
419
420
  // -------------------------------------------------------------- rendering
420
- /** Apply the resolve-names setting + path-segment disambiguation. */
421
+ /** Apply the presentation-mode setting (path-segment disambiguation is
422
+ * handled separately in ``_disambiguate``). */
421
423
  _displayName(s) {
422
- if (!this._resolveNames) {
423
- return this._basename(s.project_path) || s.encoded_path;
424
+ const folder = this._basename(s.project_path) || s.encoded_path;
425
+ switch (this._presentationMode) {
426
+ case 'folder':
427
+ return folder;
428
+ case 'path':
429
+ return this._displayPath(s.project_path) || folder;
430
+ case 'session':
431
+ default:
432
+ return s.name || folder;
424
433
  }
425
- return s.name || this._basename(s.project_path) || s.encoded_path;
426
434
  }
427
435
  _basename(p) {
428
436
  if (!p) {
@@ -627,12 +635,6 @@ export class ClaudeCodeSessionsWidget extends Widget {
627
635
  if (s.remote_control) {
628
636
  lines.push('Remote control: active');
629
637
  }
630
- if (s.first_prompt) {
631
- const trimmed = s.first_prompt.length > 100
632
- ? `${s.first_prompt.slice(0, 100)}...`
633
- : s.first_prompt;
634
- lines.push(`First prompt: ${trimmed}`);
635
- }
636
638
  if (s.session_id) {
637
639
  lines.push(`Session id: ${s.session_id}`);
638
640
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jupyterlab_claude_code_extension",
3
- "version": "1.0.32",
3
+ "version": "1.0.37",
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
@@ -9,7 +9,7 @@ import { ITerminalTracker } from '@jupyterlab/terminal';
9
9
 
10
10
  import { requestAPI } from './request';
11
11
  import { IStatusResponse } from './types';
12
- import { ClaudeCodeSessionsWidget } from './widget';
12
+ import { ClaudeCodeSessionsWidget, PresentationMode } from './widget';
13
13
 
14
14
  const PLUGIN_ID = 'jupyterlab_claude_code_extension:plugin';
15
15
  const WIDGET_ID = 'jupyterlab-claude-code-extension';
@@ -59,9 +59,10 @@ const plugin: JupyterFrontEndPlugin<void> = {
59
59
  try {
60
60
  const settings = await settingRegistry.load(PLUGIN_ID);
61
61
  const apply = (): void => {
62
- const resolve = settings.get('resolveSessionNames')
63
- .composite as boolean;
64
- widget.setResolveSessionNames(resolve !== false);
62
+ const mode = settings.get('presentationMode').composite as string;
63
+ if (mode === 'session' || mode === 'folder' || mode === 'path') {
64
+ widget.setPresentationMode(mode as PresentationMode);
65
+ }
65
66
  const limit = settings.get('recentLimit').composite as number;
66
67
  if (typeof limit === 'number') {
67
68
  widget.setRecentLimit(limit);
package/src/widget.ts CHANGED
@@ -28,6 +28,10 @@ const EXPANDED_STORAGE_KEY = 'jupyterlab_claude_code_extension:expanded';
28
28
 
29
29
  type SectionKey = 'favourites' | 'recent' | 'all';
30
30
 
31
+ export type PresentationMode = 'session' | 'folder' | 'path';
32
+
33
+ const DEFAULT_PRESENTATION_MODE: PresentationMode = 'session';
34
+
31
35
  const SECTION_LABELS: Record<SectionKey, string> = {
32
36
  favourites: 'Favourites',
33
37
  recent: 'Recent',
@@ -113,12 +117,12 @@ export class ClaudeCodeSessionsWidget extends Widget {
113
117
  .finally(() => this._setRefreshSpinning(false));
114
118
  }
115
119
 
116
- /** Toggle whether explicit ``/rename`` names are honoured. */
117
- setResolveSessionNames(on: boolean): void {
118
- if (this._resolveNames === on) {
120
+ /** Choose how rows are labelled: by session name, folder name, or path. */
121
+ setPresentationMode(mode: PresentationMode): void {
122
+ if (this._presentationMode === mode) {
119
123
  return;
120
124
  }
121
- this._resolveNames = on;
125
+ this._presentationMode = mode;
122
126
  this._render();
123
127
  }
124
128
 
@@ -501,12 +505,19 @@ export class ClaudeCodeSessionsWidget extends Widget {
501
505
 
502
506
  // -------------------------------------------------------------- rendering
503
507
 
504
- /** Apply the resolve-names setting + path-segment disambiguation. */
508
+ /** Apply the presentation-mode setting (path-segment disambiguation is
509
+ * handled separately in ``_disambiguate``). */
505
510
  private _displayName(s: ISession): string {
506
- if (!this._resolveNames) {
507
- return this._basename(s.project_path) || s.encoded_path;
511
+ const folder = this._basename(s.project_path) || s.encoded_path;
512
+ switch (this._presentationMode) {
513
+ case 'folder':
514
+ return folder;
515
+ case 'path':
516
+ return this._displayPath(s.project_path) || folder;
517
+ case 'session':
518
+ default:
519
+ return s.name || folder;
508
520
  }
509
- return s.name || this._basename(s.project_path) || s.encoded_path;
510
521
  }
511
522
 
512
523
  private _basename(p: string): string {
@@ -737,13 +748,6 @@ export class ClaudeCodeSessionsWidget extends Widget {
737
748
  if (s.remote_control) {
738
749
  lines.push('Remote control: active');
739
750
  }
740
- if (s.first_prompt) {
741
- const trimmed =
742
- s.first_prompt.length > 100
743
- ? `${s.first_prompt.slice(0, 100)}...`
744
- : s.first_prompt;
745
- lines.push(`First prompt: ${trimmed}`);
746
- }
747
751
  if (s.session_id) {
748
752
  lines.push(`Session id: ${s.session_id}`);
749
753
  }
@@ -906,7 +910,7 @@ export class ClaudeCodeSessionsWidget extends Widget {
906
910
  private readonly _terminalsByPath: Map<string, any> = new Map();
907
911
  private readonly _pendingByPath: Map<string, Promise<void>> = new Map();
908
912
  private readonly _rootDir: string;
909
- private _resolveNames: boolean = true;
913
+ private _presentationMode: PresentationMode = DEFAULT_PRESENTATION_MODE;
910
914
  private _recentLimit: number = DEFAULT_RECENT_LIMIT;
911
915
  private _dangerouslySkip: boolean = false;
912
916
  private _displayNames: Map<string, string> = new Map();