Changelog
July 11, 2026 · View on GitHub
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
[3.0.0] - 2026-07-11
Added
- UI redesign — DevTools-native visual pass (S4.5): the 9 legacy tabs consolidate into a 5-view shell (Dashboard / Profiler / State / Effects / Settings) with an active-underline nav + per-view count badges, segmented sub-tab strips, and a sticky header. New Dashboard landing view (severity KPI stat-tiles, React version/mode + Redux chip, render-pressure sparkline, top-offenders, page-load vitals). Issue cards + design tokens (
tokens.css) + severity ramp unified across views. The classic 9-tab layout stays one toggle away. - Reusable
ChartCanvas(S4.5 V4) — inline-SVG area/line/bars with a faint grid + emphasized endpoint (no chart deps); backs the Memory heap-over-time timeline and the Performance render-distribution chart. - Headless visual-regression lane (S4.5 V6) — Playwright
toHaveScreenshotbaselines for all 5 views + classic + the new charts/inspector (9 total), served offline fromdist/with a stubbedchrome.*. Run withnpm run test:visual; documented intest/visual/README.md. Star CheckCI workflow (.github/workflows/star-check.yml) — runs on every PR and blocks merge if the author hasn't starred the repository. Auto-exempts maintainer (@hoainho), bots (Dependabot, gemini-code-assist, google-cla, github-actions, renovate),tracked-plan-labeled PRs (maintainer-driven milestone work), andpre-star-rule-labeled PRs (grandfathered pre-policy). Uses the publicGET /users/{login}/starred/{owner}/{repo}API — no extra auth scope.- Detector registry foundation (M-B) — pluggable
Detector<TIssue>lifecycle interface (id,category,budgetMs,confidence,prodCapable,init,onCommit,onIdle,drain,teardown,recover). Per-detector try/catch isolation + staged-write transactionality + bounded LRU dedupe. - React version adapter scaffolding for r17/r18/r19/r19.2 with version-aware fiber tag enums +
getDisplayName. HandlesOffscreenComponent/LegacyHiddenComponent/IndeterminateComponentlandmines across React versions. - Settings storage with zod schema validation, v0→v1 migration (from legacy
react_debugger_disabled_sitesarray), andchrome.storage.localpersistence underreact_debugger_settings_v1. - Settings UI — new panel tab with per-detector toggles + confidence badges + per-site override list.
- Hero detector #1 — reconciler-keys: detects
Math.random()/Date.now()keys (emit on first commit) AND numeric-index keys with verified cross-commit reorder. Emits newUNSTABLE_LIST_KEYissue type. Confidence: high (defaults ON). Production-capable. - Unified fiber traversal core (M-D.1 / R2):
src/inject/core/fiber-traversal.ts— one depth-firstwalkFiber(root, visitors[])driving multiple isolated visitors (per-visitorskipSubtreepruning, per-visitor try/catch so one throwing visitor never aborts the others, deadline-yield + resume). The three legacy walkers migrate onto it under live-React regression (maintainer step); the core lands first, additively. - Timeline snapshot session-persistence (M-D.5):
readSnapshots/writeSnapshots/clearSnapshotsoverchrome.storage.session(timeline_snapshots_v1) — snapshots survive panel reload / tab switch but not page reload. Wired into the Timeline view in the S4 Profiler rebuild. - BYOK AI providers (M-D / R4): pluggable AI provider abstraction (
src/services/ai-provider.ts) — HostedProxy (default, reproduces the current proxy request), OpenAIDirect, and AnthropicDirect, plus anoneprovider that leaves the free panel tools working. BYOK key stored underreact_debugger_byok_v1. Request shaping + response parsing + provider selection are unit-tested without live network calls. - stale-closure-async detector (M-D.4): conservative source analysis flagging a
useCallback/useEffectwhose async body (await/.then/setTimeout) reads auseStatevariable missing from its dependency array. Emits newSTALE_CLOSURE_ASYNC. Confidence: medium (opt-in; heuristic, not full exhaustive-deps). Ships withtest/fixtures/stale-closure-async/. - Production-capability matrix (M-E.4) + Perf-Tracks version gate (M-E.2): buildCapabilityMatrix() derives each detector’s prod/dev capability + confidence from its metadata (README table + Settings "(dev only)" badge source); selectProfilingStrategy() routes React >=19.2 to the Performance Tracks API, else the legacy profiling hook (live 19.2 API = maintainer gate).
- Opt-in anonymous telemetry (M-F.2) (
src/services/telemetry.ts) — default OFF; aggregates per-detector counters (fires/dismisses/fp-clicks) and hourly-batches them; a whitelist payload builder guarantees only{detector, fires, dismisses, fpClicks, ext_version, react_version}ever leave (payload-audit test proves no URLs / component names / user data). Endpoint deploy = maintainer gate. - 2026 retrospective (
docs/RETROSPECTIVE-2026.md): stages S0–S6, human gates, and 2027 kickoff topics. - Quick-win detectors (M-F.1): inline-handler-cost (a React.memo child gets an inline function prop that changes identity every commit → memo bypassed; fiber identity tracking) and ref-mutation-during-render (conservative source analysis: ref.current mutated in the render body, effect bodies excluded). New INLINE_HANDLER_COST / REF_MUTATION_DURING_RENDER. Confidence medium/low, opt-in. (M-F.1 slip to 2 quick-wins invoked — useFormStatus-outside-form needs FP-prone form-ancestry, deferred.)
- Hero detector #4 — suspense-waterfall (M-E): flags a Suspense boundary that re-suspends on >=3 consecutive commits (a data-fetch waterfall signature), with a "may be intentional" caveat. Tracks a per-boundary consecutive-suspension streak; emits new SUSPENSE_WATERFALL. Confidence: medium (opt-in). Ships with test/fixtures/suspense-waterfall/ + bench.
- Hero detector #3 — context-cascade (M-D): flags a
Context.Providerwhosevalueis a fresh reference every commit AND has ≥2 consumers (the "new object literal in Provider value" mistake that re-renders every consumer). Tracks value-reference identity across commits + counts context consumers; emits newCONTEXT_CASCADEwith auseMemofix. Confidence: high (defaults ON). Ships withtest/fixtures/context-cascade/+ bench. - Hero detector #2 — hydration-mismatch (M-C): intercepts React's
console.errorhydration-failure family ("Hydration failed", "Text content did not match", "Expected server HTML…"), parses the server/client diff + component, and emits a newHYDRATION_MISMATCHissue with a determinism-fix suggestion. Confidence: high (defaults ON); dev-only (React strips hydration warnings from production). Ships withtest/fixtures/hydration-mismatch/+ aparseHydrationErrorbench. Also lands M-C.1 (WeakMap-cachedtryInferStateName), M-C.2 (fair-share budget allocator with yield/resume), and M-C.3 (source-map lookup helper scaffold). - Registry
onIdledriver (Registry.dispatchIdle) — scheduled viarequestIdleCallbackafter every commit, enables detectors to do deferred work off the hot path. - reconciler-keys fixtures + perf baseline (M-B.6.7) — shared fixture set under
test/fixtures/unstable-keys/(positiveMath.random()/Date.now()/index-reorder cases + a stable-id negative case) drivingsrc/__tests__/reconciler-keys.fixtures.test.ts, plus atest/bench/detectors.bench.tsbenchmark that runs the detector'sonCommitover a 1000-child keyed list. First baseline recorded atbench/baselines/reconciler-keys.json(~0.08ms/commit, under the 0.3ms budget) as the reference for future PR bench gates.
Changed
- Contributor claim policy hardened — starring the repo is now a hard precondition for merge, enforced by CI. See CONTRIBUTING.md → How to claim. The previous "comment
I'll take this" rule stays honor-system + reviewer-checked. - PR template adds a "Claim confirmation" section with checkboxes for the two required steps. Maintainer / tracked-plan PRs can delete this section.
- closure-leak detector migrated to registry pattern via Strategy A (thin adapter through
window.__REACT_DEBUGGER_CLOSURE_BRIDGE__). Legacy_installClosureTrackingbody unchanged; existing behavior preserved end-to-end. Confidence: medium (defaults OFF). - scan-overlay detector migrated to registry pattern.
getBoundingClientRect()moved from synchronousonCommitto deferredonIdle— the biggest live perf-budget violation flagged by the M-A audit is now closed. Confidence: high (defaults ON). Behavior preserved with a one-idle-callback-tick delay. - Motion + accessibility pass (S4.5 V5) — section-switch + issue-card reveal transitions gated behind a global
prefers-reduced-motioncatch-all;:focus-visiblerings extended to links; WCAG 2.1 AA contrast fix (--text-muted#484f58→#7d8590, now clears 4.5:1 on both--bg-primaryand--bg-card). - UI timeout magic numbers extracted to
src/panel/constants.ts— 6 named constants (POLL_INTERVAL_MS,HEALTH_DEBOUNCE_MS,AI_ANALYSIS_TIMEOUT_MS,MEMORY_GC_INTERVAL_MS,RECONNECT_BACKOFF_MS,RECONNECT_MAX_DELAY_MS) replace inlinesetTimeout/setIntervalvalues acrossPanel.tsx,TimelineTab.tsx,PerformanceTab.tsx,MemoryTab.tsx, andReduxTab.tsx. Zero behavior change; one place to tune from now on. Closes #31. Thanks to @Kunall7890.
Fixed
- Periodic cleanup now drains the detector registry's per-detector buffers every 60s, preventing unbounded buffer growth if users opt in to medium/low-confidence detectors.
- CLI bootstrap logs no longer leak to stdout —
cli/bin/cli.jsroutes human-readable install diagnostics tostderr, keeping the JSON-RPC stream clean for strict-mode MCP clients. TheprintSuccesslogger bindsconsole.log/console.errorto preserve execution context in V8 strict mode (avoidsTypeError: Illegal invocationon the success path). Closes #49. Thanks to @AsifpMulla123 for their first merged PR to this repo (after authoring the originalMCP_USAGE.mdin PR #38). - MCP pairing token migrated from
chrome.storage.localtochrome.storage.session— the panel-level bearer token (long-lived, auth-equivalent) now lives in session storage and is wiped when the browser session ends. Includes amigrateLegacyStorage()helper that one-time-migrates any existing local entries and removes them, plus a URL-hash scrub viawindow.history.replaceStateso the token never lingers in the address bar after parsing. Closes #42. Thanks to @iMindCap for the security fix (their 2nd PR to this repo, returning after #17). - Click-only divs/spans converted to keyboard-accessible buttons — 5 elements across
IssueCard.tsxandAIAnalysisTab.tsxnow exposerole="button",tabIndex={0},aria-expandedwhere relevant, and Enter/Space key handlers. Adds:focus-visiblering styling inpanel.css. Includes ane.target === e.currentTargetguard so nested interactive children (e.g. the link inside an expandable card) don't double-fire the toggling handler. Closes #29. Thanks to @Kunall7890.
Documentation
MCP_USAGE.mdnow includes a Continue.dev setup snippet — alongside the existing Cline / Claude Desktop / Opencode entries. Three config variants documented: global~/.continue/config.yaml, workspace.continue/config.yaml, and legacy~/.continue/config.json. Includes a verify-the-install step. Closes #5. Thanks to @Kunall7890 for the addition (extends @AsifpMulla123's originalMCP_USAGE.mdfrom PR #38).
Contributors (this release)
- @Kunall7890 (Kunal Jaiswal) — 3 PRs merged on launch day (2026-06-07): #58 (alert→inline errors), #61 (Continue.dev docs), #62 (timeout constants), #64 (a11y buttons). Plus 5 prior PRs including #18 (a11y prefers-reduced-motion). 10 merged PRs across GitHub (freeCodeCamp, Cloudflare Kinetics Editor, Memact Contracts).
- @iMindCap (Arael Amador) — 1 PR on launch day: #63 (MCP pairing token security migration). Plus 1 prior PR #17 (MCPPairingPanel error messages, 184 insertions).
- @AsifpMulla123 (Asif Mulla) — 1 PR on launch day: #57 (CLI bootstrap stdout leak fix). Plus 1 prior PR #38 (original
MCP_USAGE.mdauthor, the foundation Kunall7890's #61 extends).
Migration
- First run after upgrade: existing per-site disabled list (
react_debugger_disabled_sites) is migrated to the newSettings.perSiteshape. Migration is idempotent; legacy key is removed after successful migration. - Default-policy applied on first install: high-confidence detectors (reconciler-keys, scan-overlay) default ON; medium/low (closure-leak) default OFF.
- 4 PRs that were already open when the Star Check policy landed (#17, #36, #37, #38) labeled
pre-star-ruleand grandfathered through the check. - First run after upgrade from any pre-
storage.sessionbuild: the MCP pairing token is automatically migrated fromchrome.storage.localtochrome.storage.sessionviamigrateLegacyStorage()(one-time, idempotent, removes the legacy key after success). Requires Chrome 102+ forchrome.storage.sessionsupport (extension already requires Chrome 122+).
[2.0.3] - 2026-02-28
Improved
Zero-Lag Host Page Performance
- Eliminated host page jank caused by extension running analysis on every React commit
webNavigation.onCommittednow filters bytransitionType— only real navigations (typed, link, reload) trigger re-initialization, SPApushStateno longer floodsENABLE_DEBUGGER- Added
enableInProgressguard in content script to prevent duplicatehandleEnableDebuggercalls on rapid navigation - Deferred heavy initialization (
installReduxHook,installErrorHandlers,forceReanalyze) to idle callback (500ms) instead of running synchronously on enable periodicCleanupinterval moved insideENABLE_DEBUGGERhandler and reduced frequency (30s → 60s)- POLL_DATA
scheduleIdleWorktimeout increased from 50ms → 1000ms to reduce main thread contention - Panel poll interval reduced from 2s → 5s
Hybrid Render Detection Architecture
- New synchronous render snapshot system — lightweight fiber tree walk in
onCommitFiberRootcaptures render info (component name, duration, render change details,WeakRefto fiber) within a 2ms budget - Deferred
analyzeFiberTreein POLL_DATA uses captured snapshot data instead of stalefiber.alternate(which gets overwritten by React's double-buffering after the next commit) forceReanalyzestill uses livedidFiberRender()as fallback when no snapshot is available- Render detection now works reliably regardless of poll timing
Accurate Render Detection (aligned with react-scan/bippy)
- Rewrote
didFiberRenderto match bippy's battle-tested approach used by react-scan - For composite components (function, class, memo, forwardRef): primary check is
PerformedWorkflag (0x01) — the only flag React sets when it actually executes a render function - Added
memoizedProps/memoizedStatereference-inequality fallback for React versions/builds wherePerformedWorkmay not be set - Removed false-positive triggers:
Update,Placement,Passiveflags,actualDuration > 0, andlanes !== 0no longer count as renders — these indicate side effects, not actual component re-renders
Scan Overlay (Visual Re-render Flash)
- Scan overlay now fires synchronously at commit time inside
onCommitFiberRootusingtraverseFiber— immediate visual feedback matching the original v2.0.0 behavior - Removed duplicate scan overlay from deferred POLL_DATA handler that caused double-flash and delayed feedback
- Overlay correctly shows render intensity colors: green (×1), yellow (×2–3), orange (×5), red (×10+)
Fixed
- Fixed scan overlay not appearing on large React apps (e.g., game apps with deep component trees) — previously limited by the 2ms snapshot capture budget
- Fixed overlay flashing continuously on every commit even when data hadn't changed — caused by overly broad
didFiberRenderdetecting passive effects as renders - Fixed build error from missing closing brace in
analyzeFiberTreeblock structure - Added
WeakReftype declaration to resolve TypeScript lib target mismatch (WeakRef is ES2021+, available in all modern browsers) stopAllMonitoringnow clearspendingRenderSnapshotsbuffer
Technical Details
| Component | Before (v2.0.2) | After (v2.0.3) |
|---|---|---|
onCommitFiberRoot | Full analysis on every commit | Lightweight snapshot only (~2ms) |
POLL_DATA interval | 2s | 5s |
scheduleIdleWork timeout | 50ms | 1000ms |
didFiberRender checks | 7 conditions (many false positives) | PerformedWork + props/state fallback |
| Scan overlay trigger | Deferred in POLL_DATA (seconds late) | Synchronous at commit time |
| Navigation re-init | Every pushState | Real navigations only |
periodicCleanup | Every 30s, on every message | Every 60s, only after enable |
[2.0.0] - 2026-02-22
Added
AI Analysis Tab
AI-powered code analysis with security, performance, crash risk, and root cause detection Rate-limited to 3 free calls per 5-minute window Subscription key system for unlimited access with paywall UI Remote key validation via Cloudflare Worker (no secrets in source code) PRO badge and "Unlimited" status indicator for subscribers Contact email link for subscription inquiries
Exclusive Branding
New proprietary logo: broken orbital rings + hexagonal core + diagnostic crosshair Replaced standard React atom icon with unique design across all sizes (16/48/128px)
Changed
UI Overhaul
Replaced all emoji indicators with CSS badge/indicator system New dark blue theme (GitHub Dark style) with cyan accent tokens Modernized all 10 tab components with consistent badge styling Added 375+ lines of new CSS for badges, indicators, status elements, and paywall
Panel Header
Removed Recording ON/OFF toggle (redundant with extension bar tooltip enable) Simplified header to logo + version + Redux badge only
AI Settings
Removed proxy URL and API key fields from settings (security: prevents credential exposure) Settings now show only Model selector + subscription key input Added contact email section (hoainho.work@gmail.com)
Fixed
React Detection
Fixed race condition: proactive ENABLE_DEBUGGER re-send on navigation Fixed async content script injection timing Added REACT_DETECTED re-send when React is already initialized Auto-enable debugger on panel open
DevTools
Fixed Extension context invalidated error in devtools.js by removing dead PANEL_READY callback
Git Hygiene
Untracked node_modules/ and dist/ from git (were previously committed)
Added worker/ to .gitignore
Security
Subscription key validation moved from local SHA-256 hash to remote Cloudflare Worker No API keys, hashes, or secrets stored in source code Real proxy API key hidden from extension UI
[1.0.2] - 2026-02-10
Fixed
Content Script (BUG-001, BUG-002, BUG-015)
- Lazy initialization: Script injection now only occurs when DevTools panel is opened (ENABLE_DEBUGGER message), not on every page load
- Removed synchronous storage access: Storage check moved from init() to message handler, eliminating blocking operations at document_start
- Proper event listener cleanup: Added
removePageMessageListener()function to clean up window message listeners on disable - Error boundaries: Wrapped message handler in try-catch to prevent extension errors from affecting host page
Inject Script (BUG-004, BUG-005, BUG-006-010, BUG-012, BUG-013)
- Optimized React root detection: Now checks known selectors (#root, #app, #__next) first before falling back to limited DOM scan (max 200 elements)
- Replaced Redux polling with single-attempt detection: Removed 20-second setInterval polling, now uses single check with one retry after 2 seconds
- Bounded fiber tree traversal:
traverseFiberconverted from recursive to iterative with 500 node limit - Increased analysis throttle: Changed from 100ms to 250ms to reduce main thread blocking
- Fixed memory leaks: All Maps and Sets now cleared on DISABLE_DEBUGGER:
renderCountslastRenderTimesrecentRenderTimestampsreportedEffectIssuesreportedExcessiveRerendersreportedSlowRenderscomponentRenderIdslastEffectStatestrackedClosuresstaleClosureIssuesstateOverridesoverlayElementsrenderFlashTimers
Background Script (BUG-014, BUG-025)
- Message validation: Added
isValidMessage()function to validate incoming messages before processing - Rate limiting: Added 50ms throttle for FIBER_COMMIT messages to prevent flooding
- Navigation state clearing: Added
chrome.webNavigation.onCommittedlistener to reset tab state on page navigation - Safe tab messaging: Created
safeSendToTab()helper with.catch()to handle disconnected tabs gracefully - Memory cleanup:
debuggerEnabledStatesMap now properly cleared on tab removal
Added
- Unit tests: Added 43 new tests for utility functions (sanitize.ts, messaging.ts), bringing total to 170 tests
- EDGE-CASES.md: Documented 50 edge cases across 6 categories:
- Initialization & Detection (10 cases)
- Performance Monitoring (10 cases)
- Redux Integration (8 cases)
- Memory & Cleanup (8 cases)
- UI & State Issues (7 cases)
- CLS & Layout (7 cases)
- Landing page: Created modern dark-themed landing page at docs/index.html for GitHub Pages
- CHANGELOG.md: This file
Changed
- Fiber traversal limit: Reduced from unlimited to 500 nodes per traversal
- Analysis throttle: Increased from 100ms to 250ms
- Redux detection: Changed from polling (20 attempts over 20 seconds) to single attempt with one retry
Security
- Error isolation: Extension errors are now caught and logged without propagating to host page
- Context validation: Added
extensionContextValidchecks throughout content script
[1.0.1] - 2026-01-15
Fixed
- Minor bug fixes and stability improvements
[1.0.0] - 2026-01-01
Added
- Initial release
- UI & State Issues detection (missing keys, index as key, direct state mutation)
- Performance Analysis (render tracking, excessive re-render detection)
- Side Effects monitoring (missing cleanup, dependency issues)
- CLS Monitor (real-time Cumulative Layout Shift tracking)
- Redux DevTools integration (state tree, action dispatch)
- Memory monitoring (heap size tracking, leak detection)
- Timeline view (visual timeline of React events)
- Dark theme DevTools panel
Bug Reference
The following bugs from the v1.0.2 audit were addressed:
| Bug ID | Severity | Description | Status |
|---|---|---|---|
| BUG-001 | Critical | Content script injects heavy script on every page | ✅ Fixed |
| BUG-002 | Critical | Synchronous storage access blocks init | ✅ Fixed |
| BUG-004 | Critical | findReactRoots queries all DOM elements | ✅ Fixed |
| BUG-005 | Critical | Redux polling for 20 seconds | ✅ Fixed |
| BUG-006 | High | Unbounded Maps grow indefinitely | ✅ Fixed |
| BUG-007 | High | Reported issues Sets grow indefinitely | ✅ Fixed |
| BUG-008 | High | staleClosureIssues Map never cleaned | ✅ Fixed |
| BUG-009 | High | componentRenderIds Map grows indefinitely | ✅ Fixed |
| BUG-010 | High | lastEffectStates Map grows indefinitely | ✅ Fixed |
| BUG-012 | High | Fiber traversal has no depth limit | ✅ Fixed |
| BUG-013 | High | analyzeFiberTree runs on every commit | ✅ Fixed |
| BUG-014 | High | broadcastToPanel silently fails | ✅ Fixed |
| BUG-015 | High | Content script listeners without cleanup | ✅ Fixed |
| BUG-025 | Medium | Tab state not cleared on navigation | ✅ Fixed |
See .sisyphus/audit/bugs.md for the complete bug audit report.