jupyterlab_claude_code_extension 1.2.2 → 1.2.5

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 CHANGED
@@ -92,6 +92,11 @@ export declare class ClaudeCodeSessionsWidget extends Widget {
92
92
  * case the file browser has no way to address it. */
93
93
  private _pathUnderRoot;
94
94
  private _formatRelativeTime;
95
+ /** Branch entry display: conversation name plus short session id in
96
+ * brackets; branches share the project path so only the name and id
97
+ * distinguish them. Skips the suffix when the label already is the
98
+ * short id (the backend's last-resort fallback). */
99
+ private _branchDisplayName;
95
100
  private _setRefreshSpinning;
96
101
  private _setActiveRow;
97
102
  private _setupContextMenu;
package/lib/widget.js CHANGED
@@ -812,6 +812,12 @@ export class ClaudeCodeSessionsWidget extends Widget {
812
812
  ? `${this._lookupName(session)} (${session.extra_sessions + 1})`
813
813
  : this._lookupName(session);
814
814
  row.appendChild(name);
815
+ if (session.file_mtime) {
816
+ const time = document.createElement('span');
817
+ time.className = 'jp-ClaudeSessionsPanel-rowTime';
818
+ time.textContent = this._formatRelativeTime(session.file_mtime);
819
+ row.appendChild(time);
820
+ }
815
821
  // No star in the Favorites section - every row there is a favorite
816
822
  // by definition; stars are an indicator only useful in Recent/All.
817
823
  if (session.favourite && sectionKey !== 'favourites') {
@@ -898,7 +904,7 @@ export class ClaudeCodeSessionsWidget extends Widget {
898
904
  }
899
905
  const diff = Date.now() - epochMs;
900
906
  if (diff < 60000) {
901
- return 'just now';
907
+ return 'now';
902
908
  }
903
909
  if (diff < 3600000) {
904
910
  return `${Math.floor(diff / 60000)}m ago`;
@@ -906,10 +912,15 @@ export class ClaudeCodeSessionsWidget extends Widget {
906
912
  if (diff < 86400000) {
907
913
  return `${Math.floor(diff / 3600000)}h ago`;
908
914
  }
909
- if (diff < 30 * 86400000) {
910
- return `${Math.floor(diff / 86400000)}d ago`;
911
- }
912
- return new Date(epochMs).toLocaleDateString();
915
+ return `${Math.floor(diff / 86400000)}d ago`;
916
+ }
917
+ /** Branch entry display: conversation name plus short session id in
918
+ * brackets; branches share the project path so only the name and id
919
+ * distinguish them. Skips the suffix when the label already is the
920
+ * short id (the backend's last-resort fallback). */
921
+ _branchDisplayName(b) {
922
+ const shortId = b.session_id.slice(0, 8);
923
+ return b.label === shortId ? b.label : `${b.label} (${shortId})`;
913
924
  }
914
925
  _setRefreshSpinning(on) {
915
926
  if (!this._refreshBtn) {
@@ -1130,7 +1141,7 @@ export class ClaudeCodeSessionsWidget extends Widget {
1130
1141
  command: 'claude-code-sessions:switch-branch',
1131
1142
  args: {
1132
1143
  session_id: b.session_id,
1133
- label: `${b.label} - ${this._formatRelativeTime(b.file_mtime)}`
1144
+ label: `${this._branchDisplayName(b)} - ${this._formatRelativeTime(b.file_mtime)}`
1134
1145
  }
1135
1146
  });
1136
1147
  }
@@ -1187,7 +1198,7 @@ export class ClaudeCodeSessionsWidget extends Widget {
1187
1198
  row.title = `Session id: ${b.session_id}`;
1188
1199
  const label = document.createElement('span');
1189
1200
  label.className = 'jp-ClaudeSessionsPanel-branchLabel';
1190
- label.textContent = b.label;
1201
+ label.textContent = this._branchDisplayName(b);
1191
1202
  row.appendChild(label);
1192
1203
  const time = document.createElement('span');
1193
1204
  time.className = 'jp-ClaudeSessionsPanel-branchTime';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jupyterlab_claude_code_extension",
3
- "version": "1.2.2",
3
+ "version": "1.2.5",
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",
@@ -157,6 +157,20 @@ describe('launch spinner dismiss contract', () => {
157
157
  );
158
158
  });
159
159
 
160
+ it('branch entries render name plus short id via _branchDisplayName', () => {
161
+ const display = (widgetSrc.match(
162
+ /private _branchDisplayName[\s\S]*?\n \}/
163
+ ) ?? [''])[0];
164
+ expect(display).toMatch(/session_id\.slice\(0, 8\)/);
165
+ expect(display).toMatch(/`\$\{b\.label\} \(\$\{shortId\}\)`/);
166
+ expect(widgetSrc).toMatch(
167
+ /label: `\$\{this\._branchDisplayName\(b\)\} - \$\{this\._formatRelativeTime\(b\.file_mtime\)\}`/
168
+ );
169
+ expect(widgetSrc).toMatch(
170
+ /label\.textContent = this\._branchDisplayName\(b\)/
171
+ );
172
+ });
173
+
160
174
  it('More... popup filters by label or session id and switches on click', () => {
161
175
  const popup = (widgetSrc.match(
162
176
  /private _showBranchPopup[\s\S]*?\n \}/
@@ -182,6 +196,23 @@ describe('launch spinner dismiss contract', () => {
182
196
  expect(switchBranch).toMatch(/Branch no longer exists/);
183
197
  });
184
198
 
199
+ it('shows last activity on session rows via the shared formatter', () => {
200
+ expect(widgetSrc).toMatch(
201
+ /jp-ClaudeSessionsPanel-rowTime[\s\S]*?_formatRelativeTime\(session\.file_mtime\)/
202
+ );
203
+ });
204
+
205
+ it('formats relative time as now / m / h / d ago, no date fallback', () => {
206
+ const fmt = (widgetSrc.match(
207
+ /private _formatRelativeTime[\s\S]*?\n \}/
208
+ ) ?? [''])[0];
209
+ expect(fmt).toMatch(/return 'now'/);
210
+ expect(fmt).toMatch(/m ago/);
211
+ expect(fmt).toMatch(/h ago/);
212
+ expect(fmt).toMatch(/d ago/);
213
+ expect(fmt).not.toMatch(/toLocaleDateString/);
214
+ });
215
+
185
216
  it('warns when the resolved current differs from the requested branch', () => {
186
217
  expect(switchBranch).toMatch(
187
218
  /result\.current !== result\.requested[\s\S]*?Notification\.warning/
package/src/widget.ts CHANGED
@@ -958,6 +958,13 @@ export class ClaudeCodeSessionsWidget extends Widget {
958
958
  : this._lookupName(session);
959
959
  row.appendChild(name);
960
960
 
961
+ if (session.file_mtime) {
962
+ const time = document.createElement('span');
963
+ time.className = 'jp-ClaudeSessionsPanel-rowTime';
964
+ time.textContent = this._formatRelativeTime(session.file_mtime);
965
+ row.appendChild(time);
966
+ }
967
+
961
968
  // No star in the Favorites section - every row there is a favorite
962
969
  // by definition; stars are an indicator only useful in Recent/All.
963
970
  if (session.favourite && sectionKey !== 'favourites') {
@@ -1050,7 +1057,7 @@ export class ClaudeCodeSessionsWidget extends Widget {
1050
1057
  }
1051
1058
  const diff = Date.now() - epochMs;
1052
1059
  if (diff < 60_000) {
1053
- return 'just now';
1060
+ return 'now';
1054
1061
  }
1055
1062
  if (diff < 3_600_000) {
1056
1063
  return `${Math.floor(diff / 60_000)}m ago`;
@@ -1058,10 +1065,16 @@ export class ClaudeCodeSessionsWidget extends Widget {
1058
1065
  if (diff < 86_400_000) {
1059
1066
  return `${Math.floor(diff / 3_600_000)}h ago`;
1060
1067
  }
1061
- if (diff < 30 * 86_400_000) {
1062
- return `${Math.floor(diff / 86_400_000)}d ago`;
1063
- }
1064
- return new Date(epochMs).toLocaleDateString();
1068
+ return `${Math.floor(diff / 86_400_000)}d ago`;
1069
+ }
1070
+
1071
+ /** Branch entry display: conversation name plus short session id in
1072
+ * brackets; branches share the project path so only the name and id
1073
+ * distinguish them. Skips the suffix when the label already is the
1074
+ * short id (the backend's last-resort fallback). */
1075
+ private _branchDisplayName(b: IBranch): string {
1076
+ const shortId = b.session_id.slice(0, 8);
1077
+ return b.label === shortId ? b.label : `${b.label} (${shortId})`;
1065
1078
  }
1066
1079
 
1067
1080
  private _setRefreshSpinning(on: boolean): void {
@@ -1316,7 +1329,7 @@ export class ClaudeCodeSessionsWidget extends Widget {
1316
1329
  command: 'claude-code-sessions:switch-branch',
1317
1330
  args: {
1318
1331
  session_id: b.session_id,
1319
- label: `${b.label} - ${this._formatRelativeTime(b.file_mtime)}`
1332
+ label: `${this._branchDisplayName(b)} - ${this._formatRelativeTime(b.file_mtime)}`
1320
1333
  }
1321
1334
  });
1322
1335
  }
@@ -1381,7 +1394,7 @@ export class ClaudeCodeSessionsWidget extends Widget {
1381
1394
 
1382
1395
  const label = document.createElement('span');
1383
1396
  label.className = 'jp-ClaudeSessionsPanel-branchLabel';
1384
- label.textContent = b.label;
1397
+ label.textContent = this._branchDisplayName(b);
1385
1398
  row.appendChild(label);
1386
1399
 
1387
1400
  const time = document.createElement('span');
package/style/base.css CHANGED
@@ -346,3 +346,11 @@
346
346
  color: var(--jp-ui-font-color2);
347
347
  font-size: var(--jp-ui-font-size0);
348
348
  }
349
+
350
+ /* Last-activity time on session rows - dim, right of the name. */
351
+ .jp-ClaudeSessionsPanel-rowTime {
352
+ flex: 0 0 auto;
353
+ margin-left: 6px;
354
+ color: var(--jp-ui-font-color2);
355
+ font-size: var(--jp-ui-font-size0);
356
+ }