Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(desktop): migrate from Electron to Tauri v2#119

Merged
cwchanap merged 77 commits into
mainfrom
codex/dtx-desktop-tauri-migration
Jun 20, 2026
Merged

feat(desktop): migrate from Electron to Tauri v2#119
cwchanap merged 77 commits into
mainfrom
codex/dtx-desktop-tauri-migration

Conversation

@cwchanap

@cwchanap cwchanap commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • Remove Electron and all related tooling (electron-builder, electron-vite, main/preload processes, GraphQL client)
  • Add Tauri v2 Rust backend with typed commands covering:
    • Filesystem (list, read, write, copy, delete, watch)
    • Songs (local metadata, search, CRUD, setdefs)
    • Auth (deep links, session management, Supabase integration)
    • Cloud API (upload, download, asset sync)
    • Auto-updater via Tauri plugin
    • Electron local data migration on first run
  • Introduce typed desktopHost adapter in renderer to abstract Tauri IPC
  • Port all renderer services and components to use Tauri APIs
  • Update Vitest tests and add new desktopHost test suite
  • Add Tauri scaffold config, Cargo workspace, macOS capabilities, and generated schemas

Test plan

  • Renderer unit tests pass (bun run --filter=dtx-desktop test)
  • Desktop host adapter tests pass
  • Auth service tests updated for Tauri flow
  • Workspace, simfile, and asset file service tests aligned
  • Settings store tests updated

Breaking Changes

  • Desktop build output now uses Tauri instead of Electron
  • Removed electron.vite.config.ts, electron-builder.yml, and all src/main/ / src/preload/ code

Generated with Devin

Summary by CodeRabbit

  • New Features
    • Migrated the desktop app from Electron to Tauri with a new desktop host for filesystem, API, songs, uploads, skin assets, and update checks.
    • Improved magic-link/deep-link authentication with stricter callback parsing and safer session validation.
    • Web login redirect now preserves the configured desktop callback scheme.
  • Bug Fixes
    • Hardened workspace-contained file browsing/reads, preview uploading, and clearer error shaping for network/API failures.
  • Tests
    • Added/expanded unit and integration coverage for the new desktop host and Tauri-backed behaviors.
  • Documentation
    • Updated desktop README and added a migration design specification.

cwchanap added 30 commits June 12, 2026 18:02
Add 40 new tests targeting previously uncovered branches across four
modules, closing 67 additional patch-coverage lines.

api.rs (+18 tests, -33 missing lines):
- upload_name_from_file_name: prefix stripping, deep subfolder, fallback
- upload_file_to_api: missing song folder, missing file, path traversal
- read_preview_within_workspace: empty root, missing root, outside
  workspace, absent preview, present preview
- run_graphql_value_with_client: server timeout
- upload_form_to_api: server timeout
- load_asset_files_impl: NOT_FOUND graphql code, simfile_id=0, general
  graphql error
- create_simfile_record_impl: preview upload warnings surface in response

songs.rs (+9 tests, -17 missing lines):
- parse_dtx_folder: empty folder (DtxParseResult::empty), unreadable
  .dtx (parse_failures count), .dtx without metadata
- resolve_export_directory: explicit path, empty string, tilde expansion
- data_url_for_asset: png, jpg, jpeg, unknown extension mime types
- valid_export_files: directories and invalid extensions skipped

filesystem.rs (+6 tests, -11 missing lines):
- read_file_path: file exceeding TEXT_FILE_SIZE_LIMIT, file exceeding
  AUDIO_FILE_SIZE_LIMIT
- decode_text_content: all-null fallback to SHIFT_JIS/UTF-8, BOM stripping
- join_path_parts: base with parts, empty parts
- file_path_to_string: FilePath::Path conversion

auth.rs (+3 tests, -6 missing lines):
- session_value_from_data: includes user when present, omits when None
- auth_client: builds client with timeout

