ghost-qa 1.3.2 β†’ 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +77 -24
  2. package/SKILL.md +78 -77
  3. package/dist/bin/ghost-qa.d.ts +10 -2
  4. package/dist/bin/ghost-qa.d.ts.map +1 -1
  5. package/dist/bin/ghost-qa.js +106 -16
  6. package/dist/bin/ghost-qa.js.map +1 -1
  7. package/dist/src/engine/audit-runner.d.ts +6 -5
  8. package/dist/src/engine/audit-runner.d.ts.map +1 -1
  9. package/dist/src/engine/audit-runner.js +117 -60
  10. package/dist/src/engine/audit-runner.js.map +1 -1
  11. package/dist/src/engine/browser-session.d.ts +3 -3
  12. package/dist/src/engine/browser-session.d.ts.map +1 -1
  13. package/dist/src/engine/browser-session.js +18 -7
  14. package/dist/src/engine/browser-session.js.map +1 -1
  15. package/dist/src/engine/compare.d.ts +37 -0
  16. package/dist/src/engine/compare.d.ts.map +1 -0
  17. package/dist/src/engine/compare.js +63 -0
  18. package/dist/src/engine/compare.js.map +1 -0
  19. package/dist/src/engine/health-score.d.ts +14 -0
  20. package/dist/src/engine/health-score.d.ts.map +1 -0
  21. package/dist/src/engine/health-score.js +74 -0
  22. package/dist/src/engine/health-score.js.map +1 -0
  23. package/dist/src/engine/version.d.ts +14 -0
  24. package/dist/src/engine/version.d.ts.map +1 -0
  25. package/dist/src/engine/version.js +43 -0
  26. package/dist/src/engine/version.js.map +1 -0
  27. package/dist/src/index.d.ts +6 -0
  28. package/dist/src/index.d.ts.map +1 -1
  29. package/dist/src/index.js +6 -0
  30. package/dist/src/index.js.map +1 -1
  31. package/dist/src/mcp/server.d.ts +24 -4
  32. package/dist/src/mcp/server.d.ts.map +1 -1
  33. package/dist/src/mcp/server.js +43 -5
  34. package/dist/src/mcp/server.js.map +1 -1
  35. package/dist/src/reporter/agent-diagnostic.d.ts +6 -0
  36. package/dist/src/reporter/agent-diagnostic.d.ts.map +1 -1
  37. package/dist/src/reporter/agent-diagnostic.js +52 -2
  38. package/dist/src/reporter/agent-diagnostic.js.map +1 -1
  39. package/dist/src/reporter/html-report.d.ts.map +1 -1
  40. package/dist/src/reporter/html-report.js +79 -4
  41. package/dist/src/reporter/html-report.js.map +1 -1
  42. package/dist/src/reporter/terminal-summary.d.ts.map +1 -1
  43. package/dist/src/reporter/terminal-summary.js +6 -0
  44. package/dist/src/reporter/terminal-summary.js.map +1 -1
  45. package/dist/src/traps/a11y-trap.d.ts +23 -0
  46. package/dist/src/traps/a11y-trap.d.ts.map +1 -1
  47. package/dist/src/traps/a11y-trap.js +185 -0
  48. package/dist/src/traps/a11y-trap.js.map +1 -1
  49. package/dist/src/traps/console-trap.d.ts +3 -1
  50. package/dist/src/traps/console-trap.d.ts.map +1 -1
  51. package/dist/src/traps/console-trap.js +41 -0
  52. package/dist/src/traps/console-trap.js.map +1 -1
  53. package/dist/src/traps/layout-trap.d.ts +31 -0
  54. package/dist/src/traps/layout-trap.d.ts.map +1 -1
  55. package/dist/src/traps/layout-trap.js +173 -0
  56. package/dist/src/traps/layout-trap.js.map +1 -1
  57. package/dist/src/traps/links-trap.d.ts +34 -0
  58. package/dist/src/traps/links-trap.d.ts.map +1 -0
  59. package/dist/src/traps/links-trap.js +136 -0
  60. package/dist/src/traps/links-trap.js.map +1 -0
  61. package/dist/src/traps/network-trap.d.ts +4 -1
  62. package/dist/src/traps/network-trap.d.ts.map +1 -1
  63. package/dist/src/traps/network-trap.js +29 -2
  64. package/dist/src/traps/network-trap.js.map +1 -1
  65. package/dist/src/traps/perf-trap.d.ts +18 -0
  66. package/dist/src/traps/perf-trap.d.ts.map +1 -1
  67. package/dist/src/traps/perf-trap.js +148 -8
  68. package/dist/src/traps/perf-trap.js.map +1 -1
  69. package/dist/src/traps/seo-trap.d.ts +30 -0
  70. package/dist/src/traps/seo-trap.d.ts.map +1 -0
  71. package/dist/src/traps/seo-trap.js +98 -0
  72. package/dist/src/traps/seo-trap.js.map +1 -0
  73. package/dist/src/traps/theme-trap.d.ts +32 -0
  74. package/dist/src/traps/theme-trap.d.ts.map +1 -0
  75. package/dist/src/traps/theme-trap.js +109 -0
  76. package/dist/src/traps/theme-trap.js.map +1 -0
  77. package/dist/src/types.d.ts +55 -3
  78. package/dist/src/types.d.ts.map +1 -1
  79. package/dist/src/types.js +30 -2
  80. package/dist/src/types.js.map +1 -1
  81. package/package.json +11 -3
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # πŸ‘» ghost-qa
2
2
 
3
- **Autonomous headless browser QA & self-healing verification loop for coding agents.**
3
+ **Autonomous headless browser QA & self-healing verification loop for coding agents.** `v2.0.0` β€” the 8-Trap Deep Browser Inspection Engine: 3 viewports Γ— light/dark, QA Health Score (A+…F), interactive HTML dashboard, and regression diffing.
4
4
 
