refactor(desktop): keep remote fs routing inside the fs facade
Let UI callers ask for folders/files without knowing remote-picker limits: selectDesktopPaths now normalizes remote directory selection to a single folder inside the facade. Project creation and composer context picking no longer branch on remote mode; they route through desktop-fs helpers just like git callers route through desktopGit(). Behavior unchanged except remote folder context now works through the same backend picker path.
This commit is contained in:
parent
453f134b3b
commit
8d8c7111d9
|
|
@ -5,7 +5,7 @@ import { droppedFileInlineRef } from '@/app/chat/composer/inline-refs'
|
|||
import { formatRefValue } from '@/components/assistant-ui/directive-text'
|
||||
import { useI18n } from '@/i18n'
|
||||
import { attachmentId, contextPath, pathLabel } from '@/lib/chat-runtime'
|
||||
import { isDesktopFsRemoteMode, readDesktopFileDataUrl, selectDesktopPaths } from '@/lib/desktop-fs'
|
||||
import { readDesktopFileDataUrl, selectDesktopPaths } from '@/lib/desktop-fs'
|
||||
import {
|
||||
addComposerAttachment,
|
||||
type ComposerAttachment,
|
||||
|
|
@ -266,8 +266,7 @@ export function useComposerActions({ activeSessionId, currentCwd, requestGateway
|
|||
const paths = await selectDesktopPaths({
|
||||
title: kind === 'file' ? 'Add files as context' : 'Add folders as context',
|
||||
defaultPath: currentCwd || undefined,
|
||||
directories: kind === 'folder',
|
||||
multiple: kind === 'folder' && isDesktopFsRemoteMode() ? false : undefined
|
||||
directories: kind === 'folder'
|
||||
})
|
||||
|
||||
if (!paths?.length) {
|
||||
|
|
|
|||
|
|
@ -132,15 +132,15 @@ describe('desktop filesystem facade', () => {
|
|||
expect(selectPaths).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('does not treat the remote directory picker as a general file picker', async () => {
|
||||
it('limits the remote picker to single-directory selection', async () => {
|
||||
const remoteSelect = vi.fn(async () => ['/remote/project'])
|
||||
$connection.set({ mode: 'remote' } as never)
|
||||
setDesktopFsRemotePicker({ selectPaths: remoteSelect })
|
||||
|
||||
await expect(selectDesktopPaths({ directories: false, multiple: false })).resolves.toEqual([])
|
||||
await expect(selectDesktopPaths({ directories: true, multiple: true })).resolves.toEqual([])
|
||||
await expect(selectDesktopPaths({ directories: true })).resolves.toEqual(['/remote/project'])
|
||||
|
||||
expect(remoteSelect).not.toHaveBeenCalled()
|
||||
expect(remoteSelect).toHaveBeenCalledWith({ directories: true, multiple: false })
|
||||
expect(selectPaths).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -178,9 +178,9 @@ export async function selectDesktopPaths(options?: HermesSelectPathsOptions): Pr
|
|||
return desktop.selectPaths(options)
|
||||
}
|
||||
|
||||
if (!options?.directories || options.multiple !== false) {
|
||||
if (!options?.directories) {
|
||||
return []
|
||||
}
|
||||
|
||||
return remotePicker ? remotePicker.selectPaths(options) : []
|
||||
return remotePicker ? remotePicker.selectPaths({ ...options, multiple: false }) : []
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,13 +68,12 @@ describe('pickProjectFolder', () => {
|
|||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('uses the remote-aware directory picker locally (no backend default cwd probe)', async () => {
|
||||
it('uses the remote-aware directory picker locally', async () => {
|
||||
isDesktopFsRemoteMode.mockReturnValue(false)
|
||||
selectDesktopPaths.mockResolvedValue(['/local/repo'])
|
||||
|
||||
await expect(pickProjectFolder()).resolves.toBe('/local/repo')
|
||||
expect(selectDesktopPaths).toHaveBeenCalledWith({ defaultPath: undefined, directories: true, multiple: false })
|
||||
expect(desktopDefaultCwd).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('seeds the picker with the backend cwd on a remote gateway', async () => {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { atom } from 'nanostores'
|
|||
|
||||
import { liveSessionProjectId, type SidebarProjectTree } from '@/app/chat/sidebar/projects/workspace-groups'
|
||||
import type { HermesGitBranch } from '@/global'
|
||||
import { desktopDefaultCwd, isDesktopFsRemoteMode, selectDesktopPaths, writeDesktopFileText } from '@/lib/desktop-fs'
|
||||
import { desktopDefaultCwd, selectDesktopPaths, writeDesktopFileText } from '@/lib/desktop-fs'
|
||||
import { desktopGit } from '@/lib/desktop-git'
|
||||
import { persistentAtom } from '@/lib/persisted'
|
||||
import { activeGateway, ensureActiveGatewayOpen } from '@/store/gateway'
|
||||
|
|
@ -282,7 +282,7 @@ export async function fetchProjectSessions(projectId: string): Promise<SidebarPr
|
|||
let didScanRepos = false
|
||||
|
||||
export async function scanAndRecordRepos(force = false): Promise<void> {
|
||||
const scan = window.hermesDesktop?.git?.scanRepos
|
||||
const scan = desktopGit()?.scanRepos
|
||||
|
||||
if (!scan || (didScanRepos && !force)) {
|
||||
return
|
||||
|
|
@ -738,8 +738,11 @@ export async function copyPath(path: null | string): Promise<void> {
|
|||
// mode opens the native dialog. Returns the absolute path, or null if cancelled.
|
||||
export async function pickProjectFolder(): Promise<null | string> {
|
||||
try {
|
||||
const defaultPath = isDesktopFsRemoteMode() ? (await desktopDefaultCwd())?.cwd : undefined
|
||||
const [dir] = await selectDesktopPaths({ defaultPath, directories: true, multiple: false })
|
||||
const [dir] = await selectDesktopPaths({
|
||||
defaultPath: (await desktopDefaultCwd())?.cwd,
|
||||
directories: true,
|
||||
multiple: false
|
||||
})
|
||||
|
||||
return dir || null
|
||||
} catch {
|
||||
|
|
|
|||
Loading…
Reference in New Issue