Diagnostics & Logging
Claudette writes structured, daily-rotated logs to disk so user-reported bugs can be reconstructed from the file alone — without needing the user to reproduce while the app is attached to a debugger. The pipeline is on by default in every build.
Where logs live
Section titled “Where logs live”The default log directory is ~/.claudette/logs/ (sibling to ~/.claudette/workspaces and ~/.claudette/plugins). Files are named claudette.<YYYY-MM-DD>.log (the tracing-appender layout is <prefix>.<date>.<suffix>) and rotate daily. A startup retention sweep deletes anything older than 14 days so the directory never grows unbounded.
You can override the location with the CLAUDETTE_LOG_DIR environment variable — handy when running multiple dev instances side-by-side and you want each one’s logs in its own folder.
Every log line carries the process PID, so even when two Claudette instances share the same daily file you can demux by grep pid=NNN.
Settings → Diagnostics
Section titled “Settings → Diagnostics”The Diagnostics section in Settings (between Editor and Git) gives you three controls without ever needing to touch an environment variable.
Log level
Section titled “Log level”Restart-required filter applied to the file log when RUST_LOG is unset. Choose:
| Level | Captures |
|---|---|
default | info overall plus debug for Claudette’s own crates — the shipping default |
warn | warnings and errors only |
info | startup, shutdown, every Tauri command lifecycle event |
debug | the above plus span timings for slow ops (DB migrations, git fetches, diff parsing, agent spawns) |
trace | maximum detail; not recommended for normal use |
If RUST_LOG is set in the process’s environment, this select is locked and a banner explains why — RUST_LOG always wins so the env var workflow is preserved.
Frontend log verbosity
Section titled “Frontend log verbosity”How much of the React side’s console.* output is mirrored into the daily log. Takes effect immediately, no restart needed.
| Verbosity | Mirrored sources |
|---|---|
| Errors only (default) | uncaught browser errors, promise rejections, React error-boundary catches, console.error |
| Errors + warnings | the above plus console.warn |
| Everything | the above plus console.log and console.info |
Browser-side uncaught errors and unhandled promise rejections are always captured, regardless of verbosity — only the explicit console.* calls are gated. React’s StrictMode warnings are forwarded under “Errors + warnings” if you need to see them in the file log.
Open Logs Folder / Copy path
Section titled “Open Logs Folder / Copy path”Two buttons. The first reveals the log directory in your file manager (Finder on macOS, the system handler on Linux/Windows). The second copies the path to your clipboard — useful for pasting into a bug report.
Filtering verbosity by domain
Section titled “Filtering verbosity by domain”When investigating a specific subsystem, use a per-domain RUST_LOG filter rather than turning every domain up to trace. Every event in Claudette is emitted under a claudette::<domain> target:
# Only chat lifecycle eventsRUST_LOG=claudette::chat=trace cargo tauri dev
# Chat plus MCP supervisionRUST_LOG=claudette::chat=trace,claudette::mcp=debug cargo tauri dev
# Everything from the React webviewRUST_LOG=claudette::frontend=trace cargo tauri devEstablished domains:
| Target | Covers |
|---|---|
claudette::startup | process boot, paths, multi-instance warning |
claudette::panic | Rust panic hook output (with backtrace) |
claudette::chat | turn lifecycle, persistent session reuse / respawn |
claudette::agent | Claude CLI subprocess events |
claudette::backend | alternative-provider gateway |
claudette::mcp | MCP supervisor and server registration |
claudette::plugin | Lua plugin runtime + Claude-Code marketplace |
claudette::git | git CLI shellouts |
claudette::diff | diff parsing |
claudette::scm | PR / CI provider plugin invocations |
claudette::pty | terminal spawn / exit |
claudette::voice | Whisper / Speech.framework |
claudette::ws | WebSocket server (remote workspaces) |
claudette::ipc | local CLI ↔ GUI socket |
claudette::remote | remote-control commands |
claudette::ui | theme load, settings persistence |
claudette::frontend | events forwarded from the React webview |
claudette::updater | update checks, boot probation, and rollback |
File format
Section titled “File format”Logs default to a compact text format (one event per line, with a tab-separated key=value tail of structured fields):
2026-05-08T17:32:14.123Z INFO claudette::chat send_chat_message{chat_session_id=4f… workspace_id=ws-abc…}: turn dispatchedFor machine-parseable output set CLAUDETTE_LOG_FORMAT=json before launching — every event becomes a JSON line, which is friendlier to jq post-mortems:
CLAUDETTE_LOG_FORMAT=json cargo tauri dev# Later:jq 'select(.target=="claudette::chat" and .level=="ERROR")' \ ~/.claudette/logs/claudette.2026-05-08.logMultiple dev instances
Section titled “Multiple dev instances”Claudette has no single-instance lock — running ./scripts/dev.sh twice gives you two independent processes against the same SQLite database. Logs from both instances interleave into the same daily file by default, demuxable via the pid=NNN field on every line.
If you’d rather isolate them, set CLAUDETTE_LOG_DIR to a per-instance path before launching. The dev launcher leaves this up to you so you can choose interleaved-in-one-file or separate-files based on what you’re investigating.
On startup, Claudette also scans ${TMPDIR}/claudette-dev/*.json (the discovery files scripts/dev.sh writes) and emits a WARN if another live PID is already running against the same DB path. The warning fires once at boot and explains exactly why it can corrupt persisted state — useful when an old instance lingers and you didn’t notice.
Update boot-health rollback
Section titled “Update boot-health rollback”After an in-app update, Claudette starts the new build on a short probation window (10 s by default). The React app sends a boot heartbeat after the first commit past the loader (viewStateHydrated is true and loadInitialData resolved). If that heartbeat never arrives, Claudette treats the update as failed to start and tries to restore the previous self-contained install.
When rollback succeeds, the next launch shows a native dialog saying which version failed and which version was restored. When rollback cannot be applied (for example, there was no usable previous-install backup or the install location could not be replaced), Claudette writes a no-loop failure report and shows a dialog with the failed version plus the release URL to download manually.
A force-quit during the probation window leaves the sentinel on disk; the next launch increments the attempt counter and treats attempts >= 2 as “this build runs” (the user already booted past the timer once), clears the sentinel, and skips arming the timer. This avoids spurious rollbacks on an otherwise healthy build whose user happens to quit during every probation window.
Backups under ~/.claudette/updates/previous/ are pruned to a single generation each time prepare_for_update runs, so the directory does not grow unbounded across updates.
Useful files for a rollback bug report:
| File | Meaning |
|---|---|
~/.claudette/updates/previous/<version>/ | Backup of the previous self-contained install, when one was available. |
OS data dir boot-probation.json | Internal sentinel for the update currently on probation. Cleared after a healthy boot. |
OS data dir boot-rollback-report.json | One-shot report consumed on next launch to show the native rollback dialog. |
~/.claudette/logs/claudette.<DATE>.log | Structured timeline under the claudette::updater target. |
The OS data dir is ~/Library/Application Support/claudette/ on macOS, $XDG_DATA_HOME/claudette/ on Linux, and %APPDATA%/claudette/ on Windows unless CLAUDETTE_DATA_DIR overrides it.
Tuning the probation window
Section titled “Tuning the probation window”CLAUDETTE_BOOT_PROBATION_SECS overrides the default 10 s probation. Useful for slow first-launch scenarios (e.g. cold-cache Linux builds where libwebkit2gtk dynamic loading dominates startup time) and for shrinking the window while testing the rollback path locally. Values are clamped to the range 1–120 s; non-numeric values fall back to the default. Setting CLAUDETTE_BOOT_PROBATION_SECS=2 plus an artificial pre-render hang in the React tree is the recommended way to exercise the rollback dialog from a dev build.
Sandboxed (fresh-user) sessions
Section titled “Sandboxed (fresh-user) sessions”For testing first-run UX (the welcome card, onboarding, plugin seeding) you can launch Claudette with a completely empty data tree:
./scripts/dev.sh --clean.\scripts\dev.ps1 --cleanThe flag points three env vars at a per-PID directory under ${TMPDIR}/claudette-dev/clean-<pid>/ ($env:TEMP\claudette-dev\clean-<pid>\ on Windows) and removes the tree on exit:
CLAUDETTE_HOMEoverrides the~/.claudette/tree (workspaces, plugins, themes, logs, models, packs).CLAUDETTE_DATA_DIRoverrides the OS data directory holdingclaudette.db.CLAUDE_CONFIG_DIRoverrides the Claude CLI’s~/.claude/tree, which Claudette reads and writes forsettings.json,.credentials.json, installed plugins, and marketplace registrations. Without this override, a--cleanrun that touches plugins or auth would write into the real~/.claude/and survive the sandbox tear-down — defeating the “simulate a new user” purpose of the flag.
You can also set any of these env vars manually for a longer-lived sandbox:
CLAUDETTE_HOME=/tmp/claudette-demo \CLAUDETTE_DATA_DIR=/tmp/claudette-demo/data \CLAUDE_CONFIG_DIR=/tmp/claudette-demo/claude \ ./scripts/dev.sh$env:CLAUDETTE_HOME = "$env:TEMP\claudette-demo"$env:CLAUDETTE_DATA_DIR = "$env:TEMP\claudette-demo\data"$env:CLAUDE_CONFIG_DIR = "$env:TEMP\claudette-demo\claude".\scripts\dev.ps1Filing a bug report
Section titled “Filing a bug report”- Reproduce the issue.
- Settings → Diagnostics → Copy path to grab the log directory.
- Open the most recent
claudette.<DATE>.log— that’s your timeline. - If you want fuller detail, switch the Log level to
debug, restart Claudette, reproduce, and the file log will include span timings + every command’s entry/exit fields. - Attach the relevant log file to the GitHub issue along with the reproduction steps.
The frontend-bridge default catches React render crashes and uncaught browser errors automatically, so the file log usually has enough context to triage even if you can’t reproduce on demand.