Skip to content

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.

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.

The Diagnostics section in Settings (between Editor and Git) gives you three controls without ever needing to touch an environment variable.

Restart-required filter applied to the file log when RUST_LOG is unset. Choose:

LevelCaptures
defaultinfo overall plus debug for Claudette’s own crates — the shipping default
warnwarnings and errors only
infostartup, shutdown, every Tauri command lifecycle event
debugthe above plus span timings for slow ops (DB migrations, git fetches, diff parsing, agent spawns)
tracemaximum 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.

How much of the React side’s console.* output is mirrored into the daily log. Takes effect immediately, no restart needed.

VerbosityMirrored sources
Errors only (default)uncaught browser errors, promise rejections, React error-boundary catches, console.error
Errors + warningsthe above plus console.warn
Everythingthe 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.

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.

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:

Terminal window
# Only chat lifecycle events
RUST_LOG=claudette::chat=trace cargo tauri dev
# Chat plus MCP supervision
RUST_LOG=claudette::chat=trace,claudette::mcp=debug cargo tauri dev
# Everything from the React webview
RUST_LOG=claudette::frontend=trace cargo tauri dev

Established domains:

TargetCovers
claudette::startupprocess boot, paths, multi-instance warning
claudette::panicRust panic hook output (with backtrace)
claudette::chatturn lifecycle, persistent session reuse / respawn
claudette::agentClaude CLI subprocess events
claudette::backendalternative-provider gateway
claudette::mcpMCP supervisor and server registration
claudette::pluginLua plugin runtime + Claude-Code marketplace
claudette::gitgit CLI shellouts
claudette::diffdiff parsing
claudette::scmPR / CI provider plugin invocations
claudette::ptyterminal spawn / exit
claudette::voiceWhisper / Speech.framework
claudette::wsWebSocket server (remote workspaces)
claudette::ipclocal CLI ↔ GUI socket
claudette::remoteremote-control commands
claudette::uitheme load, settings persistence
claudette::frontendevents forwarded from the React webview
claudette::updaterupdate checks, boot probation, and rollback

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 dispatched

For machine-parseable output set CLAUDETTE_LOG_FORMAT=json before launching — every event becomes a JSON line, which is friendlier to jq post-mortems:

Terminal window
CLAUDETTE_LOG_FORMAT=json cargo tauri dev
# Later:
jq 'select(.target=="claudette::chat" and .level=="ERROR")' \
~/.claudette/logs/claudette.2026-05-08.log

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.

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:

FileMeaning
~/.claudette/updates/previous/<version>/Backup of the previous self-contained install, when one was available.
OS data dir boot-probation.jsonInternal sentinel for the update currently on probation. Cleared after a healthy boot.
OS data dir boot-rollback-report.jsonOne-shot report consumed on next launch to show the native rollback dialog.
~/.claudette/logs/claudette.<DATE>.logStructured 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.

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.

For testing first-run UX (the welcome card, onboarding, plugin seeding) you can launch Claudette with a completely empty data tree:

Terminal window
./scripts/dev.sh --clean

The 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_HOME overrides the ~/.claudette/ tree (workspaces, plugins, themes, logs, models, packs).
  • CLAUDETTE_DATA_DIR overrides the OS data directory holding claudette.db.
  • CLAUDE_CONFIG_DIR overrides the Claude CLI’s ~/.claude/ tree, which Claudette reads and writes for settings.json, .credentials.json, installed plugins, and marketplace registrations. Without this override, a --clean run 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:

Terminal window
CLAUDETTE_HOME=/tmp/claudette-demo \
CLAUDETTE_DATA_DIR=/tmp/claudette-demo/data \
CLAUDE_CONFIG_DIR=/tmp/claudette-demo/claude \
./scripts/dev.sh
  1. Reproduce the issue.
  2. Settings → Diagnostics → Copy path to grab the log directory.
  3. Open the most recent claudette.<DATE>.log — that’s your timeline.
  4. 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.
  5. 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.