3.9 KiB
Bug + Dead Code Audit — 2026-04-03
Scope
Static audit focused on the changed tauri-app surface plus verification via:
cd tauri-app && npm testcd tauri-app && npm run buildcd tauri-app/src-tauri && cargo check- targeted reference searches with
rg
Files reviewed
tauri-app/src/App.tsxtauri-app/src/App.test.tsxtauri-app/src/components/ChatView.tsxtauri-app/src/components/Sidebar.tsxtauri-app/src/components/Sidebar.test.tsxtauri-app/src/components/MessageBubble.tsxtauri-app/src/components/StreamingBubble.tsxtauri-app/src/lib/devLogger.tstauri-app/src/types/forgeagent.tstauri-app/src/components/chat/index.tstauri-app/src/components/chat/MessageBubble.tsxtauri-app/src/components/chat/ThinkingCard.tsxtauri-app/src/components/chat/TaskList.tsxtauri-app/src/components/chat/ArtifactViewer.tsx
Findings
1. tauri-app/src/components/ChatView.tsx:21-33
Severity: High
Problem: Stream decoders are module-level singletons with stream: true and are never flushed/reset.
Evidence: WINDOWS_1252_DECODER and UTF8_DECODER live across requests. If a request aborts or ends mid-multibyte sequence, decoder internal state can bleed into the next response and create phantom mojibake.
Fix: Create fresh decoders per request inside handleSend, and flush on stream completion with decoder.decode().
2. tauri-app/src/App.tsx:22-25
Severity: Medium
Problem: window.localStorage.getItem(...) is called without checking that localStorage is a functional Storage object.
Evidence: Full suite fails with TypeError: window.localStorage.getItem is not a function from this exact line.
Fix: Guard with typeof window.localStorage?.getItem === 'function' and wrap storage access in a safe helper.
3. tauri-app/src/components/Sidebar.tsx:196-198
Severity: Medium
Problem: Settings control has only title="Settings" and no explicit accessible name.
Evidence: Sidebar tests cannot reliably locate the footer settings action after the UI rewrite; button markup lacks aria-label.
Fix: Add aria-label="Open settings".
4. tauri-app/src/components/ChatView.tsx:467-491
Severity: Medium
Problem: Assistant message persistence depends on a DB refresh path after generation; one regression test shows the final reply is not visible after completion.
Evidence: npm test fails at src/components/ChatView.test.tsx:514 even though DB insert succeeds (The answer is 42 logged and inserted).
Fix: Add a direct optimistic append to local messages state after successful insert, then re-sync from DB.
5. tauri-app/src/components/chat/index.ts:1-4 + tauri-app/src/components/chat/*
Severity: Medium
Problem: Obsolete component subtree appears dead.
Evidence: Reference search shows no runtime imports of components/chat/index.ts, ThinkingCard, TaskList, ArtifactViewer, or components/chat/MessageBubble.tsx.
Fix: Remove the unused subtree or wire it back intentionally. Keeping both old and new message-bubble systems increases maintenance risk.
6. tauri-app/src/types/forgeagent.ts:109-112
Severity: Low
Problem: ArtifactViewerProps is duplicated/unused.
Evidence: The real component defines its own local props in src/components/chat/ArtifactViewer.tsx; no imports reference the exported type.
Fix: Delete the unused interface or centralize the prop type.
Test / verification summary
build: PASScargo check: PASSnpm test: FAILsrc/App.test.tsx(4 failures)src/Sidebar.test.tsx(4 failures)src/components/ChatView.test.tsx(1 failure)
Checklist summary
- Injection/XSS/auth/CSRF/crypto: no concrete new exploit found in reviewed files
- Bugs/regressions: confirmed
- Dead code/obsolete paths: confirmed
- Not fully verified: Rust inference crates outside
tauri-appchanged set were not fully line-audited in this pass