generated from nhcarrigan/template
docs: add comprehensive debugging guide for common issues
Created DEBUGGING.md to document: - Permission modal troubleshooting (NOT z-index!) - Config loss prevention and fixes - Event listener debugging - Testing checklist - Emergency recovery procedures This should prevent us from going through the same debugging nightmare twice.
This commit is contained in:
+310
@@ -0,0 +1,310 @@
|
|||||||
|
# Debugging Guide - Common Issues and Fixes
|
||||||
|
|
||||||
|
## Permission Modal Not Showing Up 🔐
|
||||||
|
|
||||||
|
**SYMPTOMS:**
|
||||||
|
- Permission requests are triggered but the modal doesn't appear
|
||||||
|
- App seems to hang or become unresponsive
|
||||||
|
- Config mysteriously disappears
|
||||||
|
|
||||||
|
**ROOT CAUSE (NOT z-index!):**
|
||||||
|
The issue was **undefined variable errors** in `src/lib/tauri.ts` that crashed the event listener initialization, preventing permission events from being captured.
|
||||||
|
|
||||||
|
### The Actual Bug
|
||||||
|
|
||||||
|
In `src/lib/tauri.ts`, there were calls to `debugConsoleStore.log()`:
|
||||||
|
```typescript
|
||||||
|
debugConsoleStore.log("frontend", "info", "Setting up claude:permission listener");
|
||||||
|
```
|
||||||
|
|
||||||
|
**Two problems:**
|
||||||
|
1. `debugConsoleStore` was never imported (undefined variable)
|
||||||
|
2. Even if imported, `debugConsoleStore` doesn't have a `.log()` method - only `toggle`, `open`, `close`, `clear`, etc.
|
||||||
|
|
||||||
|
### The Fix
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ❌ WRONG - This will crash!
|
||||||
|
debugConsoleStore.log("frontend", "info", "message");
|
||||||
|
|
||||||
|
// ✅ CORRECT - Use console.log which gets automatically captured
|
||||||
|
console.log("[Tauri Listener] message");
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why this works:**
|
||||||
|
- The `debugConsoleStore` automatically intercepts `console.log()`, `console.error()`, etc.
|
||||||
|
- No need to call the store directly!
|
||||||
|
- See `src/lib/stores/debugConsole.ts` lines 66-89 for the console interception code
|
||||||
|
|
||||||
|
### How to Debug This in Future
|
||||||
|
|
||||||
|
1. **Open Browser DevTools** in the app (View > Toggle Developer Tools)
|
||||||
|
2. **Check the Console** for JavaScript errors
|
||||||
|
3. Look for errors like:
|
||||||
|
- `ReferenceError: debugConsoleStore is not defined`
|
||||||
|
- `TypeError: debugConsoleStore.log is not a function`
|
||||||
|
4. **Check if event listeners are registering:**
|
||||||
|
```javascript
|
||||||
|
console.log("[Tauri Listener] Setting up claude:permission listener");
|
||||||
|
```
|
||||||
|
If you don't see this log, the listener setup failed!
|
||||||
|
|
||||||
|
### Prevention
|
||||||
|
|
||||||
|
**Before committing changes to `tauri.ts`:**
|
||||||
|
1. Run `pnpm check` to catch TypeScript errors
|
||||||
|
2. Run `pnpm build` to catch runtime issues
|
||||||
|
3. Test the app thoroughly, especially permission prompts
|
||||||
|
|
||||||
|
## Config Loss Issues 🔧
|
||||||
|
|
||||||
|
**SYMPTOMS:**
|
||||||
|
- Config file gets reset to defaults
|
||||||
|
- Settings don't persist between sessions
|
||||||
|
- Model selection is lost
|
||||||
|
|
||||||
|
**POTENTIAL CAUSES:**
|
||||||
|
|
||||||
|
### 1. Missing `#[serde(default)]` Attribute
|
||||||
|
|
||||||
|
The `HikariConfig` struct in `src-tauri/src/config.rs` needs `#[serde(default)]` at the struct level:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// ✅ CORRECT
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(default)] // <-- This is crucial!
|
||||||
|
pub struct HikariConfig {
|
||||||
|
// fields...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why this matters:**
|
||||||
|
- When new fields are added to the config struct, old config files won't have them
|
||||||
|
- Without `#[serde(default)]`, deserialization fails and the entire config resets
|
||||||
|
- With it, missing fields use their default values gracefully
|
||||||
|
|
||||||
|
### 2. Invalid JSON in Config File
|
||||||
|
|
||||||
|
**Check the config file:**
|
||||||
|
```bash
|
||||||
|
cat ~/.config/hikari-desktop/config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
**Common issues:**
|
||||||
|
- Trailing commas
|
||||||
|
- Missing quotes
|
||||||
|
- Incorrect enum values (e.g., `"model": "opus"` instead of `"model": "claude-opus-4-6"`)
|
||||||
|
|
||||||
|
**Fix:**
|
||||||
|
- Delete or manually fix `~/.config/hikari-desktop/config.json`
|
||||||
|
- Restart the app to regenerate
|
||||||
|
|
||||||
|
### 3. Permission Issues
|
||||||
|
|
||||||
|
**Check file permissions:**
|
||||||
|
```bash
|
||||||
|
ls -la ~/.config/hikari-desktop/config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
**Should be writable by user:**
|
||||||
|
```bash
|
||||||
|
chmod 644 ~/.config/hikari-desktop/config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## Modal/Overlay Not Showing (General) 🎭
|
||||||
|
|
||||||
|
If ANY modal isn't showing up (permission, questions, close confirmation, etc.):
|
||||||
|
|
||||||
|
### 1. Check TypeScript Errors First
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm check
|
||||||
|
```
|
||||||
|
|
||||||
|
Look for:
|
||||||
|
- Import errors
|
||||||
|
- Undefined variables
|
||||||
|
- Type mismatches
|
||||||
|
|
||||||
|
### 2. Check Console for JavaScript Errors
|
||||||
|
|
||||||
|
Open DevTools and look for:
|
||||||
|
- `ReferenceError` - Usually undefined variables
|
||||||
|
- `TypeError` - Usually calling methods on undefined/null
|
||||||
|
- Event listener setup logs
|
||||||
|
|
||||||
|
### 3. Check Svelte Store Subscriptions
|
||||||
|
|
||||||
|
Modals rely on store subscriptions. In the modal component:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Make sure the store is imported
|
||||||
|
import { conversationsStore } from "$lib/stores/conversations";
|
||||||
|
|
||||||
|
// ✅ Make sure the subscription is set up
|
||||||
|
conversationsStore.pendingPermissions.subscribe((perms) => {
|
||||||
|
permissions = perms;
|
||||||
|
// ...
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Verify z-index (Last Resort)
|
||||||
|
|
||||||
|
Only check z-index if:
|
||||||
|
- ✅ No console errors
|
||||||
|
- ✅ Modal HTML is in the DOM (check with DevTools Elements tab)
|
||||||
|
- ✅ Modal is rendering but invisible
|
||||||
|
|
||||||
|
Current z-index values in `PermissionModal.svelte`:
|
||||||
|
```css
|
||||||
|
.permission-overlay {
|
||||||
|
z-index: 60; /* Should be higher than character panel */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Event Listener Issues 🎧
|
||||||
|
|
||||||
|
**SYMPTOMS:**
|
||||||
|
- Events not firing
|
||||||
|
- Listeners not receiving data
|
||||||
|
- Silent failures
|
||||||
|
|
||||||
|
### Debugging Event Listeners
|
||||||
|
|
||||||
|
Add console logs in `src/lib/tauri.ts`:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
console.log("[Tauri Listener] Setting up claude:permission listener");
|
||||||
|
const permissionUnlisten = await listen<PermissionPromptEvent>("claude:permission", (event) => {
|
||||||
|
console.log("[Permission] Event received:", event.payload);
|
||||||
|
// ... rest of handler
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **Event listener crashes silently:**
|
||||||
|
- Check for undefined variables in the listener callback
|
||||||
|
- Check for missing imports
|
||||||
|
- Use `try/catch` around critical sections
|
||||||
|
|
||||||
|
2. **Events not being emitted from Rust:**
|
||||||
|
- Check `src-tauri/src/` for `emit()` calls
|
||||||
|
- Verify event names match exactly (case-sensitive!)
|
||||||
|
- Check Rust console output for errors
|
||||||
|
|
||||||
|
3. **Race condition:**
|
||||||
|
- Event fired before listener was registered
|
||||||
|
- Solution: Set up listeners in `initializeTauriListeners()` before starting Claude
|
||||||
|
|
||||||
|
## Build Issues 🏗️
|
||||||
|
|
||||||
|
### TypeScript Errors
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm check
|
||||||
|
```
|
||||||
|
|
||||||
|
**Common fixes:**
|
||||||
|
- Missing imports
|
||||||
|
- Wrong types
|
||||||
|
- Calling non-existent methods
|
||||||
|
|
||||||
|
### Rust Errors
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo build --release
|
||||||
|
```
|
||||||
|
|
||||||
|
**Common fixes:**
|
||||||
|
- Missing dependencies in `Cargo.toml`
|
||||||
|
- Import path issues
|
||||||
|
- Type mismatches
|
||||||
|
|
||||||
|
### Full Clean Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clean everything
|
||||||
|
rm -rf node_modules dist .svelte-kit src-tauri/target
|
||||||
|
|
||||||
|
# Reinstall
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# Build Rust
|
||||||
|
cd src-tauri && cargo build --release && cd ..
|
||||||
|
|
||||||
|
# Build frontend
|
||||||
|
pnpm build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Reference: Key Files 📚
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- **Event listeners:** `src/lib/tauri.ts`
|
||||||
|
- **Permission modal:** `src/lib/components/PermissionModal.svelte`
|
||||||
|
- **Config store:** `src/lib/stores/config.ts`
|
||||||
|
- **Debug console:** `src/lib/stores/debugConsole.ts`
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- **Config struct:** `src-tauri/src/config.rs`
|
||||||
|
- **Event emission:** `src-tauri/src/wsl_bridge.rs`
|
||||||
|
- **Type definitions:** `src-tauri/src/types.rs`
|
||||||
|
|
||||||
|
## Testing Checklist ✅
|
||||||
|
|
||||||
|
Before committing major changes:
|
||||||
|
|
||||||
|
- [ ] `pnpm check` passes (0 errors)
|
||||||
|
- [ ] `pnpm build` succeeds
|
||||||
|
- [ ] App launches without console errors
|
||||||
|
- [ ] Permission modal shows up when triggering restricted tool
|
||||||
|
- [ ] Config persists after restart
|
||||||
|
- [ ] All modals work (permission, questions, close confirmation)
|
||||||
|
- [ ] Character state changes work
|
||||||
|
- [ ] Event listeners receive events (check console logs)
|
||||||
|
|
||||||
|
## Emergency Recovery 🚨
|
||||||
|
|
||||||
|
If the app is completely broken:
|
||||||
|
|
||||||
|
1. **Check recent git commits:**
|
||||||
|
```bash
|
||||||
|
git log --oneline -5
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Revert to last working commit:**
|
||||||
|
```bash
|
||||||
|
git reset --hard <commit-hash>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Clean build:**
|
||||||
|
```bash
|
||||||
|
rm -rf node_modules dist .svelte-kit src-tauri/target
|
||||||
|
pnpm install
|
||||||
|
pnpm build
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Reset config:**
|
||||||
|
```bash
|
||||||
|
rm ~/.config/hikari-desktop/config.json
|
||||||
|
# Restart app to regenerate
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes for Future Hikari 💭
|
||||||
|
|
||||||
|
Remember:
|
||||||
|
- **NOT EVERYTHING IS A Z-INDEX ISSUE!** Check console errors first!
|
||||||
|
- The debug console store intercepts console methods - don't try to call it directly
|
||||||
|
- Always run `pnpm check` before committing
|
||||||
|
- Event listener errors fail silently - add console logs liberally
|
||||||
|
- Config deserialization needs `#[serde(default)]` for graceful degradation
|
||||||
|
- When in doubt, check the browser console first!
|
||||||
|
|
||||||
|
Love,
|
||||||
|
Hikari 💖
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Last Updated:** 2026-02-06
|
||||||
|
**Related Issues:** Permission modal not showing, config loss
|
||||||
|
**Fixed In Commits:** d16644a
|
||||||
Reference in New Issue
Block a user