Verification:
- cargo fmt --check: clean
- cargo clippy --all-targets --locked -- -D warnings: clean
- cargo test --locked --lib: 321 passed (was 281), 0 flakes over 3 runs
- Patch coverage: 77.62% -> 80.40% (missing: 539 -> 472, -67 lines)
- Cumulative since original Codecov baseline: 630 -> 472 missing (-25.1%)
cwchanap and others added 2 commits June 18, 2026 15:40
Replace PathBuf::from(".") with *"." in test assertion to avoid
creating an owned instance just for comparison, which triggers
clippy::cmp_owned warning with -D warnings flag.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Replace outdated Electron references with Tauri 2 / Rust backend
- Add dtx-api package to project overview and commands
- Expand development commands (cargo test, codegen, API deploy)
- Update deployment and infrastructure sections
- Add GraphQL API and Desktop backend architecture sections

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
cwchanap and others added 8 commits June 18, 2026 17:48
… version in CI

- Add canonicalization check in read_preview_within_workspace to reject symlinks
  pointing outside the workspace, preventing potential data exfiltration
- Add Set Release Version step in desktop-build-deploy.yml to bake SemVer into
  tauri.conf.json and Cargo.toml before building, ensuring updater comparisons
  work correctly
- Add Unix-only test for symlink rejection security check

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ad of env vars

- Add get_default_downloads_dir Tauri command using dirs crate
- Replace getEnvironment with getDefaultDownloadsDir in desktopHost
- Update settingsStore to use async Rust command for default path
- Harden CSP in tauri.conf.json and index.html
- Remove unused Versions component
- Make console logs DEV-only in main.ts
- Update tests for new Downloads directory API

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… artifact handling

- Add best-effort Supabase session revocation in logout_session() by POSTing to
  /auth/v1/logout with the access token before clearing local state. Falls back
  to local-only logout if config or HTTP client is unavailable.
- Fix desktop-build-deploy.yml to handle Tauri v2 artifact format: the setup
  .exe is both installer and updater bundle (no separate .nsis.zip wrapper),
  with .exe.sig as the minisign signature sidecar.
- Add comprehensive Rust tests for revoke_session_with_client covering happy
  path, unreachable server, and no session scenarios.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Implement proactive access token refresh to keep desktop sessions working past the Supabase token lifetime (default 1 hour). The auth module now decodes JWT expiry and refreshes tokens when they're within 60 seconds of expiry, preventing expired-JWT errors during long desktop sessions.

Changes:
- Add ensure_valid_access_token function that checks token expiry and refreshes proactively
- Extract perform_refresh as a pure HTTP refresh function for better testability
- Add jwt_exp_seconds to decode JWT expiry without signature verification (API still validates server-side)
- Update access_token_from_auth_state to delegate to proactive refresh
- Add comprehensive unit tests for refresh logic and JWT expiry decoding
- Fix getDefaultDownloadsDir to properly invoke the Rust command instead of hard-coding null

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…cation logging

- Add refresh_lock to AuthState to serialize concurrent token refreshes, preventing duplicate refresh token submissions that could cause Supabase to reject the second call or revoke the token family
- Extract session_access_token and session_refresh_token helpers to reduce boilerplate and centralize token extraction logic
- Improve logout revocation error logging to surface failed server-side revocations instead of silently treating them as success
- Update CLAUDE.md to document configurable auth callback port via DTX_DESKTOP_AUTH_CALLBACK_PORT
- Add filesystem security improvements and expand test coverage for auth and filesystem error paths

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…erations

Add mandatory workspace_root parameter to file system commands (path_exists, load_tree_structure, parse_dtx_files, upload_file, export_song_to_zip) to prevent path traversal and symlink exfiltration attacks. All file access now routes through the canonicalize_within_workspace primitive, ensuring compromised renderers cannot access files outside the user-selected workspace.

- Add workspace_root parameter to IPC commands and frontend service calls
- Reject empty/missing workspace roots with actionable error messages
- Add symlink type reporting in directory listings
- Update GitHub workflow environment name from "Electron" to "Desktop"
- Expand test coverage for containment enforcement and error paths

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The Rust backend proactively refreshes Supabase tokens during long-running
sessions and on startup validation, but the rotated refresh token was only
stored in the in-memory AuthState. The renderer kept the now-revoked refresh
token in localStorage, so the next launch logged the user out.

