jupyterlab_claude_code_extension 1.2.2 → 1.2.4

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.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,7 @@ 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`;
913
916
  }
914
917
  _setRefreshSpinning(on) {
915
918
  if (!this._refreshBtn) {
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.4",
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",
@@ -182,6 +182,23 @@ describe('launch spinner dismiss contract', () => {
182
182
  expect(switchBranch).toMatch(/Branch no longer exists/);
183
183
  });
184
184
 
185
+ it('shows last activity on session rows via the shared formatter', () => {
186
+ expect(widgetSrc).toMatch(
187
+ /jp-ClaudeSessionsPanel-rowTime[\s\S]*?_formatRelativeTime\(session\.file_mtime\)/
188
+ );
189
+ });
190
+
191
+ it('formats relative time as now / m / h / d ago, no date fallback', () => {
192
+ const fmt = (widgetSrc.match(
193
+ /private _formatRelativeTime[\s\S]*?\n \}/
194
+ ) ?? [''])[0];
195
+ expect(fmt).toMatch(/return 'now'/);
196
+ expect(fmt).toMatch(/m ago/);
197
+ expect(fmt).toMatch(/h ago/);
198
+ expect(fmt).toMatch(/d ago/);
199
+ expect(fmt).not.toMatch(/toLocaleDateString/);
200
+ });
201
+
185
202
  it('warns when the resolved current differs from the requested branch', () => {
186
203
  expect(switchBranch).toMatch(
187
204
  /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,7 @@ 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`;
1065
1069
  }
1066
1070
 
1067
1071
  private _setRefreshSpinning(on: boolean): void {
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
+ }