diff --git a/src/renderer/src/attention/hidden-workspace-notification-mute.test.ts b/src/renderer/src/attention/hidden-workspace-notification-mute.test.ts index bfa503af87a..11e120fd97a 100644 --- a/src/renderer/src/attention/hidden-workspace-notification-mute.test.ts +++ b/src/renderer/src/attention/hidden-workspace-notification-mute.test.ts @@ -101,6 +101,33 @@ describe('isWorkspaceNotificationMutedBySidebarFilters', () => { expect(muted(CLI_ID)).toBe(false) }) + it('still mutes a hidden parent whose only lineage child is hidden too', () => { + store.setState({ + worktreeLineageById: { + [PLAIN_ID]: { + worktreeId: PLAIN_ID, + worktreeInstanceId: 'plain', + parentWorktreeId: CLI_ID, + parentWorktreeInstanceId: 'cli', + origin: 'cli', + capture: { source: 'terminal-context', confidence: 'inferred' }, + createdAt: 1 + } + }, + worktreesByRepo: { + repo1: [ + { ...cliRow, instanceId: 'cli' }, + { + ...plainRow, + instanceId: 'plain', + cliProvenance: { kind: 'created-by-cli', createdAt: 0 } + } + ] + } + }) + expect(muted(CLI_ID)).toBe(true) + }) + it('keeps notifying for an id whose twin on another host the switches show', () => { store.setState({ worktreesByRepo: { diff --git a/src/renderer/src/attention/hidden-workspace-notification-mute.ts b/src/renderer/src/attention/hidden-workspace-notification-mute.ts index 1b8b553f448..273cfbdb386 100644 --- a/src/renderer/src/attention/hidden-workspace-notification-mute.ts +++ b/src/renderer/src/attention/hidden-workspace-notification-mute.ts @@ -4,6 +4,7 @@ import { ALL_EXECUTION_HOSTS_SCOPE } from '../../../shared/execution-host' import { parseWorkspaceKey } from '../../../shared/workspace-scope' import { sidebarHasActiveFilters } from '@/components/sidebar/sidebar-filter-actions' import { computeVisibleWorktreeIds } from '@/components/sidebar/compute-visible-worktrees' +import { isHiddenBySidebarSwitch } from '@/components/sidebar/sidebar-switch-hidden-workspace' import { buildVisibleWorktreeOptionsFromState } from '@/components/sidebar/visible-worktree-options-from-state' import { isFolderWorkspaceFromOtherDevice } from '../../../shared/workspace-creator-visibility' @@ -39,12 +40,26 @@ export function isWorkspaceNotificationMutedBySidebarFilters( isFolderWorkspaceFromOtherDevice(folder, inputs.pairedDeviceIdsByEnvironment) ) } - const known = getIndexedAllWorktrees(state.worktreesByRepo).some( + const matches = getIndexedAllWorktrees(state.worktreesByRepo).filter( (worktree) => worktree.id === workspaceId && !worktree.isArchived ) - if (!known) { + // Why these shortcuts: the full pass below only adds lineage parents, so a row the switches show + // is visible, and a hidden row no lineage record names as a parent cannot be shown above a child. + if ( + matches.length === 0 || + matches.some( + (worktree) => !isHiddenBySidebarSwitch(worktree, repoMap.get(worktree.repoId), inputs) + ) + ) { return false } + if ( + !Object.values(state.worktreeLineageById).some( + (lineage) => lineage.parentWorktreeId === workspaceId + ) + ) { + return true + } const visibleIds = computeVisibleWorktreeIds(state.worktreesByRepo, [], { ...inputs, filterRepoIds: [],