Keep the mobile worktree unread bell cleared after opening a worktree (#6673)

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Brennan Benson
2026-06-29 00:21:34 -07:00
committed by GitHub
co-authored by Orca
parent bb4c0e2162
commit dafe844a50
2 changed files with 148 additions and 0 deletions
+141
View File
@@ -12344,6 +12344,147 @@ describe('OrcaRuntimeService', () => {
])
})
it('clears unread metadata on mobile worktree activation without focusing desktop clients', async () => {
const metaById: Record<string, WorktreeMeta> = {
[TEST_WORKTREE_ID]: makeWorktreeMeta({ isUnread: true })
}
const setWorktreeMeta = vi.fn((worktreeId: string, meta: Partial<WorktreeMeta>) => {
metaById[worktreeId] = { ...(metaById[worktreeId] ?? makeWorktreeMeta()), ...meta }
return metaById[worktreeId]
})
const activateWorktree = vi.fn()
const worktreesChanged = vi.fn()
const runtime = new OrcaRuntimeService({
...store,
getAllWorktreeMeta: () => metaById,
getWorktreeMeta: (worktreeId: string) => metaById[worktreeId],
setWorktreeMeta
} as never)
runtime.setNotifier({
worktreesChanged,
reposChanged: vi.fn(),
activateWorktree,
createTerminal: vi.fn(),
revealTerminalSession: vi.fn(),
splitTerminal: vi.fn(),
renameTerminal: vi.fn(),
focusTerminal: vi.fn(),
closeTerminal: vi.fn(),
sleepWorktree: vi.fn(),
terminalFitOverrideChanged: vi.fn(),
terminalDriverChanged: vi.fn()
})
runtime.attachWindow(TEST_WINDOW_ID)
runtime.markGraphReady(TEST_WINDOW_ID)
await runtime.activateManagedWorktree(`id:${TEST_WORKTREE_ID}`, { notifyClients: false })
expect(setWorktreeMeta).toHaveBeenCalledWith(TEST_WORKTREE_ID, { isUnread: false })
expect(metaById[TEST_WORKTREE_ID]?.isUnread).toBe(false)
expect(worktreesChanged).toHaveBeenCalledWith(TEST_REPO_ID)
expect(activateWorktree).not.toHaveBeenCalled()
})
it('does not rewrite unread metadata when a mobile activation finds the worktree already read', async () => {
// Why: seed instanceId so worktree resolution does not emit its own
// metadata-stamp write, isolating the assertion to the unread clear.
const metaById: Record<string, WorktreeMeta> = {
[TEST_WORKTREE_ID]: makeWorktreeMeta({ isUnread: false, instanceId: 'wt-instance' })
}
const setWorktreeMeta = vi.fn((worktreeId: string, meta: Partial<WorktreeMeta>) => {
metaById[worktreeId] = { ...(metaById[worktreeId] ?? makeWorktreeMeta()), ...meta }
return metaById[worktreeId]
})
const worktreesChanged = vi.fn()
const runtime = new OrcaRuntimeService({
...store,
getAllWorktreeMeta: () => metaById,
getWorktreeMeta: (worktreeId: string) => metaById[worktreeId],
setWorktreeMeta
} as never)
runtime.setNotifier({
worktreesChanged,
reposChanged: vi.fn(),
activateWorktree: vi.fn(),
createTerminal: vi.fn(),
revealTerminalSession: vi.fn(),
splitTerminal: vi.fn(),
renameTerminal: vi.fn(),
focusTerminal: vi.fn(),
closeTerminal: vi.fn(),
sleepWorktree: vi.fn(),
terminalFitOverrideChanged: vi.fn(),
terminalDriverChanged: vi.fn()
})
runtime.attachWindow(TEST_WINDOW_ID)
runtime.markGraphReady(TEST_WINDOW_ID)
await runtime.activateManagedWorktree(`id:${TEST_WORKTREE_ID}`, { notifyClients: false })
expect(setWorktreeMeta).not.toHaveBeenCalled()
expect(worktreesChanged).not.toHaveBeenCalled()
metaById[TEST_WORKTREE_ID] = makeWorktreeMeta({ isUnread: true, instanceId: 'wt-instance' })
setWorktreeMeta.mockClear()
worktreesChanged.mockClear()
await runtime.activateManagedWorktree(`id:${TEST_WORKTREE_ID}`, { notifyClients: false })
await runtime.activateManagedWorktree(`id:${TEST_WORKTREE_ID}`, { notifyClients: false })
expect(setWorktreeMeta).toHaveBeenCalledTimes(1)
expect(setWorktreeMeta).toHaveBeenCalledWith(TEST_WORKTREE_ID, { isUnread: false })
expect(worktreesChanged).toHaveBeenCalledTimes(1)
expect(worktreesChanged).toHaveBeenCalledWith(TEST_REPO_ID)
})
it('returns unread:false from worktree.ps after a mobile activation clears the flag', async () => {
const metaById: Record<string, WorktreeMeta> = {
[TEST_WORKTREE_ID]: makeWorktreeMeta({ isUnread: true })
}
const setWorktreeMeta = vi.fn((worktreeId: string, meta: Partial<WorktreeMeta>) => {
metaById[worktreeId] = { ...(metaById[worktreeId] ?? makeWorktreeMeta()), ...meta }
return metaById[worktreeId]
})
const runtime = new OrcaRuntimeService({
...store,
getAllWorktreeMeta: () => metaById,
getWorktreeMeta: (worktreeId: string) => metaById[worktreeId],
setWorktreeMeta
} as never)
runtime.setNotifier({
worktreesChanged: vi.fn(),
reposChanged: vi.fn(),
activateWorktree: vi.fn(),
createTerminal: vi.fn(),
revealTerminalSession: vi.fn(),
splitTerminal: vi.fn(),
renameTerminal: vi.fn(),
focusTerminal: vi.fn(),
closeTerminal: vi.fn(),
sleepWorktree: vi.fn(),
terminalFitOverrideChanged: vi.fn(),
terminalDriverChanged: vi.fn()
})
runtime.attachWindow(TEST_WINDOW_ID)
runtime.markGraphReady(TEST_WINDOW_ID)
const beforeActivation = await runtime.getWorktreePs()
expect(
beforeActivation.worktrees.find((worktree) => worktree.worktreeId === TEST_WORKTREE_ID)
?.unread
).toBe(true)
await runtime.activateManagedWorktree(`id:${TEST_WORKTREE_ID}`, { notifyClients: false })
const afterActivation = await runtime.getWorktreePs()
expect(
afterActivation.worktrees.find((worktree) => worktree.worktreeId === TEST_WORKTREE_ID)?.unread
).toBe(false)
})
it('materializes pending mobile session terminals without focusing desktop clients', async () => {
const persistedPtyId = `${TEST_WORKTREE_ID}@@mobile-only-pty`
const spawn = vi.fn().mockResolvedValue({ id: persistedPtyId })
+7
View File
@@ -11807,6 +11807,13 @@ export class OrcaRuntimeService {
throw new Error('repo_not_found')
}
if (opts.notifyClients === false && this.store?.getWorktreeMeta(worktree.id)?.isUnread) {
// Why: mobile/web session activation intentionally bypasses renderer
// selection, so the runtime must acknowledge the unread state itself.
this.store.setWorktreeMeta(worktree.id, { isUnread: false })
this.notifyWorktreesChanged(repo.id)
}
if (opts.notifyClients !== false) {
// Why: inactive worktree terminal panes are renderer-owned and may not have
// live PTYs until the desktop activates the worktree and mounts them.