Release v1.0.5#6
Conversation
There was a problem hiding this comment.
Pull request overview
Releases v1.0.5 by adding a Settings UI to view/delete downloaded Whisper models, updating documentation visuals/badges, and bumping application version metadata.
Changes:
- Added “Downloaded Models” manager in Settings (list, total size, delete flow).
- Extended backend model listing to include on-disk file size and added a delete-model command.
- Updated README with badges/screenshots and bumped versions to 1.0.5.
Reviewed changes
Copilot reviewed 9 out of 12 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| TODO.md | Marks Linux build and downloaded-model management as completed. |
| src/styles.css | Adds styling for the Downloaded Models manager UI and delete confirmation state. |
| src/main.js | Implements rendering of downloaded models, size aggregation, and delete/confirm UI flow. |
| src/index.html | Adds the “Downloaded Models” section to the Settings page. |
| src-tauri/tauri.conf.json | Bumps app version to 1.0.5. |
| src-tauri/src/model_manager.rs | Adds delete-model and file-size lookup support in the model manager. |
| src-tauri/src/lib.rs | Exposes file size in list_models and adds the delete_model Tauri command. |
| src-tauri/Cargo.toml | Bumps crate version to 1.0.5. |
| src-tauri/Cargo.lock | Updates locked package version for oratiotext. |
| README.md | Adds release/license/platform/Tauri badges and a screenshots section. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| pub fn delete_model(&self, model_name: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
| let path = self.models_dir.join(Self::model_filename(model_name)); | ||
| if path.exists() { | ||
| std::fs::remove_file(&path)?; |
There was a problem hiding this comment.
delete_model builds a path from the unvalidated model_name via model_filename(). If a caller passes a name containing path separators (e.g. "../../..."), this can escape models_dir and delete arbitrary files. Restrict model_name to an allowlist of known model IDs (tiny/base/...) or reject names containing /, \\, or .. before joining/removing the file; consider also verifying the resolved path is under models_dir after canonicalization.
There was a problem hiding this comment.
Fixed in commit 9a941f3. The changes in src-tauri/src/model_manager.rs:
- Added a
VALID_MODEL_NAMESallowlist constant (tiny,base,small,medium,turbo,large). - Added a
validate_model_name()helper that returns an error for any name not in the allowlist — called at the top ofdelete_model. - Canonicalize
models_dironce at construction time inModelManager::new()so the stored path is always resolved. - After joining,
canonicalize()the target file path and verify itstarts_with(&self.models_dir)before removing — blocking any symlink-based or residual traversal attempts.
| // Auto-reset after 3 s | ||
| setTimeout(() => { | ||
| if (deleteBtn.dataset.confirming === "true") { | ||
| deleteBtn.dataset.confirming = "false"; | ||
| deleteBtn.textContent = "Delete"; | ||
| deleteBtn.classList.remove("btn-danger-confirm"); | ||
| } | ||
| }, 10000); |
There was a problem hiding this comment.
The comment says "Auto-reset after 3 s" but the timeout is set to 10,000 ms. Update the comment or the timeout value so they match.
There was a problem hiding this comment.
@copilot apply changes based on this feedback. Update the comment.
There was a problem hiding this comment.
Updated the comment from "Auto-reset after 3 s" to "Auto-reset after 10 s" to match the actual 10,000 ms timeout (commit 5be1202).
| .model-delete-btn:hover:not(:disabled) { | ||
| opacity: 0.65; | ||
| } | ||
|
|
There was a problem hiding this comment.
.model-delete-btn:hover:not(:disabled) sets opacity: 0.65, which is identical to the base .model-delete-btn opacity. Unless this is intentionally overriding a more specific rule elsewhere, the hover selector is redundant and can be removed (or changed to a different hover opacity if a visual cue is intended).
| .model-delete-btn:hover:not(:disabled) { | |
| opacity: 0.65; | |
| } |
Agent-Logs-Url: https://github.com/kylethedeveloper/OratioText/sessions/3874db65-2474-4f8d-b6a0-a9298358cb03 Co-authored-by: kylethedeveloper <8023096+kylethedeveloper@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…calization Agent-Logs-Url: https://github.com/kylethedeveloper/OratioText/sessions/e301a6f4-adfa-4e78-9e51-80ff57268bfe Co-authored-by: kylethedeveloper <8023096+kylethedeveloper@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 13 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /// Returns an error if `model_name` is not in the allowlist of known model IDs. | ||
| fn validate_model_name(model_name: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
| if VALID_MODEL_NAMES.contains(&model_name) { | ||
| Ok(()) | ||
| } else { | ||
| Err(format!("Unknown model '{}'", model_name).into()) | ||
| } | ||
| } |
There was a problem hiding this comment.
validate_model_name() is only used by delete_model, but other model_name entry points (e.g., download_model, get_model_path, is_model_downloaded, get_model_file_size) still accept arbitrary strings and build paths/URLs via model_filename(). Because model_filename() does not sanitize separators/.., a compromised frontend could potentially trigger path traversal or read/write outside models_dir. Consider enforcing the allowlist for all public methods that accept model_name (either by validating at the start of each method, or by making model_filename() return a Result and requiring validation before constructing paths).
| <button id="open-models-dir-btn" class="btn btn-secondary btn-sm" style="padding: 2px 6px; display: flex; align-items: center; justify-content: center;" title="Open models directory in file manager"> | ||
| <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-folder-open"> | ||
| <path stroke="none" d="M0 0h24v24H0z" fill="none" /> | ||
| <path d="M5 19l2.757 -7.351a1 1 0 0 1 .936 -.649h12.307a1 1 0 0 1 .986 1.164l-.996 5.211a2 2 0 0 1 -1.964 1.625h-14.026a2 2 0 0 1 -2 -2v-11a2 2 0 0 1 2 -2h4l2 2h5a2 2 0 0 1 2 2v1" /> | ||
| </svg> | ||
| </button> | ||
| </div> |
There was a problem hiding this comment.
The “open models directory” icon-only button relies on title, which is not a reliable accessible name for screen readers. Add an explicit accessible label (e.g., aria-label="Open models directory") and ensure it remains meaningful without the SVG.
There was a problem hiding this comment.
Added aria-label="Open models directory in file manager" to the button in commit 10ca1de. The button now has an explicit accessible name independent of the SVG icon, matching the existing title text.
Agent-Logs-Url: https://github.com/kylethedeveloper/OratioText/sessions/d48c3f10-a893-48c7-9fed-cd9d17ac2229 Co-authored-by: kylethedeveloper <8023096+kylethedeveloper@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
What's Changed