fix(tauri): resolve Windows blank screen via relative base path#113
Conversation
- vite.config.ts: detect TAURI_PLATFORM env var and return './' for Tauri builds - src-tauri/src/lib.rs: add RunEvent handlers (Ready/Opened/SecondInstance) - services/pluginRegistry.ts: add structured logging for plugin execution - tests/unit/plugins/pluginRegistryLoad.test.ts: 7 tests for loadPlugin scenarios - docs/PLUGINS-BETA.md: document plugin system Beta status - .npmrc: add strict-dep-builds, block-exotic-subdeps, minimum-release-age - pnpm-workspace.yaml: add security justification comments to overrides - stryker.conf.json: add aiRetry/fetchAdapter/routingLogger to mutate targets - AUDIT.md: document P0/P1 implementation status and known overrides QNBS-v3: Tauri builds load via file:// and require relative paths. The TAURI_PLATFORM env var is set by Tauri CLI during desktop builds.
|
CodeAnt AI is reviewing your PR. Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| log::info!("Tauri app ready"); | ||
| } | ||
| tauri::RunEvent::Opened { args, .. } => { | ||
| log::info!("Main window opened with args: {:?}", args); |
There was a problem hiding this comment.
Suggestion: Avoid logging raw startup arguments in runtime events; either remove this log in production or sanitize it to only emit non-sensitive metadata (for example, count or event type). [custom_rule_security]
Severity Level: Critical 🚨
Why it matters? 🤔
This is a production runtime log (log::info!) that prints the full args payload with debug formatting. The custom rule explicitly flags production logging that could expose sensitive data, so this is a real violation.
Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src-tauri/src/lib.rs
**Line:** 88:88
**Comment:**
*Custom Rule Security: Avoid logging raw startup arguments in runtime events; either remove this log in production or sanitize it to only emit non-sensitive metadata (for example, count or event type).
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| log::info!("Main window opened with args: {:?}", args); | ||
| } | ||
| tauri::RunEvent::SecondInstance { args, .. } => { | ||
| log::info!("Second instance started: {:?}", args); |
There was a problem hiding this comment.
Suggestion: Do not log full second-instance argument payloads directly; replace this with a redacted message or restrict it to debug-only execution. [custom_rule_security]
Severity Level: Critical 🚨
Why it matters? 🤔
This is also a production log::info! call that emits the complete args payload. Since the rule forbids production logging that could expose sensitive content, this is a genuine violation.
Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src-tauri/src/lib.rs
**Line:** 91:91
**Comment:**
*Custom Rule Security: Do not log full second-instance argument payloads directly; replace this with a redacted message or restrict it to debug-only execution.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| tauri::RunEvent::SecondInstance { args, .. } => { | ||
| log::info!("Second instance started: {:?}", args); | ||
| // Emit deep-link event for deep-link plugin to handle | ||
| let _ = app.emit("deep-link://new-url", args); | ||
| } |
There was a problem hiding this comment.
Suggestion: This emits deep-link://new-url manually on SecondInstance, even though the deep-link/single-instance plugin already emits that event, which can cause the same deep-link payload to be processed twice (duplicate import/open side effects). Remove the manual emit or gate it so only one source emits the event. [logic error]
Severity Level: Major ⚠️
- ❌ Deep-link file opens import the same project twice.
- ⚠️ Duplicate navigation and notifications for one deep-link.
- ⚠️ Potential race conditions in project import side effects.Steps of Reproduction ✅
1. The Tauri entrypoint `run()` in `src-tauri/src/lib.rs:39-50` registers
`tauri_plugin_single_instance` and `tauri_plugin_deep_link`, with the comment at lines
42-45 explicitly stating that the deep-link plugin "automatically handles CLI args and
emits \"deep-link://new-url\" event".
2. On the frontend, `services/tauriDeepLink.ts:27-49` defines `initTauriDeepLink`, which
uses `listen('deep-link://new-url', ...)` at line 37 to subscribe to these events and, for
each URL payload, imports the project via `importProjectThunk` and navigates to the
manuscript view (lines 51-95).
3. The same `run()` builder in `src-tauri/src/lib.rs` now attaches a `.on_event` handler
at lines 81-97 that matches `tauri::RunEvent::SecondInstance { args, .. }` and, inside
that arm at lines 90-93, logs `"Second instance started"` and calls `let _ =
app.emit("deep-link://new-url", args);`.
4. When a user opens a `.storycraft` or `.scst` file via OS file association,
`tauri_plugin_single_instance` handles the second-instance CLI args and
`tauri_plugin_deep_link` emits a `"deep-link://new-url"` event once; the additional manual
`app.emit("deep-link://new-url", args)` in `src-tauri/src/lib.rs:90-93` causes
`initTauriDeepLink` to receive a second event for the same open operation, leading to
duplicate `importProjectThunk` dispatches and double-handling (import and navigation) of
the same deep-link payload.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src-tauri/src/lib.rs
**Line:** 90:94
**Comment:**
*Logic Error: This emits `deep-link://new-url` manually on `SecondInstance`, even though the deep-link/single-instance plugin already emits that event, which can cause the same deep-link payload to be processed twice (duplicate import/open side effects). Remove the manual emit or gate it so only one source emits the event.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| const originalFetch = global.fetch; | ||
| global.fetch = vi.fn().mockResolvedValue({ | ||
| ok: false, | ||
| status: 404, | ||
| text: () => Promise.resolve(''), | ||
| }) as unknown as typeof fetch; | ||
|
|
||
| const result = await registry.loadPlugin( | ||
| makePlugin({ entrypoint: 'https://example.com/missing.js' }), | ||
| mockApi, | ||
| ); | ||
| expect(result.ok).toBe(false); | ||
| if (!result.ok) expect(result.error).toMatch(/Failed to fetch plugin/); | ||
|
|
||
| // Restore fetch | ||
| global.fetch = originalFetch; |
There was a problem hiding this comment.
Suggestion: These tests mutate global.fetch but restore it only at the end of each test body; if an assertion throws earlier, cleanup is skipped and subsequent tests inherit the mocked fetch. Move restoration into try/finally (or centralized afterEach) to prevent cross-test contamination. [missing cleanup]
Severity Level: Major ⚠️
- ⚠️ Failing tests can leave global.fetch mocked.
- ⚠️ Subsequent tests rely on polluted global state.
- ⚠️ Test suite behaviour becomes order-dependent and flaky.Steps of Reproduction ✅
1. In `tests/unit/plugins/pluginRegistryLoad.test.ts:52-70`, the test `it('returns error
when fetch fails with non-OK status', ...)` saves `const originalFetch = global.fetch;` at
line 54 and then overrides it with `global.fetch = vi.fn().mockResolvedValue(...)` at
lines 55-59 before invoking `registry.loadPlugin(...)`.
2. After assertions at lines 61-66, the test restores the original implementation with
`global.fetch = originalFetch;` at line 69; other tests in the same file follow the same
pattern of manual override and restoration (lines 72-87, 89-107, 109-129, 131-153,
155-163).
3. The `afterEach` hook at lines 41-43 only calls `vi.restoreAllMocks()`, which resets vi
mocks and spies but does not revert direct property assignments like `global.fetch = ...`,
so it cannot undo the manual override if the test body exits early.
4. If this test (or any similar one) throws or fails an assertion after `global.fetch` has
been assigned but before `global.fetch = originalFetch;` runs, the jest/vitest runner
skips the trailing cleanup line, leaving `global.fetch` pointing at the mocked function;
subsequent tests then capture this mocked value as their `originalFetch` or rely on it
directly, causing cross-test contamination, order dependence, and hard-to-debug flakiness
whenever a failure occurs mid-test.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** tests/unit/plugins/pluginRegistryLoad.test.ts
**Line:** 54:69
**Comment:**
*Missing Cleanup: These tests mutate `global.fetch` but restore it only at the end of each test body; if an assertion throws earlier, cleanup is skipped and subsequent tests inherit the mocked fetch. Move restoration into `try/finally` (or centralized `afterEach`) to prevent cross-test contamination.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix|
CodeAnt AI finished reviewing your PR. |
- src-tauri/src/lib.rs: Remove sensitive args from logs, remove duplicate deep-link emit - tests/unit/plugins/pluginRegistryLoad.test.ts: Centralize fetch cleanup in afterEach Security: Logs no longer expose raw CLI args (could contain file paths/sensitive data). Logic: Removed duplicate deep-link event emission - the deep-link plugin already handles this.
Summary
Fixes the Tauri Windows blank screen issue by making Vite base path detection Tauri-aware.
Changes
Tauri Windows Runtime Fix (Primary)
P0/P1 Hardening (Secondary)
Verification
Next Steps
Run tauri-build workflow to verify the Tauri build works on Windows.