From 4dcf201cd8e0522d1e832b40a50b0ed23e45a7ba Mon Sep 17 00:00:00 2001
From: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Date: Tue, 18 Aug 2026 17:57:17 -0700
Subject: [PATCH] Extract path flavor logic to cross-platform-path utility
- Remove local pathFlavor function in favor of shared cross-platform utilities
- Simplify buildExcludePathPrefixes to use relativePathInsideRoot and resolveRuntimePath
- Ensures consistent path handling for both local and remote roots
---
.../components/WorktreeJumpPalette.test.tsx | 25 +++++++++++++++++++
.../src/components/WorktreeJumpPalette.tsx | 22 +++++++++++++++-
2 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/src/renderer/src/components/WorktreeJumpPalette.test.tsx b/src/renderer/src/components/WorktreeJumpPalette.test.tsx
index f42cdbb8d9c..5c57e6fad38 100644
--- a/src/renderer/src/components/WorktreeJumpPalette.test.tsx
+++ b/src/renderer/src/components/WorktreeJumpPalette.test.tsx
@@ -435,4 +435,29 @@ describe('WorktreeJumpPalette', () => {
expect(input?.value).toBe('😉')
})
+
+ it('renders last active timestamp when worktree has lastActivityAt', async () => {
+ const twentyThreeDaysAgo = Date.now() - 23 * 24 * 60 * 60 * 1000
+ const activeWorktree = makeWorktree('active-wt', 'Active workspace', {
+ lastActivityAt: twentyThreeDaysAgo
+ })
+ const noActivityWorktree = makeWorktree('no-activity-wt', 'No activity workspace', {
+ lastActivityAt: 0
+ })
+
+ await renderPalette({
+ worktreesByRepo: { 'repo-1': [activeWorktree, noActivityWorktree] },
+ showSleepingWorkspaces: true
+ })
+
+ const activeRow = testContainer.querySelector('[data-command-item="worktree:active-wt"]')
+ expect(activeRow?.textContent).toContain('23d')
+ const activeSpan = activeRow?.querySelector('span[aria-label="Last active 23d ago"]')
+ expect(activeSpan).not.toBeNull()
+ expect(activeSpan?.textContent).toBe('23d')
+
+ const noActivityRow = testContainer.querySelector('[data-command-item="worktree:no-activity-wt"]')
+ expect(noActivityRow?.querySelector('span[aria-label*="Last active"]')).toBeNull()
+ })
})
+
diff --git a/src/renderer/src/components/WorktreeJumpPalette.tsx b/src/renderer/src/components/WorktreeJumpPalette.tsx
index 6304e1fa099..2d7fd8bde9c 100644
--- a/src/renderer/src/components/WorktreeJumpPalette.tsx
+++ b/src/renderer/src/components/WorktreeJumpPalette.tsx
@@ -527,7 +527,7 @@ function PaletteOpenTabPrimaryLine({
'Last active {{value0}} ago',
{ value0: sessionAge }
)}
- className="inline-flex h-5 shrink-0 items-center self-center text-[11px] font-medium leading-none tabular-nums text-muted-foreground/70"
+ className="shrink-0 text-[11px] font-medium tabular-nums text-muted-foreground/70"
>
{sessionAge}
@@ -3234,6 +3234,10 @@ function WorktreeJumpPaletteContent({
? (sshConnectionStates.get(sshConnectionId)?.status ?? 'disconnected')
: null
const isSshDisconnected = sshStatus != null && sshStatus !== 'connected'
+ const sessionAge = formatPaletteSessionAge(
+ worktree.lastActivityAt,
+ paletteNowMs
+ )
return (
+ {sessionAge ? (
+
+ {sessionAge}
+
+ ) : null}
{isCurrentWorktree && (
{translate(
@@ -3530,6 +3546,7 @@ function WorktreeJumpPaletteContent({
? resolveRepoForWorktree(simulatorWorktree)
: undefined
const simulatorRepoName = simulatorRepo?.displayName ?? result.repoName
+ const sessionAge = formatPaletteSessionAge(result.lastActiveAt ?? null, paletteNowMs)
return (
{result.isCurrentTab && (
@@ -3606,6 +3624,7 @@ function WorktreeJumpPaletteContent({
? resolveRepoForWorktree(browserWorktree)
: undefined
const browserRepoName = browserRepo?.displayName ?? result.repoName
+ const sessionAge = formatPaletteSessionAge(result.lastActiveAt ?? null, paletteNowMs)
return (
{result.isCurrentPage && (