5
5
  [![CI](https://github.com/avivgerz-hue/ghost-qa/actions/workflows/ci.yml/badge.svg)](https://github.com/avivgerz-hue/ghost-qa/actions/workflows/ci.yml)
6
6
  [![npm version](https://img.shields.io/npm/v/ghost-qa.svg)](https://www.npmjs.com/package/ghost-qa)
@@ -66,60 +66,107 @@ npx -y ghost-qa init
66
66
  β”‚ β–Ό β–Ό β”‚
67
67
  β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
68
68
  β”‚ β”‚ CONSOLE β”‚ β”‚ NETWORK β”‚ β”‚ LAYOUT β”‚ β”‚
69
- β”‚ β”‚ A11Y β”‚ β”‚ PERF β”‚ β”‚ 5 TRAPS β”‚ β”‚
69
+ β”‚ β”‚ A11Y β”‚ β”‚ PERF β”‚ β”‚ 8 TRAPS β”‚ β”‚
70
70
  β”‚ β”‚ TRAP β”‚ β”‚ TRAP β”‚ β”‚ TRAP β”‚ β”‚
71
71
  β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
72
- β”‚ Desktop 1440Γ—900 + Mobile 390Γ—844 (iPhone) β”‚
72
+ β”‚ Desktop 1440Γ—900 Β· Tablet 768Γ—1024 Β· Mobile 375Γ—812 β”‚
73
73
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
74
74
  β”‚
75
75
  fix bugs β”€β”€β”€β”€β”€β”€β”€β”˜ re-run until βœ” PASS
76
76
  ```
77
77
 
78
78
  1. The agent writes code and starts the dev server.
79
- 2. `ghost-qa test` crawls every internal route on **desktop + mobile**, exercising interactive controls.
80
- 3. Five traps capture everything the browser actually experienced.
81
- 4. Failures return as a token-efficient diagnostic; the agent fixes the root causes and re-runs.
82
- 5. The loop ends only at **PASS** β€” that's when the agent may tell you it's done.
79
+ 2. `ghost-qa test` crawls every internal route on **Desktop 1440Γ—900, Tablet 768Γ—1024 and Mobile 375Γ—812**, in **light + dark** colour schemes, exercising interactive controls.
80
+ 3. Eight traps capture everything the browser actually experienced, scored into a deterministic **QA Health Score (0–100, Grade A+…F)**.
81
+ 4. Failures return as a token-efficient diagnostic (`GHOST-QA-REPORT.md` + `PATCH-PROMPT.md` with exact selectors); the agent fixes root causes and re-runs.
82
+ 5. `ghost-qa compare before.json after.json` proves the fix: the loop ends only at **score 95–100 (A+)**, zero critical/major remaining, and **zero new regressions**.
83
83
 
84
84
  ---
85
85
 
86
- ## πŸͺ€ The 5-Trap Engine
86
+ ## πŸͺ€ The 8-Trap Deep Browser Inspection Engine *(v2.0.0)*
87
87
 
88
- ### 1. Console Trap β€” `src/traps/console-trap.ts`
88
+ ### 1. Console & Framework Runtime Trap β€” `src/traps/console-trap.ts`
89
89
  - Uncaught `pageerror` exceptions with stack traces
90
90
  - Unhandled promise rejections
91
91
  - **React hydration mismatches** ("Text content did not match", "A tree hydrated but…")
92
+ - **Duplicate-key warnings** and **Content-Security-Policy violations** *(new in v2)*
92
93
  - `console.error` (major) and `console.warning` (minor) β€” with dev-server noise (`[vite]`, HMR, React DevTools banners) filtered out
93
94
 
94
- ### 2. Network Trap β€” `src/traps/network-trap.ts`
95
+ ### 2. Network & Asset Integrity Trap β€” `src/traps/network-trap.ts`
95
96
  - HTTP `5xx` API crashes (critical) and `4xx` responses (major)
96
- - Failed `fetch`/`XHR` requests and connection failures
97
- - **CORS-blocked requests** with remediation guidance
98
- - Broken static assets (JS/CSS/images/fonts) and missing favicons (minor)
97
+ - Failed `fetch`/`XHR` requests, **timed-out requests**, and connection failures
98
+ - **CORS-blocked requests and failed CORS preflights** with remediation guidance
99
+ - Broken static assets, broken images (`naturalWidth === 0`), **broken inline SVGs (0Γ—0)**, **>500KB unoptimized payloads**, and missing favicons (minor)
99
100
 
100
- ### 3. Layout Trap β€” `src/traps/layout-trap.ts`
101
+ ### 3. Layout, Responsive Geometry & Collision Trap β€” `src/traps/layout-trap.ts`
101
102
  - **Horizontal overflow**: `scrollWidth > innerWidth`, with the offending elements named (critical on mobile)
103
+ - **Overlapping interactive elements** via bounding-box collision math, with exact selectors + boxes *(new in v2)*
104
+ - **Touch targets < 44Γ—44px** on touch viewports (WCAG 2.5.5 / Apple HIG), **clipped text**, and **off-screen interactives** *(new in v2)*
102
105
  - Zero-dimension interactive elements β€” buttons rendered at 0Γ—0 that no human could tap
103
- - Broken images (`naturalWidth === 0`)
104
106
  - Missing `<meta name="viewport">` on mobile
105
107
 
106
- ### 4. Accessibility Trap β€” `src/traps/a11y-trap.ts` *(new in v1.1.0)*
108
+ ### 4. Accessibility (WCAG 2.1 AA) & Keyboard Focus Trap β€” `src/traps/a11y-trap.ts`
107
109
  - Buttons and links with **no accessible name** (icon-only controls screen readers can't identify)
108
110
  - Images **missing `alt`** attributes (descriptive alt, or `alt=""` for decorative)
109
111
  - Form inputs with **no associated label** β€” a placeholder is not a label
112
+ - **Real computed contrast ratios** (`getComputedStyle` foreground vs effective background, WCAG formula) *(new in v2)*
113
+ - **Heading hierarchy** (missing `<h1>`, h1β†’h3 skips) and **automated Tab-order verification** β€” simulated Tab presses catch invisible or dead focus states *(new in v2)*
110
114
  - Missing document `<title>` and missing `<html lang>`
111
115
 
112
- ### 5. Performance & Asset Trap β€” `src/traps/perf-trap.ts` *(new in v1.1.0)*
116
+ ### 5. Performance & Core Web Vitals Trap β€” `src/traps/perf-trap.ts`
117
+ - **Core Web Vitals**: TTFB, FCP, LCP estimation, and CLS (Cumulative Layout Shift) *(new in v2)*
113
118
  - Slow page loads via Navigation Timing (DOMContentLoaded / load budgets, 2Γ— = critical)
114
- - **Oversized resources** (> 1MB single asset) and excessive total payload (> 3MB)
119
+ - **Oversized resources** (> 1MB single asset), **unoptimized >500KB images/scripts**, and excessive total payload (> 3MB)
115
120
  - Main-thread jank / layout-thrashing indicators from the Long Tasks API
116
- - Render-blocking `<head>` resources and excessive DOM size
121
+ - Render-blocking `<head>` resources, excessive DOM size (>1500 nodes) and **DOM depth > 32**
122
+
123
+ ### 6. Safe Interactive & Link Integrity Trap β€” `src/traps/links-trap.ts` *(new in v2)*
124
+ - Placeholder links (`href=""`, `href="#"`, `javascript:void(0)`) and **dead anchors/routes** found during crawling
125
+ - Buttons inside `<form>` with **no `type`** (they silently become submit buttons)
126
+ - Disabled/stuck interactive controls β€” all observational, this trap never clicks anything
127
+
128
+ ### 7. SEO, Metadata & Social Graph Trap β€” `src/traps/seo-trap.ts` *(new in v2)*
129
+ - `<title>` (missing, <10 or >60 chars), meta description, `<html lang>`, viewport meta, canonical tag
130
+ - OpenGraph set (`og:title`, `og:description`, `og:image`) for link unfurls
131
+ - **Duplicate `id` attributes** in the live, post-hydration DOM
132
+
133
+ ### 8. Dark / Light Theme Emulation Trap β€” `src/traps/theme-trap.ts` *(new in v2)*
134
+ - Every page also renders under `colorScheme: 'dark'` and `'light'` emulation
135
+ - Computed contrast is re-evaluated per scheme β€” invisible dark-mode text (dark-on-dark) is caught automatically and tagged with the failing scheme
117
136
 
118
137
  Plus a **safety-first Interaction Runner**: it fills forms with inert data (`ghost-qa@example.com`), opens tabs/modals/menus, and clicks ordinary buttons β€” but *never* destructive ones (`delete`, `checkout`, `pay`, `logout`, `publish`… are blocked by a tested safety gate).
119
138
 
120
139
  ---
121
140
 
122
- ## πŸ”Œ Native MCP Server *(new in v1.1.0)*
141
+ ## πŸ“Š QA Health Score, Artifacts & Interactive Dashboard *(new in v2)*
142
+
143
+ Every run computes a deterministic **QA Health Score (0–100)** and **Letter Grade (A+ … F)**: each trap starts at 100 and loses 25 per critical, 10 per major, 3 per minor finding; the overall score is the mean of the eight trap sub-scores (Console, Network, Layout, A11y, Performance, Links/UX, SEO/DOM, Theme Parity).
144
+
145
+ ```bash
146
+ npx -y ghost-qa test http://localhost:3000 --out-dir ghost-qa-out --screenshots
147
+ ```
148
+
149
+ | Artifact | Contents |
150
+ | --- | --- |
151
+ | `report.json` | Complete machine-readable telemetry: per-trap scores, viewport matrices, exact DOM selectors (`#id`, `data-testid`, CSS path) and bounding boxes |
152
+ | `GHOST-QA-REPORT.md` | Human + agent Self-Healing Bug Report with root-cause analysis and the fix playbook |
153
+ | `PATCH-PROMPT.md` | Copy-paste remediation prompt: every finding with selector, bounding box, parent-component hints and the compare loop |
154
+ | `report.html` | Self-contained, zero-dependency, dark-mode **interactive QA Dashboard**: Grade hero (A+…F), 8-Trap Scorecard, Route & Viewport Matrix, filterable findings (severity/trap/viewport), embedded screenshots when captured |
155
+
156
+ ## πŸ”€ Regression Diffing β€” `ghost-qa compare` / `ghost_qa_compare` *(new in v2)*
157
+
158
+ ```bash
159
+ npx -y ghost-qa test http://localhost:3000 --json > before.json # baseline
160
+ # …agent fixes the bugs…
161
+ npx -y ghost-qa test http://localhost:3000 --json > after.json # re-audit
162
+ npx -y ghost-qa compare before.json after.json # Regression & Verification Delta Report
163
+ ```
164
+
165
+ The delta matches findings by stable fingerprint id and reports **`scoreDelta`, `fixedFindings`, `newRegressions`, `remainingFindings`** β€” so a coding agent can *prove* its fix resolved the bug without introducing regressions. `verified` requires score β‰₯ 95, zero regressions and no blocking findings left. Also available as the `ghost_qa_compare` MCP tool.
166
+
167
+ ---
168
+
169
+ ## πŸ”Œ Native MCP Server
123
170
 
124
171
  ghost-qa ships a zero-dependency **Model Context Protocol** server (JSON-RPC 2.0 over stdio), so MCP hosts can invoke browser verification as a native tool instead of shelling out:
125
172
 
@@ -129,7 +176,8 @@ npx -y ghost-qa mcp
129
176
 
130
177
  | MCP tool | What it does |
131
178
  | --- | --- |
132
- | `ghost_qa_audit_url` | Runs the full crawl + 5-trap suite against a running URL and returns the Self-Healing Bug Report (text + structured content) |
179
+ | `ghost_qa_audit_url` | Runs the full 8-trap deep inspection (3 viewports Γ— light/dark) and returns the Self-Healing Bug Report + QA Health Score (structured content includes the full report for baselining) |
180
+ | `ghost_qa_compare` | *(new in v2)* Diffs two report JSONs into the Regression & Verification Delta Report (`scoreDelta`, `fixedFindings`, `newRegressions`, `remainingFindings`) |
133
181
  | `ghost_qa_doctor` | Verifies Node, Chromium availability, and runs a live browser smoke test |
134
182
 
135
183
  `npx -y ghost-qa init` writes the ready-to-use `.mcp.json` entry for you (merging with any servers you already have):
@@ -166,7 +214,7 @@ Pair it with `--html ghost-qa-report.html` for a self-contained, dark-mode **vis
166
214
  ```
167
215
  πŸ‘» ghost-qa β€” autonomous browser verification
168
216
  Target: http://localhost:3000/
169
- Duration: 8.4s Β· Viewports: desktop + mobile Β· Depth: 2
217
+ Duration: 14.2s Β· Viewports: desktop + tablet + mobile Β· Schemes: light + dark Β· Depth: 2
170
218
 
171
219
  Routes crawled
172
220
  / Home [200] 3 issues
@@ -177,6 +225,7 @@ Coverage
177
225
  Routes visited: 3
178
226
  Interactions tested: 21 passed Β· 1 failed Β· 4 skipped (safety)
179
227
  Issues: 5 total β€” 2 critical, 3 major, 0 minor
228
+ QA Health Score: 62/100 β€” Grade D (8 traps Β· per-trap: console 65 Β· network 75 Β· layout 90 Β· a11y 100 Β· perf 100 Β· links 100 Β· seo 100 Β· theme 65)
180
229
 
181
230
  Failures caught
182
231
  βœ– CRITICAL [console] React hydration mismatch: Text content did not match…
@@ -199,7 +248,8 @@ The agent-facing report (`--report ghost-qa-report.md`) groups the same bugs by
199
248
  | --- | --- |
200
249
  | `ghost-qa test <url>` | Crawl a running app and trap browser failures. Exit `0` = PASS, `1` = blocking issues, `2` = runner error |
201
250
  | `ghost-qa init [--force]` | Install `.claude/skills/ghost-qa/SKILL.md`, verification protocol (`CLAUDE.md`, `AGENTS.md`, `.cursorrules`) + MCP config (`.mcp.json`) β€” all idempotent |
202
- | `ghost-qa mcp` | Run the native MCP server (JSON-RPC 2.0 over stdio) exposing `ghost_qa_audit_url` and `ghost_qa_doctor` |
251
+ | `ghost-qa compare <before.json> <after.json>` | Regression & Verification Delta Report between two report JSONs. Exit `1` if new regressions appeared |
252
+ | `ghost-qa mcp` | Run the native MCP server (JSON-RPC 2.0 over stdio) exposing `ghost_qa_audit_url`, `ghost_qa_compare` and `ghost_qa_doctor` |
203
253
  | `ghost-qa doctor` | Diagnose Node β‰₯ 20, Playwright and Chromium setup, with a live browser smoke test |
204
254
  | `ghost-qa --version` / `--help` | Version / usage |
205
255
 
@@ -210,7 +260,10 @@ The agent-facing report (`--report ghost-qa-report.md`) groups the same bugs by
210
260
  | `--max-depth <n>` | `2` | Link-following depth from the start URL |
211
261
  | `--max-routes <n>` | `25` | Maximum routes to visit |
212
262
  | `--timeout <ms>` | `15000` | Per-navigation timeout |
213
- | `--viewport <name>` | `both` | `both` \| `desktop` \| `mobile` |
263
+ | `--viewport <name>` | `all` | `all` \| `both` (desktop+mobile) \| `desktop` \| `tablet` \| `mobile` |
264
+ | `--color-scheme <name>` | `both` | `both` \| `light` \| `dark` β€” colour schemes emulated per viewport |
265
+ | `--screenshots` | off | Capture a screenshot per route/viewport for the HTML dashboard |
266
+ | `--out-dir <dir>` | β€” | Write `report.json` + `GHOST-QA-REPORT.md` + `PATCH-PROMPT.md` + `report.html` into this directory |
214
267
  | `--no-interactions` | off | Load pages only; don't click or fill anything |
215
268
  | `--headed` | off | Show the browser window (debugging) |
216
269
  | `--fail-on <severity>` | `major` | Exit 1 on `critical` \| `major` \| `minor` issues |
package/SKILL.md CHANGED
@@ -1,18 +1,16 @@
1
1
  ---
2
2
  name: ghost-qa
3
- description: Verify frontend work in a real headless browser before reporting a task complete. Use after building or changing any UI, route, form, API integration, or client-side logic β€” crawls the running app on desktop and mobile, runs a 5-trap engine (console/hydration, network, layout, accessibility, performance), exercises interactive controls, and returns a self-healing bug report to fix from. Also usable via the ghost_qa_audit_url MCP tool.
3
+ description: Verify frontend work in a real headless browser before reporting a task complete. The autonomous Staff QA Engineer protocol β€” doctor readiness, multi-viewport 8-Trap baseline audit (Desktop/Tablet/Mobile, light + dark), DOM-to-source root-cause mapping, surgical remediation, and closed-loop delta verification with ghost_qa_compare until QA Health Score is 95–100 (Grade A+). Use after building or changing any UI, route, form, API integration, or client-side logic.
4
4
  license: MIT
5
5
  ---
6
6
 
7
- # πŸ‘» ghost-qa β€” Verify in Browser Before Done
7
+ # πŸ‘» ghost-qa β€” Autonomous Staff QA Engineer Protocol
8
8
 
9
- Coding agents write code blind. Code that type-checks can still ship with React hydration mismatches, uncaught exceptions, 500ing APIs, dead buttons, icon-only controls no screen reader can name, and mobile layouts that scroll sideways. **The browser is the source of truth β€” never your mental model of the DOM.**
9
+ Coding agents write code blind. Code that type-checks can still ship with React hydration mismatches, uncaught exceptions, 500ing APIs, dead links, invisible dark-mode text, 30px tap targets, and mobile layouts that scroll sideways. **The browser is the source of truth β€” never your mental model of the DOM.**
10
10
 
11
- ## The Rule
11
+ > **The Rule:** Before reporting ANY task that touches frontend code as complete, you MUST execute all five phases below, in order, and finish with a verified delta: QA Health Score 95–100 (Grade A+ band), zero critical/major findings, zero new regressions.
12
12
 
13
- > Before reporting ANY task that touches frontend code as complete, you MUST run the app in a real browser with ghost-qa, fix everything blocking it catches, and re-run until it passes.
14
-
15
- Unit tests, type-checking, linting and code review do **not** satisfy this rule. They cannot see hydration, layout, network or accessibility failures.
13
+ Unit tests, type-checking, linting and code review do **not** satisfy this rule. They cannot see hydration, layout, network, contrast or focus failures.
16
14
 
17
15
  ## When to use this skill
18
16
 
@@ -20,88 +18,91 @@ Unit tests, type-checking, linting and code review do **not** satisfy this rule.
20
18
  - βœ… You fixed a bug that manifested in the browser
21
19
  - βœ… You are about to tell the user a UI task is "done"
22
20
 
23
- **Not a substitute for:** your unit/E2E test suites, a full WCAG accessibility audit (ghost-qa's a11y trap covers common machine-checkable failures, not full WCAG conformance), load testing, or manual exploratory QA.
21
+ **Not a substitute for:** your unit/E2E suites, a full manual WCAG audit (the a11y trap covers machine-checkable WCAG 2.1 AA failures), load testing, or exploratory QA.
24
22
 
25
- ## Choose your path
23
+ ## The 8-Trap Deep Browser Inspection Engine
26
24
 
27
- | Situation | Command |
28
- | --- | --- |
29
- | Dev server already running | `npx -y ghost-qa test <url>` |
30
- | Server not running (most common) | `npx -y ghost-qa test <url> --server-cmd "npm run dev"` β€” ghost-qa spawns it, waits for it, audits, and kills the process tree afterward |
31
- | Your host exposes MCP tools | Call **`ghost_qa_audit_url`** with the URL (call `ghost_qa_doctor` first if it errors) β€” identical engine, identical report |
32
- | Mobile-only bug hunt | add `--viewport mobile` |
33
- | Large app | add `--max-depth 3 --max-routes 50` |
34
- | Evidence for a PR/CI | add `--report ghost-qa-report.md --html ghost-qa-report.html` |
25
+ Every audit crawls each route on **Desktop 1440Γ—900, Tablet 768Γ—1024 and Mobile 375Γ—812**, under **light + dark** colour schemes:
35
26
 
36
- > All commands use the published npm package (`npx -y ghost-qa …`). If npm is unavailable, `npx -y github:avivgerz-hue/ghost-qa …` runs the identical CLI straight from GitHub.
27
+ | # | Trap | What it catches |
28
+ | --- | --- | --- |
29
+ | 1 | Console & Framework Runtime | `pageerror`, `console.error`, unhandled rejections, React/Next.js hydration mismatches, duplicate-key warnings, CSP violations |
30
+ | 2 | Network & Asset Integrity | 4xx/5xx, timed-out/aborted requests, failed CORS preflights, broken images (`naturalWidth === 0`), broken inline SVGs (0Γ—0), >500KB unoptimized payloads |
31
+ | 3 | Layout, Responsive Geometry & Collision | Horizontal overflow, overlapping interactive elements (bounding-box collision math), <44Γ—44px touch targets, clipped text, off-screen interactives |
32
+ | 4 | Accessibility (WCAG 2.1 AA) & Keyboard Focus | Missing accessible names/labels/alt, heading hierarchy breaks, real computed contrast ratios, automated Tab-order verification (invisible/dead focus) |
33
+ | 5 | Performance & Core Web Vitals | TTFB, FCP, LCP, CLS, DOM bloat (>1500 nodes), DOM depth (>32), render-blocking scripts, long tasks |
34
+ | 6 | Safe Interactive & Link Integrity | Placeholder hrefs (`""`, `#`, `javascript:void(0)`), dead anchors/routes, in-form buttons without `type`, stuck disabled controls |
35
+ | 7 | SEO, Metadata & Social Graph | Title length, meta description, `<html lang>`, viewport meta, canonical, OpenGraph set, duplicate `id`s |
36
+ | 8 | Dark / Light Theme Emulation | Contrast/visibility recomputed under `colorScheme: light` and `dark` β€” catches invisible dark-mode text |
37
37
 
38
- Common local URLs: Next.js / CRA `http://localhost:3000`, Vite `http://localhost:5173`, Astro `http://localhost:4321`, Angular `http://localhost:4200`. If unsure, check the dev server output or `package.json` scripts β€” never guess silently; state the URL you verified in your completion message.
38
+ Scoring is deterministic: each trap starts at 100, βˆ’25 per critical, βˆ’10 per major, βˆ’3 per minor. The **QA Health Score** is the mean of the 8 trap scores, graded **A+ (97+) … F (<60)**.
39
39
 
40
- ## The Self-Healing Loop
40
+ ---
41
41
 
42
- 1. **Run the audit** (path table above). The 5-Trap Engine checks, on Desktop 1440Γ—900 *and* Mobile 390Γ—844:
43
- - **Console** β€” uncaught errors, unhandled promise rejections, React hydration mismatches, `console.error`
44
- - **Network** β€” HTTP 4xx/5xx, failed fetch/XHR, CORS failures, broken assets
45
- - **Layout** β€” horizontal overflow, zero-size interactive elements, broken images, missing viewport meta
46
- - **Accessibility** β€” buttons/links with no accessible name, images missing `alt`, inputs with no label, missing `<title>` / `<html lang>`
47
- - **Performance** β€” slow loads, oversized assets/payloads, main-thread long-task jank, render-blocking resources, excessive DOM
48
- 2. **Read the Self-Healing Bug Report.** Every issue has a stable `#id`, a severity (`critical` / `major` / `minor`), the route, and the viewport. Fix **critical and major** issues. Note minors; fix them when cheap.
49
- 3. **Fix root causes in source** (fix guidance below). Reference issues by `#id` in your own narration so the user can follow along.
50
- 4. **Re-run the identical command.** A fix that breaks a different route or viewport only shows up on re-run.
51
- 5. **Repeat until `GHOST-QA PASS`.** If you have looped 5 times on the same `#id`, stop and report to the user what is stuck and why β€” do not silently give up or declare success.
52
- 6. **Only then** report completion, using the completion template below.
42
+ ## Phase 1 β€” Environment & Server Readiness (`ghost_qa_doctor`)
53
43
 
54
- ## Fix guidance per trap
44
+ 1. Call the **`ghost_qa_doctor`** MCP tool, or run `npx -y ghost-qa doctor`.
45
+ 2. It must report **READY**: Node β‰₯ 20, Chromium installed, live browser smoke test passing.
46
+ 3. If Chromium is missing: `npx playwright install chromium` (one-time), then re-run doctor. **Never skip to Phase 2 on a red doctor** β€” a failed launch is not a passing audit.
47
+ 4. Start the app (`npm run dev`) or plan to use `--server-cmd "npm run dev"` / let the audit spawn it.
55
48
 
56
- | Trap | Typical root causes | Fix like this |
57
- | --- | --- | --- |
58
- | Hydration mismatch | `Date.now()`/`Math.random()`/`window` during render, server/client branching, invalid HTML nesting (`<p>` in `<p>`, `<div>` in `<p>`) | Make server and client render identical markup; move time/random/client-only values into `useEffect` + state; fix the nesting |
59
- | Uncaught page error | undefined data, missing null checks on async data, bad imports | Reproduce via the stack trace in the report; guard the actual data path |
60
- | Console error | failed state updates, rejected promises, React warnings treated seriously by the app | Trace the first error, not the cascade after it |
61
- | HTTP 5xx | API route crash, bad env var, DB down | Read the server logs for that endpoint; the browser found it, the fix is server-side |
62
- | HTTP 404 / broken asset | wrong path, case-sensitivity, asset not emitted by the build | Compare the URL in the report with the actual build output / public dir |
63
- | CORS failure | API missing `Access-Control-Allow-Origin` for the page origin | Fix the API's CORS config (or the dev proxy), not the fetch call |
64
- | Horizontal overflow | `100vw` + scrollbar, fixed-width children, flex/grid children without `min-width: 0` | Constrain widths (`max-width: 100%`, `min-width: 0`, `overflow-wrap`); the report names the offending elements |
65
- | Zero-size interactive | collapsed CSS, `display: contents` misuse, content that never rendered | Restore a real, tappable size (β‰₯ 24px, ideally β‰₯ 40px on mobile) |
66
- | No accessible name | icon-only `<button>`/`<a>` | Add visible text or `aria-label` describing the action/destination |
67
- | Missing `alt` | forgotten attribute | Descriptive alt; `alt=""` only if purely decorative |
68
- | Input without label | placeholder used as label | Real `<label for>`, wrapping `<label>`, or `aria-label` |
69
- | Slow load / oversized asset | unoptimized images, giant bundles, blocking scripts | Compress/lazy-load, `defer`/`async`, code-split; check the named resource first |
70
- | Long-task jank | heavy sync JS, layout reads in loops after writes | Break up work, memoize, batch DOM reads before writes |
71
-
72
- ## Anti-cheating rules (this is the point of the skill)
73
-
74
- - ❌ Never silence the checker: no deleting the failing UI, no blanket `try/catch`, no `suppressHydrationWarning`, no removing the code path "so the error goes away"
75
- - ❌ Never use `--no-interactions` or narrow `--viewport`/`--max-depth` to hide failures (legitimate only when a page has side-effectful controls, and you must say so)
76
- - ❌ Never edit ghost-qa's report, thresholds, or your project's ghost-qa invocation to manufacture a PASS
77
- - βœ… If a finding is a genuine false positive, say so explicitly in your completion message with the `#id` and why β€” a human can overrule the tool; you may not quietly ignore it
78
-
79
- ## Safety guarantees you can rely on
80
-
81
- ghost-qa never clicks destructive controls (delete, checkout, pay, logout, publish, sign-in…), never submits real orders/payments, fills forms only with inert data (`ghost-qa@example.com`, `ghost-qa test`), stays on same-origin links, and is designed for localhost/dev servers. **Do not point it at production systems you do not own or have permission to test.** Pages behind authentication will typically redirect to a login page β€” ghost-qa will audit what an anonymous visitor sees; say so if that's what happened.
49
+ ## Phase 2 β€” Multi-Viewport 8-Trap Baseline Audit (`ghost_qa_audit_url`)
82
50
 
83
- ## Troubleshooting
51
+ Run the baseline BEFORE changing code (or before your fix, when debugging):
84
52
 
85
- | Symptom | Do this |
86
- | --- | --- |
87
- | "could not launch Chromium" | `npx playwright install chromium` (one-time), then `npx -y ghost-qa doctor` |
88
- | `navigation-failed` on every route | Server isn't on that URL/port β€” start it, or re-run with `--server-cmd "npm run dev"` |
89
- | Everything 404s | Wrong port or base path β€” confirm the URL in a browser/`curl` yourself first |
90
- | Audit seems to test a login page | The app requires auth for those routes; report that limitation instead of claiming full verification |
91
- | Perf findings vary between runs | Machine load affects timings; re-run once before treating a borderline perf major as real |
92
- | MCP tool unavailable | Fall back to the CLI β€” the audit engine and report are identical |
53
+ - MCP: call **`ghost_qa_audit_url`** with the app URL. Save the full returned report JSON as **`before.json`**.
54
+ - CLI equivalent: `npx -y ghost-qa test <local-url> --out-dir ghost-qa-out` β†’ writes `report.json` (copy to `before.json`), `GHOST-QA-REPORT.md`, `PATCH-PROMPT.md`, and the interactive `report.html` dashboard. Add `--screenshots` for embedded route screenshots; `--server-cmd "npm run dev"` if the server isn't running.
55
+
56
+ Record the baseline: **QA Health Score, grade, per-trap scores, and every finding's `#id`.** Common local URLs: Next.js/CRA `http://localhost:3000`, Vite `http://localhost:5173`, Astro `http://localhost:4321`, Angular `http://localhost:4200`. Never guess silently β€” state the URL you verified.
57
+
58
+ ## Phase 3 β€” DOM-to-Source Root-Cause Mapping
59
+
60
+ For every critical/major finding, trace it back to the exact source component before editing:
93
61
 
94
- ## Completion template
62
+ - **Exact selectors:** findings carry `#id`, `[data-testid=…]`, or a CSS path, plus the live **bounding box**. Search the codebase for that id/testid/class or the element's visible text to find the React/Next.js/Vue/Svelte component that renders it.
63
+ - **Collisions/overflow:** the two colliding selectors + boxes tell you which siblings overlap β€” inspect their flex/grid/absolute layout in that component, on the failing viewport.
64
+ - **Console stacks:** follow the first app-owned stack frames to the throwing component/effect. Hydration mismatches mean server and client rendered different markup (Date/random/`window` at render, invalid nesting like `<p>` in `<p>`).
65
+ - **Dark-mode contrast:** a `theme-contrast` finding names the scheme that fails β€” find the hard-coded colour in that component and replace it with the theme token.
66
+ - **Network:** map the failing URL to its route handler/client fetch; 5xx is server code, CORS preflight is API config.
95
67
 
96
- When the final run passes, report completion like this:
68
+ Write the mapping down (finding `#id` β†’ file β†’ root cause) before Phase 4. If you cannot map a finding, say so β€” do not guess-fix.
97
69
 
98
- > βœ… Done. Verified in a real browser with ghost-qa: `npx -y ghost-qa test <url>` β†’ **GHOST-QA PASS**
99
- > Routes crawled: N Β· Interactions tested: N Β· Issues fixed this session: (list `#id`s, or "none found")
100
- > Stack: desktop 1440Γ—900 + mobile 390Γ—844, 5 traps (console, network, layout, accessibility, performance)
70
+ ## Phase 4 β€” Surgical Code Remediation
101
71
 
102
- ## Completion checklist
72
+ Fix root causes, one finding at a time, in severity order (critical β†’ major β†’ minor):
103
73
 
104
- - [ ] Final code state audited (not an earlier draft of the change)
105
- - [ ] All critical/major issues fixed at the root cause, or explicitly reported as false positives with reasoning
106
- - [ ] Final run prints `GHOST-QA PASS`
107
- - [ ] Completion message uses the template above and names the URL verified
74
+ - **Hydration:** identical server/client markup; defer client-only values to effects; fix invalid HTML nesting. Never `suppressHydrationWarning` to silence it.
75
+ - **Responsive geometry:** `min-width: 0` on flex/grid children, `max-width: 100%`, no `100vw` + scrollbar overflow, reserve image space with width/height or `aspect-ratio` (also fixes CLS).
76
+ - **Tap targets:** every touch target β‰₯ 44Γ—44px (padding or min-height/min-width).
77
+ - **ARIA/labels:** visible text or `aria-label` on icon controls, `<label for>` (or wrapping label) per input, `alt` on images (`alt=""` only if decorative), one `<h1>`, no heading level skips, visible `:focus-visible` rings β€” never `outline: none` without a replacement.
78
+ - **Dark-mode tokens:** CSS variables / `dark:` variants driven by `prefers-color-scheme` or the app theme β€” never hard-coded hex that only works in one scheme.
79
+ - **Links/forms:** real hrefs or `<button type="button">`; dead anchors get real targets; in-form buttons get explicit `type`.
80
+ - **Performance:** defer/async non-critical scripts, compress/resize/lazy-load >500KB assets, code-split, break up long tasks.
81
+
82
+ **Anti-cheating rules (absolute):** never delete failing UI, never loosen the checker, never hide elements from the traps, never stub network responses. Fixing the checker instead of the bug is a failed task.
83
+
84
+ ## Phase 5 β€” Closed-Loop Delta Verification (`ghost_qa_compare`)
85
+
86
+ 1. Re-run the identical audit (same URL/viewports) β†’ save as **`after.json`**.
87
+ 2. Compare: MCP **`ghost_qa_compare`** with `{ before, after }`, or `npx -y ghost-qa compare before.json after.json`.
88
+ 3. Read the **Regression & Verification Delta Report**: `scoreDelta`, `fixedFindings`, `newRegressions`, `remainingFindings`.
89
+ 4. **Done only when ALL hold:** QA Health Score **95–100 (Grade A+ band)** Β· zero critical/major remaining Β· **zero new regressions** (`verified: true`). Otherwise loop back to Phase 3 with the delta as your new worklist.
90
+ 5. If the same `#id` survives 5 loops, stop and report honestly what you tried β€” never declare success on a red delta.
91
+
92
+ ## Completion report (required format)
93
+
94
+ > βœ… Done. Verified in a real browser with ghost-qa: `ghost_qa_audit_url` on `<url>`
95
+ > Stack: Desktop 1440Γ—900 + Tablet 768Γ—1024 + Mobile 375Γ—812, light + dark, 8 traps
96
+ > QA Health Score: `<before>` β†’ `<after>` (Grade `<grade>`) Β· Delta: `<n>` fixed, 0 new regressions
97
+ > Routes crawled: `<n>` Β· Interactions tested: `<n>` Β· Artifacts: `report.json`, `GHOST-QA-REPORT.md`, `PATCH-PROMPT.md`, `report.html`
98
+
99
+ ## Troubleshooting
100
+
101
+ | Symptom | Fix |
102
+ | --- | --- |
103
+ | "could not launch Chromium" | `npx playwright install chromium` (one-time), then `npx -y ghost-qa doctor` |
104
+ | Navigation failures on every route | The dev server isn't running (or wrong port) β€” start it, or use `--server-cmd "npm run dev"` |
105
+ | Score stuck below 95 | Work the delta's remaining findings by severity; re-check Phase 3 mapping before editing |
106
+ | A trap flags a healthy page | File an issue with `report.json` attached β€” false positives are the most valuable bug reports |
107
+
108
+ > All commands use the published npm package (`npx -y ghost-qa …`). If npm is unavailable, `npx -y github:avivgerz-hue/ghost-qa …` runs the identical CLI straight from GitHub.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { type GhostQAOptions } from '../src/types.js';
3
- export declare const VERSION = "1.3.1";
4
- export declare const AGENT_PROTOCOL = "<!-- ghost-qa:start -->\n## \uD83D\uDC7B ghost-qa \u2014 Browser Verification Protocol (MANDATORY)\n\nBefore reporting any task that touches frontend code as complete, you MUST verify it in a real browser:\n\n1. Ensure the app is running locally (e.g. `npm run dev`).\n2. Run: `npx -y ghost-qa test <local-url>` (e.g. `npx -y ghost-qa test http://localhost:3000`) \u2014 or call the `ghost_qa_audit_url` MCP tool if your host exposes it. Add `--server-cmd \"npm run dev\"` to let ghost-qa manage the dev server itself.\n3. If ghost-qa reports ANY critical or major issue (hydration errors, console errors, 4xx/5xx responses, mobile overflow, accessibility or performance failures, broken interactions), fix the root cause in source and re-run.\n4. Repeat until ghost-qa prints **PASS**. Only then may you tell the user the task is done.\n\nNever declare a UI task finished based only on code review, type-checking, or unit tests. The browser is the source of truth.\n<!-- ghost-qa:end -->";
3
+ export declare const VERSION: string;
4
+ export declare const AGENT_PROTOCOL = "<!-- ghost-qa:start -->\n## \uD83D\uDC7B ghost-qa \u2014 Browser Verification Protocol (MANDATORY)\n\nBefore reporting any task that touches frontend code as complete, you MUST verify it in a real browser \u2014 the closed-loop Self-Healing Browser Verification Protocol:\n\n1. **Readiness:** run `ghost-qa doctor` (or the `ghost_qa_doctor` MCP tool). Do not proceed on red.\n2. **Baseline audit:** ensure the app runs locally, then `npx -y ghost-qa test <local-url> --out-dir ghost-qa-out` (add `--server-cmd \"npm run dev\"` to let ghost-qa manage the server) \u2014 or call `ghost_qa_audit_url`. This runs the 8-Trap Engine on Desktop 1440\u00D7900, Tablet 768\u00D71024 and Mobile 375\u00D7812, light + dark. Save the baseline as `before.json` (it is `ghost-qa-out/report.json`).\n3. **Root-cause mapping:** for every critical/major finding, map the exact DOM selector, bounding box, stack trace or dark-mode contrast failure back to the component file that renders it.\n4. **Surgical remediation:** fix root causes in source (hydration, overflow, tap targets, ARIA/labels, dark-mode tokens\u2026). Never silence the checker or delete failing UI.\n5. **Delta verification:** re-run the audit to `after.json`, then `npx -y ghost-qa compare before.json after.json` (or `ghost_qa_compare`). Repeat until QA Health Score is **95\u2013100 (A+)**, zero critical/major remain, and the delta shows **zero new regressions**. Only then report done, citing score, routes, viewports and the delta.\n\nNever declare a UI task finished based only on code review, type-checking, or unit tests. The browser is the source of truth.\n<!-- ghost-qa:end -->";
5
5
  export interface ParsedTestArgs {
6
6
  target: string;
7
7
  options: GhostQAOptions;
@@ -9,10 +9,18 @@ export interface ParsedTestArgs {
9
9
  quiet: boolean;
10
10
  reportFile?: string;
11
11
  htmlFile?: string;
12
+ outDir?: string;
12
13
  serverCmd?: string;
13
14
  serverTimeoutMs: number;
14
15
  }
15
16
  export declare function parseTestArgs(args: string[]): ParsedTestArgs;
17
+ export interface ParsedCompareArgs {
18
+ beforeFile: string;
19
+ afterFile: string;
20
+ json: boolean;
21
+ outFile?: string;
22
+ }
23
+ export declare function parseCompareArgs(args: string[]): ParsedCompareArgs;
16
24
  export declare function installSkill(targetDir: string, force?: boolean): Promise<Array<{
17
25
  file: string;
18
26
  action: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ghost-qa.d.ts","sourceRoot":"","sources":["../../bin/ghost-qa.ts"],"names":[],"mappings":";AAWA,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEvE,eAAO,MAAM,OAAO,UAAmB,CAAC;AAKxC,eAAO,MAAM,cAAc,i+BAWX,CAAC;AA4EjB,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,CA+E5D;AAyDD,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,KAAK,UAAQ,GACZ,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAqBlD;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,KAAK,UAAQ,GACZ,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAuCD,wBAAsB,IAAI,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoDxE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,GAAE,MAAwB,GAClC,OAAO,CAOT"}
1
+ {"version":3,"file":"ghost-qa.d.ts","sourceRoot":"","sources":["../../bin/ghost-qa.ts"],"names":[],"mappings":";AAYA,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEvE,eAAO,MAAM,OAAO,QAAmB,CAAC;AAKxC,eAAO,MAAM,cAAc,8mDAYX,CAAC;AAoFjB,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,CAgG5D;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAiBlE;AAiFD,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,KAAK,UAAQ,GACZ,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAqBlD;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,KAAK,UAAQ,GACZ,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAuCD,wBAAsB,IAAI,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiExE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,GAAE,MAAwB,GAClC,OAAO,CAOT"}