This repository contains a local browser debugging toolkit for reproducible frontend investigations. It combines a Chrome MV3 extension, a local Node.js agent, and JSONL log storage to capture runtime evidence, run browser actions, and query traces by time window.
| Dimension | Core mode | Enhanced mode (fix-app-bugs optional addon) |
|---|---|---|
| Goal | Fast local debugging with direct extension + agent workflow. | Strict, machine-verifiable bugfix workflow with guarded instrumentation decisions. |
| Required tools | Node.js, Chrome with CDP, extension. | Core mode tools + fix-app-bugs skill scripts. |
| Required bootstrap | No guarded bootstrap required. | Guarded bootstrap required before evidence collection decisions. |
| Evidence/report strictness | Standard debugging evidence; report format is optional. | Strict evidence mode, cleanup checks, and required final report blocks. |
| Best for | Manual investigation, local iteration, general diagnostics. | Reproducible bugfix runs with explicit instrumentation gates and auditability. |
Core mode is the default and does not require fix-app-bugs.
Enhanced mode (fix-app-bugs optional addon) adds guarded bootstrap, strict evidence, and cleanup/report discipline.
- Developers who need reliable runtime evidence for frontend bug investigations.
- AI agents that must follow deterministic debugging workflows.
extensions/humans-debugger: MV3 extension (background service worker, popup, content script).src/agent: local Fastify-based agent with Core API (4678by default) and Debug API (7331by default).logs/browser-debug: local JSONL event storage and screenshot artifacts.
Mode note: runtime architecture is identical in both modes; Enhanced mode adds external workflow controls on top.
- The extension discovers an available Core API on
127.0.0.1(ports4678..4698) and syncs runtime config. - A session starts for the active tab through
/session/start; the agent attaches to Chrome DevTools Protocol (CDP). - The content script captures runtime signals (console, errors, unhandled rejections, fetch/XHR network events).
- Events are ingested through
/events(session + ingest token) or/debug(BUGFIX_TRACEpayloads). - The agent normalizes payloads, redacts sensitive data, writes JSONL logs, and stores snapshots.
- Operators query logs via
/events/queryornpm run agent:query, and run CDP commands via/commandornpm run agent:cmd.
Mode note: Enhanced mode gates instrumentation decisions through guarded bootstrap; Core mode can operate directly.
- Install dependencies:
npm install- Start the local agent:
npm run agent:start- Start Chrome with CDP enabled:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222- Open
chrome://extensions, enable Developer mode, then load unpacked extension from:
extensions/humans-debugger
- Complete all Core mode steps first.
- Ensure
CODEX_HOMEis set:
export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"- Run guarded bootstrap for target project:
python3 "$CODEX_HOME/skills/fix-app-bugs/scripts/bootstrap_guarded.py" --project-root <project-root> --json- Re-run with the real app URL (required for browser-fetch mode):
python3 "$CODEX_HOME/skills/fix-app-bugs/scripts/bootstrap_guarded.py" --project-root <project-root> --actual-app-url <url> --jsonBootstrap notes:
- Loopback origins
localhostand127.0.0.1are treated as equivalent for capability checks. checks.appUrl.recommendedCommands(object entries) andchecks.appUrl.recommendedCommandsText(string entries) prioritize--apply-recommendedon mismatch to avoid rerun loops.checks.appUrl.primaryRecommendedCommandprovides a copy-ready command string for fast remediation.- Inspect
browserInstrumentation.failureCategoryto distinguishnetwork-mismatch-onlyvsendpoint-unavailable. - Use
readyForScenarioRun+readinessReasonsas the final go/no-go verdict before scenario pipelines. - Strict readiness gate blocks scenario launch on
app-url-gate:*and, inbrowser-fetch, onheaded-evidence:*.
If guarded bootstrap falls back or Enhanced prerequisites are unavailable, continue in Core mode.
Each target project can provide .codex/browser-debug.json:
{
"version": 1,
"projectId": "my-project",
"appUrl": "http://localhost:5173",
"agent": {
"host": "127.0.0.1",
"corePort": 4678,
"debugPort": 7331
},
"browser": {
"cdpPort": 9222
},
"capture": {
"allowedDomains": ["localhost", "127.0.0.1"],
"networkAllowlist": []
},
"defaults": {
"queryWindowMinutes": 30
}
}- Choose
Core modefor local/manual debugging and fast iteration. - Choose
Enhanced mode (fix-app-bugs optional addon)when you need audit-ready evidence, final parity sign-off, CI/release sign-off evidence, or strict 5-block final report output. - Every run should log
Mode selected + reason.
Workflow and reviewer skills can auto-route into Browser Debug + fix-app-bugs based on a shared contract.
Source-of-truth and mirrors:
- Local:
$CODEX_HOME/skills/workflows-shared/references/auto-routing-contract.md - Local capability map:
$CODEX_HOME/skills/workflows-shared/references/auto-routing-capability-map.md - Repo mirrors:
docs/contracts/auto-routing-contract.mddocs/contracts/auto-routing-capability-map.md
Routing guardrails:
EVERY_AUTO_ROUTING_ENABLED=falsedisables all auto-routing.- Session opt-out tokens (
no-auto-routing,manual-only,skip-browser-debug) forceno-route. Core moderemains default;Enhancedis used only for strict reproducibility.- Fallback verdicts force
terminal-probe, with no browser-sidefetch(debugEndpoint)usage.
- Start with
Core modefor exploratory debugging and fast command loops. - Move to
Enhanced modewhen you need guarded bootstrap verdicts and strict final reports. - If
Enhancedreturnsbootstrap.status = fallbackorcanInstrumentFromBrowser = false, useterminal-probeimmediately. - For parity-sensitive work, capture one artifact bundle per checkpoint and keep headed evidence.
- If parity does not improve after 3 cycles or 90 minutes, stop and switch to rollback/retrospective planning.
These commands are valid in both modes:
- Start agent:
npm run agent:start - Stop active session:
npm run agent:stop - Execute a browser command:
npm run agent:cmd -- --session <id> --do <reload|click|type|snapshot|compare-reference|webgl-diagnostics> - Capture one parity bundle:
npm run agent:parity-bundle -- --session <id> --reference /path/ref.png --label baseline - Query logs:
npm run agent:query -- --from <ISO> --to <ISO> [--tag <tag>] - Aggregate 24h agent feedback:
npm run agent:feedback -- --window 24h [--targets browser-debug,fix-app-bugs](--jsonnow includes structuredsignals, per-signalpromotion,promotionRules, andbacklogSlicewith promoted signals only). - Run tests:
npm test
Examples:
npm run agent:cmd -- --session <id> --do reload
npm run agent:cmd -- --session <id> --do click --selector "button[data-test=save]"
npm run agent:cmd -- --session <id> --do type --selector "input[name=email]" --text "user@example.com" --clear
npm run agent:cmd -- --session <id> --do snapshot --fullPage
npm run agent:cmd -- --session <id> --do compare-reference --actual /path/app.png --reference /path/ref.png --label baseline --dimension-policy strict --resize-interpolation bilinear
npm run agent:parity-bundle -- --session <id> --reference /path/ref.png --label baseline
npm run agent:cmd -- --session <id> --do webgl-diagnostics
npm run agent:session -- --tab-url http://127.0.0.1:5173/ --match-strategy origin-pathEnhanced fallback helper (terminal-probe scenario pipeline):
python3 "$CODEX_HOME/skills/fix-app-bugs/scripts/terminal_probe_pipeline.py" --project-root <project-root> --session-id <id> --scenarios "$CODEX_HOME/skills/fix-app-bugs/references/terminal-probe-scenarios.example.json" --jsonThis helper captures scenario snapshots, computes metrics (mean, stddev, nonBlackRatio, MAE), and writes runtime.json, metrics.json, summary.json.
It also emits deterministic nextAction guidance and canonical blackScreenVerdict in top-level JSON and in summary.json.
Optional reliability flags for auto session flows:
--tab-url-match-strategy origin-path: match by origin+path first, then retry with exact URL when CDP list resolves a unique candidate.--force-new-session: stop active session beforesession/ensure.--open-tab-if-missing: attempt CDPjson/newonTARGET_NOT_FOUNDand retry ensure (enabled by default in auto mode).--no-open-tab-if-missing: disable automatic tab-open recovery.--resize-interpolation nearest|bilinear: interpolation mode forresize-reference-to-actualfallback.--no-normalize-reference-size: keep strict dimension policy only.
Visual starter helper (strict readiness + optional recovery/evidence):
python3 "$CODEX_HOME/skills/fix-app-bugs/scripts/visual_debug_start.py" --project-root <project-root> --actual-app-url <url> --jsonOptional flags:
--auto-recover-session: one bounded/health -> /session/stop -> /session/ensurerecovery attempt oncdp-unavailable:*orsession-state:*.--tab-url-match-strategy exact|origin-path|origin: matching strategy for recovery ensure + terminal-probe auto session.--open-tab-if-missing: keep automatic tab-open recovery enabled for terminal-probe auto-session flows (default).--no-open-tab-if-missing: explicitly disable auto tab-open recovery for terminal-probe auto-session flows.--headed-evidence: generate headed evidence bundle.--reference-image <path>: required with--headed-evidenceinbrowser-fetch.--evidence-label <label>: parity bundle label (defaultvisual-debug-start).
visual_debug_start.py --json output also exposes modeSelection.alternateMode, modeSelection.alternateModeRationale, and terminalProbeNextAction when terminal-probe capture returns deterministic follow-up guidance.
Recovery precedence for readiness failures:
app-url-gate:*: run config alignment commands first (preview -> apply -> resume).session-state:*orcdp-unavailable:*: use guided session lane (soft recovery -> force-new-session -> open-tab-if-missing).- If still blocked, keep terminal-probe mode and inspect
readinessReasonsbefore rerun.
Default base URLs:
- Core API:
http://127.0.0.1:4678 - Debug API:
http://127.0.0.1:7331
| Endpoint | Method | Purpose |
|---|---|---|
/health |
GET |
Agent status, active session, readiness (including CDP probe), appUrlDrift, and runReadiness verdict (`runnable |
/runtime/config |
GET, POST |
Read or update active runtime config. |
/session/start |
POST |
Start session and attach to tab via CDP (matchStrategy: `exact |
/session/ensure |
POST |
Ensure/reuse session (matchStrategy: `exact |
/session/stop |
POST |
Stop current session and detach CDP. |
/events |
POST |
Ingest extension runtime events (requires X-Ingest-Token). |
/events/query |
GET |
Query JSONL events by time window and filters. |
/command |
POST |
Execute command (reload, click, type, snapshot, compare-reference, webgl-diagnostics). compare-reference supports dimensionPolicy + resizeInterpolation; webgl-diagnostics returns readPixelsStatus/confidence/confidenceReason. |
/debug |
OPTIONS, POST |
Preflight + BUGFIX_TRACE ingestion with origin allowlist checks. |
Mode note: API surface stays the same in both modes; Enhanced mode imposes stricter workflow rules around when and how instrumentation is used.
- The agent binds to loopback (
127.0.0.1) by default and is intended for local debugging. - Domain and origin allowlists gate session start and
/debugingestion. - Sensitive values are redacted before persistence (email, bearer/JWT-like tokens, cards, secret-like keys).
- Request body capture is rule-based and byte-limited through
capture.networkAllowlist.
CDP_UNAVAILABLE: verify Chrome was started with--remote-debugging-port=9222and thatbrowser.cdpPortmatches.TARGET_NOT_FOUND: ensure the active tab URL matches the requestedtabUrlpattern.AMBIGUOUS_TARGET: tighten/session/startor/session/ensurematching (--match-strategy exact) or provide a fully exacttabUrl.DOMAIN_NOT_ALLOWED/ORIGIN_NOT_ALLOWED/CORS_POLICY_BLOCKED_PATH: updatecapture.allowedDomainsand refresh runtime config.SESSION_ALREADY_RUNNING: stop the active session first (npm run agent:stopor/session/stop).browserInstrumentation.failureCategory = network-mismatch-only: apply firstchecks.appUrl.recommendedCommandsentry with--apply-recommended.browserInstrumentation.failureCategory = endpoint-unavailable: verify agent health and endpoint reachability before retrying browser-fetch./health.appUrlDrift.status = mismatch: use/health.appUrlDrift.recommendedCommandas a template and replace<project-root>with your target app repository path./health.runReadiness.status = fallback: follow/health.runReadiness.nextActionand continue with terminal-probe starter path./health.runReadiness.status = blocked: execute/health.runReadiness.nextAction.commandfirst, then re-check/health.- Missing
fix-app-bugstooling is not a blocker for Core mode; run Core workflow directly.
Local skill is the source of truth:
$CODEX_HOME/skills/fix-app-bugs (fallback: $HOME/.codex/skills/fix-app-bugs).
Keep repository mirror in sync:
- Sync local -> repo mirror:
npm run skill:sync:from-local- Verify sync before commit/push:
npm run skill:sync:check- Optional repo -> local sync:
npm run skill:sync:to-localAuto-routing contract mirror workflow:
- Sync local -> repo mirror:
npm run routing:sync:from-local- Verify sync before commit/push:
npm run routing:sync:check- Optional repo -> local sync:
npm run routing:sync:to-localQuick check:
curl http://127.0.0.1:4678/health- Core onboarding and dual-mode entrypoint: README.md
- Enhanced deep runbook: README-debug.md
- Mode-gated AI workflow policy: AGENTS.md