From e73cc214fd1164cfd0120406a996ad87961cc31e Mon Sep 17 00:00:00 2001 From: Matt Toohey Date: Thu, 19 Feb 2026 12:05:33 -0800 Subject: [PATCH] feat: track session types and display activity in project subtitles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Register actual session types (commit, note, review) instead of 'other' when starting sessions in BranchCard and RemoteBranchCard. Add getRunningSessionTypes() to ProjectStateStore to retrieve the types of all running sessions for a given project. Add projectSubtitle() utility that builds descriptive subtitles combining repo count with active session activity, e.g.: - "1 repo" - "2 repos · making a commit" - "1 repo · making a commit and a note" - "2 repos · pushing changes" Update ProjectsList and ProjectsSidebar to use projectSubtitle() for card and sidebar item subtitles. --- .../lib/features/branches/BranchCard.svelte | 4 +- .../features/branches/RemoteBranchCard.svelte | 6 +- .../lib/features/projects/ProjectsList.svelte | 11 ++- .../features/projects/ProjectsSidebar.svelte | 12 ++- staged/src/lib/shared/utils.ts | 93 +++++++++++++++++++ staged/src/lib/stores/projectState.svelte.ts | 22 ++++- 6 files changed, 136 insertions(+), 12 deletions(-) diff --git a/staged/src/lib/features/branches/BranchCard.svelte b/staged/src/lib/features/branches/BranchCard.svelte index 166d3b96..661f1900 100644 --- a/staged/src/lib/features/branches/BranchCard.svelte +++ b/staged/src/lib/features/branches/BranchCard.svelte @@ -863,8 +863,8 @@ notifyError('Session Error', 'Failed to start session: no session ID returned'); return; } - // Register session in the unified registry - sessionRegistry.register(result.sessionId, branch.projectId, 'other', branch.id); + // Register session in the unified registry with the actual session type + sessionRegistry.register(result.sessionId, branch.projectId, newSessionMode, branch.id); projectStateStore.addRunningSession(branch.projectId, result.sessionId); showNewSession = false; draftPrompt = ''; diff --git a/staged/src/lib/features/branches/RemoteBranchCard.svelte b/staged/src/lib/features/branches/RemoteBranchCard.svelte index 0c6e2bed..1ddcdd52 100644 --- a/staged/src/lib/features/branches/RemoteBranchCard.svelte +++ b/staged/src/lib/features/branches/RemoteBranchCard.svelte @@ -364,9 +364,9 @@ notifyError('Session Error', 'Failed to start session: no session ID returned'); return; } - // Register session in the unified registry so global completion handling can - // clear running/unread indicators for remote projects. - sessionRegistry.register(result.sessionId, branch.projectId, 'other', branch.id); + // Register session in the unified registry with the actual session type so global + // completion handling can clear running/unread indicators for remote projects. + sessionRegistry.register(result.sessionId, branch.projectId, newSessionMode, branch.id); // Track the running session in the project state store projectStateStore.addRunningSession(branch.projectId, result.sessionId); const pendingType = diff --git a/staged/src/lib/features/projects/ProjectsList.svelte b/staged/src/lib/features/projects/ProjectsList.svelte index f4f66e2a..b9c29fc3 100644 --- a/staged/src/lib/features/projects/ProjectsList.svelte +++ b/staged/src/lib/features/projects/ProjectsList.svelte @@ -10,7 +10,12 @@ import { GitPullRequest, GitPullRequestClosed, GitPullRequestDraft, Plus } from 'lucide-svelte'; import type { Project, ProjectRepo, Branch } from '../../types'; import * as commands from '../../commands'; - import { projectDisplayName, aggregateProjectPrStatus } from '../../shared/utils'; + import { + projectDisplayName, + aggregateProjectPrStatus, + projectSubtitle, + } from '../../shared/utils'; + import { projectStateStore } from '../../stores/projectState.svelte'; import { selectProject } from '../../navigation.svelte'; import NewProjectModal from './NewProjectModal.svelte'; import ProjectsSidebar from './ProjectsSidebar.svelte'; @@ -281,6 +286,8 @@ {@const status = getProjectStatus(project.id, deletingProjectNames)} {@const prStatus = getProjectPrStatus(project.id)} {@const repos = reposByProject.get(project.id) ?? []} + {@const repoCount = repoCountsByProject.get(project.id) ?? (project.githubRepo ? 1 : 0)} + {@const sessionTypes = projectStateStore.getRunningSessionTypes(project.id)}
- {project.location === 'remote' ? 'Remote workspace' : 'Local worktrees'} + {projectSubtitle(repoCount, sessionTypes)}
{/each} diff --git a/staged/src/lib/features/projects/ProjectsSidebar.svelte b/staged/src/lib/features/projects/ProjectsSidebar.svelte index d63034c4..8c34dd4e 100644 --- a/staged/src/lib/features/projects/ProjectsSidebar.svelte +++ b/staged/src/lib/features/projects/ProjectsSidebar.svelte @@ -13,7 +13,12 @@ } from 'lucide-svelte'; import type { Project, Branch } from '../../types'; import { goHome, navigation, selectProject } from '../../navigation.svelte'; - import { projectDisplayName, aggregateProjectPrStatus } from '../../shared/utils'; + import { + projectDisplayName, + aggregateProjectPrStatus, + projectSubtitle, + } from '../../shared/utils'; + import { projectStateStore } from '../../stores/projectState.svelte'; import Spinner from '../../shared/Spinner.svelte'; import StagedIcon from '../../shared/StagedIcon.svelte'; import { getProjectStatus } from './projectStatus'; @@ -193,6 +198,7 @@ {@const status = getProjectStatus(project.id, deletingProjectNames)} {@const repoCount = repoCountForProject(project)} {@const prStatus = getProjectPrStatus(project.id)} + {@const sessionTypes = projectStateStore.getRunningSessionTypes(project.id)}