Files
VoiceStudio/frontend/src/components/ReportBugButton.jsx
T
debpalashandClaude Opus 4.8 ee08f56e1b feat(diagnostics): local self-check + scrubbed bug-report pipeline
Closes the gap between 'something broke' and 'a useful GitHub issue
exists' — entirely within the local-first constraint: the only outbound
path remains the user's own browser opening a prefilled issues/new URL.

Backend:
- core/scrub.py: privacy scrubber for anything leaving the machine —
  env-var secret values (*TOKEN*|*KEY*|*SECRET*|*PASSWORD*), credential
  shapes (hf_/ghp_/github_pat_/sk-), home dirs on all three OSes
- core/diagnose.py: 9-check self-check (device+GPU, ffmpeg, HF token,
  disk, data-dir writability, RAM, engine registry, hub reachability),
  pre-scrubbed, ASCII-safe output
- GET /system/diagnose + 'python main.py --diagnose' (exit 0/1)
- /system/info: hardware inventory (os_version, cpu_model, cpu_count,
  ram_total_gb, gpu_name, vram_total_gb, disk_free_gb), cached statics

Frontend:
- utils/bugReport.js: single source for the prefilled-URL builder —
  scrubText twin, hardware context capture, scrubbed error+stack embed,
  URL-length cap; ReportBugButton refactored onto it
- ErrorBoundary 'Report this bug' action with the error attached
- utils/errorToast.jsx toastErrorWithReport(); wired into export toasts
- Settings > About 'Run self-check' with per-check status badges

Tests: 27 pytest (scrub, diagnose) + 15 vitest (bugReport); existing
suites green; verified live (--diagnose, TestClient, vite build).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 21:43:03 +05:30

50 lines
1.7 KiB
React

/**
* ReportBugButton — opt-in bug reporter via prefilled GitHub Issues URL.
*
* Capability 2 from CLAUDE.md. The user clicks → we build a URL like:
* https://github.com/{owner}/{repo}/issues/new?title=…&body=…&labels=bug
* and open it in their browser. They review what we captured and click
* Submit on github.com if they're happy. We never hold an auth token,
* never POST to GitHub directly, and never bypass the user's review —
* opt-in by construction, no separate consent dialog needed.
*
* Capture + scrubbing live in utils/bugReport.js (shared with the
* ErrorBoundary's report action and error toasts): version, OS, GPU/CPU/
* RAM, active TTS engine — home paths and credential-shaped strings are
* redacted, audio contents never included.
*/
import { useState } from 'react';
import { Bug } from 'lucide-react';
import { Button } from '../ui';
import { openExternal } from '../api/external';
import { buildBugReportUrl } from '../utils/bugReport';
import { useTranslation } from 'react-i18next';
export default function ReportBugButton({ size = 'sm', variant = 'subtle', label, error }) {
const { t } = useTranslation();
const displayLabel = label || t('reportBug.label');
const [building, setBuilding] = useState(false);
const handleClick = async () => {
setBuilding(true);
try {
await openExternal(await buildBugReportUrl({ error }));
} finally {
setBuilding(false);
}
};
return (
<Button
size={size}
variant={variant}
onClick={handleClick}
loading={building}
leading={!building && <Bug size={12} />}
title={t('reportBug.title')}
>
{displayLabel}
</Button>
);
}