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

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 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