Emit a `session-refreshed` event from the refresh paths (startup validation
and proactive near-expiry refresh) carrying the new Supabase session value,
and have the renderer persist it via `storeSessionData`. `AppHandle` is
threaded as `Option` through the refresh functions so unit tests can exercise
the logic without a real app handle.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
PR builds now run unsigned to prevent the updater signing key from being
exposed to PR-controlled build scripts. A leaked signing key would allow an
attacker to ship trusted updater bundles to every installed desktop client.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Set createUpdaterArtifacts=false in committed tauri.conf.json so PR builds
(which run without the signing key) and local builds without
TAURI_SIGNING_PRIVATE_KEY don't hard-fail. The CI workflow re-enables it
only for signed release builds via jq, where the signing key is present
and the deploy job consumes the .sig sidecars.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@cwchanap

Copy link
Copy Markdown
Owner Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/dtx-desktop/src-tauri/src/songs.rs (1)

118-125: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the canonical path after the workspace containment check.

Line 118 proves the canonical target is inside the workspace, but Line 125 reopens the original song_path. A symlink swapped after validation can make the export read and zip files outside the workspace.

Use the validated canonical path for export
-    crate::filesystem::canonicalize_within_workspace(&song_path, Some(&workspace_root)).await?;
+    let canonical_song_path =
+        crate::filesystem::canonicalize_within_workspace(&song_path, Some(&workspace_root))
+            .await?;
     let export_directory = resolve_export_directory(export_directory.as_deref());
     let song_title = song_title
         .as_deref()
         .filter(|title| !title.trim().is_empty())
         .unwrap_or("song");
 
-    export_song_folder_to_zip(Path::new(&song_path), song_title, &export_directory).await
+    export_song_folder_to_zip(&canonical_song_path, song_title, &export_directory).await
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/dtx-desktop/src-tauri/src/songs.rs` around lines 118 - 125, The code
validates that song_path is within the workspace bounds on line 118 using
canonicalize_within_workspace, but then passes the original song_path to
export_song_folder_to_zip on line 125. This creates a security vulnerability
where a symlink could be changed between validation and use. Store the result of
the canonicalize_within_workspace call as the validated canonical path, then
pass this canonical path to export_song_folder_to_zip instead of the original
song_path to ensure the validated path is actually used for the export
operation.
🧹 Nitpick comments (4)
packages/dtx-desktop/src-tauri/src/tests/api_tests.rs (1)

1464-1480: ⚡ Quick win

Avoid waiting for the production timeout in this unit test.

This mock delays for API_REQUEST_TIMEOUT_MS / 1000 + 5 and calls upload_form_to_api, so CI waits for the full production timeout before the assertion can pass. Mirror the GraphQL timeout test by injecting a short-timeout client into a testable upload helper.

Shape of the test-side change
     let form = Form::new().text("data", "test");
-    let result = upload_form_to_api(&server.uri(), "tok", form).await;
+    let client = reqwest::Client::builder()
+        .timeout(std::time::Duration::from_millis(100))
+        .build()
+        .unwrap();
+    let result = upload_form_to_api_with_client(client, &server.uri(), "tok", form).await;
 
     assert_eq!(result["success"], false);
     assert!(result["error"].as_str().unwrap().contains("timed out"));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/dtx-desktop/src-tauri/src/tests/api_tests.rs` around lines 1464 -
1480, The test `upload_form_to_api_times_out_on_slow_server` is slow because it
waits for the full production timeout value `API_REQUEST_TIMEOUT_MS`. Refactor
the `upload_form_to_api` function to accept an injectable HTTP client parameter
with a configurable timeout, then create a test helper that takes a custom
timeout duration. In the test, inject a client with a short timeout duration
(e.g., a few milliseconds) instead of waiting for the production timeout, and
call the helper with this short-timeout client to make the test run quickly
while still verifying timeout behavior.
packages/dtx-desktop/src/renderer/src/components/Settings.test.ts (1)

12-14: ⚡ Quick win

Use $lib/ alias when mocking internal services.

Switch this mock target to alias-based pathing to match repository import conventions.

