fix(settings): open the deep-linked project setup, not the host's first (#12176)

A repo-only Settings deep link (sidebar "Project Settings") recorded just the
entry and host, so when one entry holds two setups on the same host (e.g. a
Windows and a WSL clone of one remote, or a provisioned plus a user clone) the
pane resolved the host's first setup and showed the other clone's settings.
Carry the setup id like the explicit-host path already does.

Addresses #11689.

Co-authored-by: Neil <neil@stably.ai>
This commit is contained in:
Anddy Sahir Agudelo
2026-10-26 05:03:56 -07:00
committed by GitHub
co-authored by Neil
parent 015996d1b1
commit fd25eb0872
3 changed files with 33 additions and 9 deletions
@@ -269,7 +269,8 @@ describe('deep-link resolution', () => {
const map = buildRepoIdToHostSelection(projects)
expect(map.get('remote-9')).toEqual({
selectionKey: projects[0].selectionKey,
hostId: 'runtime:home-mac'
hostId: 'runtime:home-mac',
setupId: 'remote-9'
})
})
@@ -325,6 +326,20 @@ describe('deep-link resolution', () => {
)
})
it('opens the linked setup when one entry holds two setups on that host (#11689)', () => {
const wslPath = '\\\\wsl.localhost\\Ubuntu\\home\\me\\app'
const sameHostRepos = [
makeRepo({ id: 'windows-clone', gitRemoteIdentity: gitRemote, path: 'C:\\repos\\app' }),
makeRepo({ id: 'wsl-clone', gitRemoteIdentity: gitRemote, path: wslPath })
]
const [entry] = buildSettingsProjectList(sameHostRepos)
const selection = buildRepoIdToHostSelection([entry]).get('wsl-clone')
expect(
getSettingsProjectHostRepo(entry, sameHostRepos, selection?.hostId, selection?.setupId)?.path
).toBe(wslPath)
})
it('defaults to the local host repo row when no host is selected', () => {
expect(getSettingsProjectHostRepo(projects[0], repos, undefined)?.id).toBe('local-1')
})
@@ -189,15 +189,26 @@ export function buildRepoIdToRepresentative(
return map
}
/** Resolve deep links to their owning host as well as their pane. */
/** Which entry, host and setup row a Settings deep link opens. */
export type SettingsProjectHostSelection = {
selectionKey: string
hostId: ExecutionHostId
setupId: string
}
/** Resolve deep links to their exact setup: one host can own several (e.g. Windows + WSL clones). */
export function buildRepoIdToHostSelection(
projects: readonly SettingsProject[]
): Map<string, { selectionKey: string; hostId: ExecutionHostId }> {
const map = new Map<string, { selectionKey: string; hostId: ExecutionHostId }>()
): Map<string, SettingsProjectHostSelection> {
const map = new Map<string, SettingsProjectHostSelection>()
for (const settingsProject of projects) {
for (const setup of settingsProject.setups) {
if (setup.repoId.trim().length > 0 && !map.has(setup.repoId)) {
map.set(setup.repoId, { selectionKey: settingsProject.selectionKey, hostId: setup.hostId })
map.set(setup.repoId, {
selectionKey: settingsProject.selectionKey,
hostId: setup.hostId,
setupId: setup.id
})
}
}
}
@@ -208,7 +219,7 @@ export function getSettingsTargetHostSelection(
projects: readonly SettingsProject[],
repoId: string,
hostId: ExecutionHostId
): { selectionKey: string; hostId: ExecutionHostId; setupId: string } | null {
): SettingsProjectHostSelection | null {
for (const settingsProject of projects) {
const setup = settingsProject.setups.find(
(candidate) => candidate.repoId === repoId && candidate.hostId === hostId
@@ -184,9 +184,7 @@ export function useSettingsPageEffects(
setSettingsProjectHostSelection(
hostSelection.selectionKey,
hostSelection.hostId,
'setupId' in hostSelection && typeof hostSelection.setupId === 'string'
? hostSelection.setupId
: undefined
hostSelection.setupId
)
}
}