# Plan 04-02: Path and Model File Validation **Wave:** 1 **Phase:** 4 **Requirements addressed:** MODL-02 --- ## Objective Add path existence validation and model file scanning integration so users receive immediate feedback when their selected model path or models directory is invalid. --- ## Read First - `tauri-app/src-tauri/src/model_files.rs` — scan_models, pick_models_dir commands - `tauri-app/src/features/runtime/api.ts` — invoke wrappers for Tauri commands - `tauri-app/src/features/runtime/runtime-settings-form.ts` — RuntimeSettingsFormState, scanned models - `tauri-app/src/features/runtime/types.ts` — RuntimeModelFile, RuntimePickDirResult - `.planning/phases/04-model-source-validation/04-RESEARCH.md` — path validation patterns --- ## Action 1. **Add Tauri command wrappers** in `api.ts`: ```typescript export interface ScannedModelsResult { dir: string; models: RuntimeModelFile[]; } export async function scanModelsDir(dirPath: string): Promise { return await invoke("scan_models", { dir: dirPath }); } export async function pickModelsDirectory(): Promise { return await invoke("pick_models_dir"); } ``` 2. **Extend runtime-utils.ts with path validation**: ```typescript import { scanModelsDir } from "./api"; export async function validateModelsDirectory( path: string | null ): Promise<{ valid: boolean; modelCount: number; error: string | null }> { if (!path) { return { valid: false, modelCount: 0, error: "No models directory selected" }; } try { const models = await scanModelsDir(path); return { valid: true, modelCount: models.length, error: null }; } catch (e) { return { valid: false, modelCount: 0, error: e instanceof Error ? e.message : String(e) }; } } export async function validateModelFile( path: string | null, scannedModels: RuntimeModelFile[] ): Promise<{ valid: boolean; exists: boolean; error: string | null }> { if (!path) { return { valid: false, exists: false, error: "No model selected" }; } const exists = scannedModels.some(m => m.path === path); return { valid: exists, exists, error: exists ? null : "Model file not found in current models directory" }; } ``` 3. **Add model scanning to runtime-settings-form.ts**: - Add `scannedModels: RuntimeModelFile[]` to RuntimeSettingsFormState - Add `scanModels(dir: string)` function that calls api.scanModelsDir - Update `resolveDraftModelSelection` to use scanned models for validation 4. **Integrate into useRuntimeManager.ts**: - Add `scannedModels` to draft state - When `models_dir` field changes, trigger rescan - When rescan completes, validate `model_path` against new scan results - Update field validation state with path-specific errors 5. **Add validation display in UI components**: - In runtime settings form, show validation message when models_dir is invalid - Show "X models found" when scan succeeds - Show "Model not in directory" when selected model is invalid after scan --- ## Acceptance Criteria - [ ] `api.ts` exports `scanModelsDir(path)` and `pickModelsDirectory()` - [ ] `runtime-utils.ts` exports async validators that check directory and file existence - [ ] Changing `models_dir` triggers rescan and updates validation state - [ ] Selected model is validated against scanned models list - [ ] Invalid paths show clear error messages in the UI - [ ] User can see "X models found" feedback after scanning --- ## Notes - Reuse existing scan_models Rust command - no backend changes needed - Keep validation async to support filesystem checks - Show appropriate loading state during scan - Handle scan errors gracefully (directory not found, permission denied)