Files
ForgeLM/docs/reports/2026-04-03-bug-dead-code-audit.md
T

77 lines
3.9 KiB
Markdown

# Bug + Dead Code Audit — 2026-04-03
## Scope
Static audit focused on the changed `tauri-app` surface plus verification via:
- `cd tauri-app && npm test`
- `cd tauri-app && npm run build`
- `cd tauri-app/src-tauri && cargo check`
- targeted reference searches with `rg`
## Files reviewed
- `tauri-app/src/App.tsx`
- `tauri-app/src/App.test.tsx`
- `tauri-app/src/components/ChatView.tsx`
- `tauri-app/src/components/Sidebar.tsx`
- `tauri-app/src/components/Sidebar.test.tsx`
- `tauri-app/src/components/MessageBubble.tsx`
- `tauri-app/src/components/StreamingBubble.tsx`
- `tauri-app/src/lib/devLogger.ts`
- `tauri-app/src/types/forgeagent.ts`
- `tauri-app/src/components/chat/index.ts`
- `tauri-app/src/components/chat/MessageBubble.tsx`
- `tauri-app/src/components/chat/ThinkingCard.tsx`
- `tauri-app/src/components/chat/TaskList.tsx`
- `tauri-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`: PASS
- `cargo check`: PASS
- `npm test`: FAIL
- `src/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-app` changed set were not fully line-audited in this pass