feat: add browsable directory picker for new sessions and project switch
Users had to type an absolute server path on a phone keyboard to pick a working directory (#49 "Choose project UIX"), and #57 reports that only the default-drive project is ever discoverable. #52 already added recents + client.project.list() as flat pickers, but there was still no way to browse into subdirectories or discover paths the server hadn't already indexed as a "project" — the only fallback was manual typing. The opencode server already exposes a scoped filesystem-listing endpoint (GET /file, handled in file.ts/handlers/file.ts) that resolves relative to whatever directory the request is scoped to (header or query param) — no new server endpoint is needed. Add file.list() to the mobile SDK client and a new DirectoryBrowserSheet that lists subdirectories one level at a time (via clientForDirectory(dir) + file.list({path: "."})), supports "up" navigation, and a manual jump-to-path field. Wire it into both the "new session" modal and the existing DirectorySwitcher, so recents/manual entry remain available as a fallback alongside browsing. Residual gap: there's still no "list available drives" API, so Windows users with projects on D:, E:, etc. still need to type the drive root once (it's then remembered via recents) — a full fix for #57 would need a small server-side addition to enumerate mounted volumes.
This commit is contained in:
@@ -143,6 +143,14 @@ export interface Project {
|
||||
}
|
||||
}
|
||||
|
||||
export interface FileEntry {
|
||||
name: string
|
||||
path: string
|
||||
absolute: string
|
||||
type: "file" | "directory"
|
||||
ignored: boolean
|
||||
}
|
||||
|
||||
export interface Event {
|
||||
type: string
|
||||
properties: Record<string, unknown>
|
||||
@@ -250,6 +258,17 @@ export function createClient(config: ClientConfig) {
|
||||
current: () => request<Project>(config, "/project/current"),
|
||||
},
|
||||
|
||||
// Server-side filesystem browsing, scoped to this client's directory
|
||||
// (see ClientConfig.directory / x-opencode-directory header). Use
|
||||
// clientForDirectory(dir) to get a client rooted at a specific folder,
|
||||
// then list("." ) to enumerate its immediate children.
|
||||
file: {
|
||||
list: (params: { path?: string } = {}) => {
|
||||
const query = new URLSearchParams({ path: params.path ?? "." })
|
||||
return request<FileEntry[]>(config, `/file?${query.toString()}`)
|
||||
},
|
||||
},
|
||||
|
||||
path: {
|
||||
get: () =>
|
||||
request<{ home: string; state: string; config: string; worktree: string; directory: string }>(config, "/path"),
|
||||
|
||||
Reference in New Issue
Block a user