import { z } from 'zod'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import { CoreErrors } from '#/_base/errors/codes'; import { Error2 } from '#/_base/errors/errors'; import { FsErrors } from '#/workspace/workspaceFs/internal/errors'; export const fsBrowseQuerySchema = z.object({ path: z.string().min(1).optional(), }); export type FsBrowseQuery = z.infer; export const fsBrowseEntrySchema = z.object({ name: z.string().min(1), path: z.string().min(1), is_dir: z.literal(true), }); export type FsBrowseEntry = z.infer; export const fsBrowseResponseSchema = z.object({ path: z.string().min(1), parent: z.string().min(1).nullable(), entries: z.array(fsBrowseEntrySchema), }); export type FsBrowseResponse = z.infer; export const fsHomeResponseSchema = z.object({ home: z.string().min(1), recent_roots: z.array(z.string().min(1)), }); export type FsHomeResponse = z.infer; export class HostFolderNotAbsoluteError extends Error2 { readonly path: string; constructor(path: string) { super(CoreErrors.codes.VALIDATION_FAILED, `path must be absolute: ${path}`, { details: { path }, }); this.name = 'HostFolderNotAbsoluteError'; this.path = path; } } export class HostFolderNotFoundError extends Error2 { readonly path: string; constructor(path: string) { super(FsErrors.codes.FS_PATH_NOT_FOUND, `path not found: ${path}`, { details: { path } }); this.name = 'HostFolderNotFoundError'; this.path = path; } } export class HostFolderPermissionError extends Error2 { readonly path: string; constructor(path: string) { super(FsErrors.codes.FS_PERMISSION_DENIED, `permission denied: ${path}`, { details: { path } }); this.name = 'HostFolderPermissionError'; this.path = path; } } export interface IHostFolderBrowser { readonly _serviceBrand: undefined; browse(absPath?: string): Promise; home(): Promise; } export const IHostFolderBrowser: ServiceIdentifier = createDecorator('hostFolderBrowser'); export const RECENT_ROOTS_LIMIT = 8;