fix(mobile): preserve legacy mixed-host labels

This commit is contained in:
Merge Sim
2026-09-02 13:40:00 -07:00
parent cef3f93a01
commit aeef60a758
2 changed files with 32 additions and 3 deletions
@@ -146,4 +146,19 @@ describe('getWorktreeHostContextLabels', () => {
expect(labeled.map((row) => row.hostContextLabel)).toEqual(['Local Mac', 'openclaw'])
expect(labeled.map((row) => row.hostContextHostId)).toEqual(['local', sshHostId])
})
it('keeps labels distinct when legacy rows reuse an id across hosts', () => {
const rows = [
worktree({ repoId: 'repo-local', worktreeId: 'same' }),
worktree({ repoId: 'repo-ssh', worktreeId: 'same' })
]
const labeled = applyWorktreeHostContextLabels(rows, {
...sources,
repoHostIdByRepoId: buildRepoHostIdByRepoId([
{ id: 'repo-local' },
{ id: 'repo-ssh', connectionId: 'ssh-1785104650217-eduhep' }
])
})
expect(labeled.map((row) => row.hostContextLabel)).toEqual(['Local Mac', 'openclaw'])
})
})
@@ -5,13 +5,13 @@ import {
type ExecutionHostId
} from '../../../src/shared/execution-host'
import { getMixedHostContextLabels as getSharedMixedHostContextLabels } from '../../../src/shared/worktree/host-context-labels'
import { composeWorktreeHostIdentity } from '../../../src/shared/worktree/host-qualified-identity'
export {
buildHostLabelById,
getHostContextLabel
} from '../../../src/shared/worktree/host-context-labels'
import type { RepoSummary } from './host-worktree-rpc-types'
import type { Worktree } from './workspace-list-types'
import { getWorktreeRowIdentity } from './worktree-host-row-identity'
export type HostLabelSources = {
/** Host id per repo id from repo.list; rows from hosts that predate `hostId` fall back to it. */
@@ -39,6 +39,16 @@ export function resolveWorktreeHostId(
)
}
function getResolvedWorktreeRowIdentity(
worktree: Pick<Worktree, 'worktreeId' | 'hostId' | 'repoId'>,
repoHostIdByRepoId: ReadonlyMap<string, ExecutionHostId>
): string {
return composeWorktreeHostIdentity(
resolveWorktreeHostId(worktree, repoHostIdByRepoId),
worktree.worktreeId
)
}
// Kept as a local adapter so existing mobile imports remain stable.
/**
@@ -51,7 +61,9 @@ export function getWorktreeHostContextLabels(
): Map<string, string> | undefined {
return getSharedMixedHostContextLabels(worktrees, {
getHostId: (worktree) => resolveWorktreeHostId(worktree, sources.repoHostIdByRepoId),
getIdentity: getWorktreeRowIdentity,
// Legacy hosts omit row.hostId; key by the resolved repo owner so duplicate
// worktree ids from different hosts do not overwrite each other's label.
getIdentity: (worktree) => getResolvedWorktreeRowIdentity(worktree, sources.repoHostIdByRepoId),
sources
})
}
@@ -65,7 +77,9 @@ export function applyWorktreeHostContextLabels(
return worktrees
}
return worktrees.map((worktree) => {
const hostContextLabel = labels.get(getWorktreeRowIdentity(worktree))
const hostContextLabel = labels.get(
getResolvedWorktreeRowIdentity(worktree, sources.repoHostIdByRepoId)
)
if (!hostContextLabel) {
return worktree
}