Skip to content

Diagnostics: opt-in debug capture with one-click copy from Preferences - #111

Open
daiverd wants to merge 2 commits into
masterfrom
agent/issue-100-diagnostics
Open

Diagnostics: opt-in debug capture with one-click copy from Preferences#111
daiverd wants to merge 2 commits into
masterfrom
agent/issue-100-diagnostics

Conversation

@daiverd

@daiverd daiverd commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds src/diagnostics/, a bounded, in-memory-only ring buffer (DiagnosticsRingBuffer) capped by both record count and a rough byte estimate. record(category, data) is a zero-allocation no-op while disabled, so it stays cheap to call from hot paths.
  • While capture is enabled, records: console.warn/console.error (wrapped once, original behavior preserved, message capped to 500 chars), connection lifecycle transitions + reconnect count (via useConnectionStore), and counters sampled every 5s (inbound messages/sec and output lines/sec, from useChannelHistoryStore/useOutputStore entry-id deltas — no per-event hooks) plus long-task count/duration via PerformanceObserver.
  • Adds a Diagnostics tab to Preferences with an off-by-default Capture diagnostics checkbox, a redact message text toggle, and a Copy diagnostics button. The pane states clearly — before copying — that the export includes character name, room names, and possibly message text, and never includes passwords/tokens/credentials.
  • getDiagnosticsMarkdown()/copyDiagnosticsToClipboard() assemble an environment + session snapshot (UA, platform, hardwareConcurrency, deviceMemory, window size, devicePixelRatio, page uptime, app version from package.json, connection status, live subsystems — audio via client.media.cacophony.context.state, MIDI enabled pref, editors open, file transfers) plus the buffer contents, and serialize everything to Markdown ready to paste into a GitHub issue.
  • Added small openEditorCount/activeTransferCount getters to EditorManager/FileTransferManager so the environment snapshot can report live subsystem state without reaching into private internals.
  • The capture toggle and redact-toggle live in preferencesStore (persisted like other preferences); the ring buffer contents themselves are never persisted to localStorage/IndexedDB, per the issue's privacy requirements.
  • record(category, data) is intentionally generic/decoupled from any specific producer, so the performance watchdog (issue Performance watchdog: detect and attribute sustained main-thread work while idle #103, built in parallel) can call it once both land — this PR has no dependency on or reference to watchdog code.

Test plan

  • npx vitest run — 113 test files / 1101 tests passing, including 7 new colocated test files under src/diagnostics/ covering ring buffer bounding (record count + byte estimate) and FIFO eviction, disable = no-op (record count and JSON.stringify spy), console capture wrapping + message capping, connection lifecycle + reconnect counting, counter/long-task sampling, environment snapshot assembly, and Markdown shape + redaction behavior.
  • npm run typecheck — clean
  • npx biome lint on new/changed files — clean (two pre-existing, unrelated warnings in App.tsx predate this change)

Fixes #100

🤖 Generated with Claude Code

daiverd and others added 2 commits August 11, 2026 19:52
Adds a bounded, in-memory-only ring buffer (src/diagnostics) that records
console warnings/errors, connection lifecycle events, and sampled counters
(inbound messages/sec, output lines/sec, long-task count/duration) while
capture is enabled. A new Preferences > Diagnostics tab exposes an
off-by-default "Capture diagnostics" checkbox, a "redact message text"
toggle, and a "Copy diagnostics" button that serializes the buffer plus an
environment/session snapshot to the clipboard as Markdown ready to paste
into a GitHub issue. The UI states what the export contains before copying.

The buffer never persists to localStorage/IndexedDB, disabling it is a
zero-allocation no-op on the record() hot path, and record(category, data)
is intentionally generic so the performance watchdog (issue #103) can feed
it once both land.

Fixes #100

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both #110 and #111 add this getter at the same spot; identical hunks
let git merge whichever lands second without conflict. Also adopts the
stricter liveness check (window present and not closed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
daiverd added a commit that referenced this pull request Aug 12, 2026
Matches the identical hunk in the diagnostics branch (#111) so the two
PRs merge cleanly in either order.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Diagnostics: opt-in debug capture with one-click copy from Preferences

1 participant