Summary
After a timer run completes, collect the performance.measure() entries already recorded for each audio action and expose them as a formatted diagnostics report the user can copy to the clipboard.
Motivation
When users report a first-audio-cue delay, there's currently no easy way to gather timing data without asking them to record a Chrome Performance trace. A one-click copy button gives us the data we need with zero DevTools knowledge required from the user.
Proposed UX
- A "Copy diagnostics" button (or icon) that appears after a run finishes, likely in the timer controls area or a small post-run overlay
- Clicking it formats the audio timing data as plain text and writes it to the clipboard
- User pastes directly into a GitHub issue
Data to include
For each action fired during the run:
- IPC latency (worker
postMessage → main thread onmessage)
- Dispatch-to-initiation time (message received →
src.start() called)
- Playback duration (
onended − src.start())
- Whether it was the first action in the phase
Plus environment metadata:
- Browser user agent
AudioContext.sampleRate and baseLatency / outputLatency
AudioContext.state at run start
Implementation notes
The performance.measure() entries for audio:beep (and other sounds) are already being recorded — see src/audio/sounds.ts. The main work is:
- Accumulating per-action timing in
usePhaseRunner during the run
- Exposing it after
finished is received
- Formatting +
navigator.clipboard.writeText()
Summary
After a timer run completes, collect the
performance.measure()entries already recorded for each audio action and expose them as a formatted diagnostics report the user can copy to the clipboard.Motivation
When users report a first-audio-cue delay, there's currently no easy way to gather timing data without asking them to record a Chrome Performance trace. A one-click copy button gives us the data we need with zero DevTools knowledge required from the user.
Proposed UX
Data to include
For each action fired during the run:
postMessage→ main threadonmessage)src.start()called)onended−src.start())Plus environment metadata:
AudioContext.sampleRateandbaseLatency/outputLatencyAudioContext.stateat run startImplementation notes
The
performance.measure()entries foraudio:beep(and other sounds) are already being recorded — seesrc/audio/sounds.ts. The main work is:usePhaseRunnerduring the runfinishedis receivednavigator.clipboard.writeText()