Proposed change
-vi.mock('../services/desktopHost', () => ({
+vi.mock('$lib/services/desktopHost', () => ({
 	desktopHost: mockDesktopHost
 }));

As per coding guidelines, "Use $lib/ aliases for imports within packages instead of relative paths".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/dtx-desktop/src/renderer/src/components/Settings.test.ts` around
lines 12 - 14, The vi.mock call for desktopHost is using a relative path
'../services/desktopHost' instead of the repository's $lib/ alias convention.
Replace the relative path string in the vi.mock function call with the
appropriate $lib/ alias path to match the project's import conventions and
ensure consistency across the codebase.

Source: Coding guidelines

packages/dtx-desktop/src/renderer/src/components/NewSong.svelte (1)

6-6: ⚡ Quick win

Use $lib/ alias for the new internal service import.

Please switch this import to the package alias form for consistency and safer path refactors.

Proposed change
-import { desktopHost } from '../services/desktopHost';
+import { desktopHost } from '$lib/services/desktopHost';

As per coding guidelines, "Use $lib/ aliases for imports within packages instead of relative paths".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/dtx-desktop/src/renderer/src/components/NewSong.svelte` at line 6,
In the NewSong.svelte file, the import statement for desktopHost currently uses
a relative path that should be replaced with the package alias for consistency
and maintainability. Change the desktopHost import statement from using the
relative path `../services/desktopHost` to instead use the `$lib/` alias
pattern, which will resolve to the same location but provides a more stable path
reference that is safer for future refactors.

Source: Coding guidelines

packages/dtx-desktop/src/renderer/src/components/Settings.svelte (1)

5-5: ⚡ Quick win

Use $lib/ alias for internal import.

Please move this new import to $lib/... to match package import conventions.

Proposed change
-import { desktopHost } from '../services/desktopHost';
+import { desktopHost } from '$lib/services/desktopHost';

As per coding guidelines, "Use $lib/ aliases for imports within packages instead of relative paths".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/dtx-desktop/src/renderer/src/components/Settings.svelte` at line 5,
The import statement for desktopHost currently uses a relative path
../services/desktopHost instead of following the package convention of using the
$lib/ alias. Replace the relative path import in Settings.svelte with the $lib/
aliased path, changing from '../services/desktopHost' to
'$lib/services/desktopHost' to match the codebase conventions for internal
package imports.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/desktop-build-deploy.yml:
- Around line 82-86: The version extraction logic only handles tags with the v
prefix (refs/tags/v*) but fails to extract the version from bare SemVer tags
like 1.2.3. To fix this, add an additional condition in all three
release-version blocks (lines 82-86, 197-201, and 285-289) that also matches
tags in the refs/tags/ format directly and extracts the version by stripping the
refs/tags/ prefix. The VERSION variable assignment should handle both cases:
first check for refs/tags/v* and strip the prefix accordingly, then fall back to
checking for refs/tags/ with a simple suffix removal, ensuring bare SemVer tags
are properly recognized and VERSION is populated correctly for all tag formats.

In `@packages/dtx-desktop/src-tauri/src/filesystem.rs`:
- Around line 378-389: The while let Ok(Some(entry)) pattern at the start of the
loop in inspect_tree_folder silently exits iteration when next_entry()
encounters an error without logging it, causing incomplete directory processing.
Replace this pattern with explicit error handling that logs the error from
next_entry().await before deciding to break the loop, similar to how file_type
errors are logged in the match statement, to ensure visibility into why
directory iteration failed.
- Around line 59-67: The order of checks in the match statement for
canonicalize_within_workspace is leaking information about the existence of
paths outside the workspace boundary. Before attempting to canonicalize, first
validate that the full_path_string is actually contained within the
workspace_root, and return a consistent "outside the workspace" error for all
cases where the path is outside the boundary regardless of whether the path
exists. Only proceed with canonicalization for paths that pass the containment
check first, ensuring that NotFound errors only occur for paths that are
legitimately within the workspace.

In `@packages/dtx-desktop/src-tauri/src/lib.rs`:
- Around line 42-45: The deep-link scheme filtering in the `map` and `filter`
chain is case-sensitive and only matches lowercase "dtx://" schemes, causing
valid uppercase or mixed-case variants like "DTX://" to be filtered out and
ignored. Convert each argument to lowercase before checking if it starts with
the deep-link scheme by using `to_lowercase()` on the arg within the filter
closure, so the check becomes case-insensitive while preserving the original
case of the captured URL.

---

Outside diff comments:
In `@packages/dtx-desktop/src-tauri/src/songs.rs`:
- Around line 118-125: The code validates that song_path is within the workspace
bounds on line 118 using canonicalize_within_workspace, but then passes the
original song_path to export_song_folder_to_zip on line 125. This creates a
security vulnerability where a symlink could be changed between validation and
use. Store the result of the canonicalize_within_workspace call as the validated
canonical path, then pass this canonical path to export_song_folder_to_zip
instead of the original song_path to ensure the validated path is actually used
for the export operation.

---

Nitpick comments:
In `@packages/dtx-desktop/src-tauri/src/tests/api_tests.rs`:
- Around line 1464-1480: The test `upload_form_to_api_times_out_on_slow_server`
is slow because it waits for the full production timeout value
`API_REQUEST_TIMEOUT_MS`. Refactor the `upload_form_to_api` function to accept
an injectable HTTP client parameter with a configurable timeout, then create a
test helper that takes a custom timeout duration. In the test, inject a client
with a short timeout duration (e.g., a few milliseconds) instead of waiting for
the production timeout, and call the helper with this short-timeout client to
make the test run quickly while still verifying timeout behavior.

In `@packages/dtx-desktop/src/renderer/src/components/NewSong.svelte`:
- Line 6: In the NewSong.svelte file, the import statement for desktopHost
currently uses a relative path that should be replaced with the package alias
for consistency and maintainability. Change the desktopHost import statement
from using the relative path `../services/desktopHost` to instead use the
`$lib/` alias pattern, which will resolve to the same location but provides a
more stable path reference that is safer for future refactors.

In `@packages/dtx-desktop/src/renderer/src/components/Settings.svelte`:
- Line 5: The import statement for desktopHost currently uses a relative path
../services/desktopHost instead of following the package convention of using the
$lib/ alias. Replace the relative path import in Settings.svelte with the $lib/
aliased path, changing from '../services/desktopHost' to
'$lib/services/desktopHost' to match the codebase conventions for internal
package imports.

In `@packages/dtx-desktop/src/renderer/src/components/Settings.test.ts`:
- Around line 12-14: The vi.mock call for desktopHost is using a relative path
'../services/desktopHost' instead of the repository's $lib/ alias convention.
Replace the relative path string in the vi.mock function call with the
appropriate $lib/ alias path to match the project's import conventions and
ensure consistency across the codebase.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 10073051-9970-4d69-9f3d-287ae2e08b27

📥 Commits

Reviewing files that changed from the base of the PR and between 999b29e and bac56cf.

⛔ Files ignored due to path filters (1)
  • packages/dtx-desktop/src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (45)
  • .github/workflows/desktop-build-deploy.yml
  • .github/workflows/tauri-rust-ci.yml
  • .husky/pre-commit
  • CLAUDE.md
  • packages/dtx-desktop/.gitignore
  • packages/dtx-desktop/src-tauri/Cargo.toml
  • packages/dtx-desktop/src-tauri/src/api.rs
  • packages/dtx-desktop/src-tauri/src/auth.rs
  • packages/dtx-desktop/src-tauri/src/error.rs
  • packages/dtx-desktop/src-tauri/src/filesystem.rs
  • packages/dtx-desktop/src-tauri/src/lib.rs
  • packages/dtx-desktop/src-tauri/src/macros.rs
  • packages/dtx-desktop/src-tauri/src/models.rs
  • packages/dtx-desktop/src-tauri/src/songs.rs
  • packages/dtx-desktop/src-tauri/src/tests/api_tests.rs
  • packages/dtx-desktop/src-tauri/src/tests/auth_tests.rs
  • packages/dtx-desktop/src-tauri/src/tests/error_tests.rs
  • packages/dtx-desktop/src-tauri/src/tests/filesystem_tests.rs
  • packages/dtx-desktop/src-tauri/src/tests/lib_tests.rs
  • packages/dtx-desktop/src-tauri/src/tests/models_tests.rs
  • packages/dtx-desktop/src-tauri/src/tests/songs_tests.rs
  • packages/dtx-desktop/src-tauri/src/tests/updater_tests.rs
  • packages/dtx-desktop/src-tauri/src/updater.rs
  • packages/dtx-desktop/src-tauri/tauri.conf.json
  • packages/dtx-desktop/src/renderer/index.html
  • packages/dtx-desktop/src/renderer/src/App.svelte
  • packages/dtx-desktop/src/renderer/src/components/DesktopEditor.test.ts
  • packages/dtx-desktop/src/renderer/src/components/NewSong.svelte
  • packages/dtx-desktop/src/renderer/src/components/NewSong.test.ts
  • packages/dtx-desktop/src/renderer/src/components/Settings.svelte
  • packages/dtx-desktop/src/renderer/src/components/Settings.test.ts
  • packages/dtx-desktop/src/renderer/src/components/SongDetails.svelte
  • packages/dtx-desktop/src/renderer/src/components/SongDetails.test.ts
  • packages/dtx-desktop/src/renderer/src/components/Templates.svelte
  • packages/dtx-desktop/src/renderer/src/components/Versions.svelte
  • packages/dtx-desktop/src/renderer/src/components/Versions.test.ts
  • packages/dtx-desktop/src/renderer/src/main.ts
  • packages/dtx-desktop/src/renderer/src/services/authService.test.ts
  • packages/dtx-desktop/src/renderer/src/services/authService.ts
  • packages/dtx-desktop/src/renderer/src/services/desktopHost.test.ts
  • packages/dtx-desktop/src/renderer/src/services/desktopHost.ts
  • packages/dtx-desktop/src/renderer/src/services/workspaceService.test.ts
  • packages/dtx-desktop/src/renderer/src/services/workspaceService.ts
  • packages/dtx-desktop/src/renderer/src/stores/settingsStore.test.ts
  • packages/dtx-desktop/src/renderer/src/stores/settingsStore.ts
✅ Files skipped from review due to trivial changes (5)
  • packages/dtx-desktop/src-tauri/src/tests/updater_tests.rs
  • packages/dtx-desktop/src-tauri/src/tests/error_tests.rs
  • packages/dtx-desktop/src-tauri/src/macros.rs
  • .husky/pre-commit
  • packages/dtx-desktop/.gitignore
🚧 Files skipped from review as they are similar to previous changes (8)
  • packages/dtx-desktop/src-tauri/src/error.rs
  • packages/dtx-desktop/src-tauri/Cargo.toml
  • packages/dtx-desktop/src/renderer/src/App.svelte
  • .github/workflows/tauri-rust-ci.yml
  • packages/dtx-desktop/src/renderer/src/components/NewSong.test.ts
  • packages/dtx-desktop/src/renderer/src/components/DesktopEditor.test.ts
  • packages/dtx-desktop/src/renderer/src/components/SongDetails.svelte
  • packages/dtx-desktop/src-tauri/src/api.rs

Comment thread .github/workflows/desktop-build-deploy.yml
Comment thread packages/dtx-desktop/src-tauri/src/filesystem.rs
Comment thread packages/dtx-desktop/src-tauri/src/filesystem.rs Outdated
Comment thread packages/dtx-desktop/src-tauri/src/lib.rs
- Add ancestor resolution for non-existent paths to prevent info disclosure
- Use canonical paths after validation to eliminate TOCTOU windows in export
- Accept case-insensitive URI schemes per RFC 3986 for deep links
- Add injectable client variant for upload_form_to_api timeout tests
- Improve directory iteration error handling in inspect_tree_folder
- Add comprehensive test coverage for missing-path containment semantics

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@cwchanap cwchanap merged commit 12a0d12 into main Jun 20, 2026
10 of 11 checks passed
@cwchanap cwchanap deleted the codex/dtx-desktop-tauri-migration branch June 20, 2026 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant