driftx 0.1.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.
@@ -0,0 +1,299 @@
1
+ ---
2
+ name: driftx
3
+ description: Visual comparison, accessibility audit, and layout regression for React Native and Android apps. Use when the user asks to compare their app against a design, check accessibility, detect visual regressions, inspect the component tree, or capture screenshots from a device/simulator.
4
+ ---
5
+
6
+ # driftx — Visual Analysis for React Native & Android
7
+
8
+ Use driftx when the user wants to:
9
+ - Compare their running app against a design image (Figma export, mockup, etc.)
10
+ - Run an accessibility audit on the component tree
11
+ - Detect layout regressions between builds
12
+ - Inspect the React Native component tree on a device
13
+ - Capture a screenshot from a running simulator/emulator
14
+
15
+ ## Prerequisites
16
+
17
+ driftx must be installed in the project: `npm install driftx` or available globally.
18
+ Run `npx driftx doctor` to verify the environment is set up correctly.
19
+
20
+ ## Commands Reference
21
+
22
+ ### `driftx compare` — Run visual analysis
23
+
24
+ The primary command. Compares a screenshot from a running device against a design image or baseline.
25
+
26
+ ```bash
27
+ # Compare against a design image
28
+ npx driftx compare --design path/to/design.png --format json
29
+
30
+ # Compare with specific device
31
+ npx driftx compare --design path/to/design.png --device "iPhone 16 Pro" --format json
32
+
33
+ # Use an existing screenshot instead of capturing
34
+ npx driftx compare --design path/to/design.png --screenshot path/to/screenshot.png --format json
35
+
36
+ # Run only specific analyses
37
+ npx driftx compare --design path/to/design.png --with pixel,a11y --format json
38
+
39
+ # Exclude specific analyses
40
+ npx driftx compare --design path/to/design.png --without pixel --format json
41
+
42
+ # Regression mode — compare against previous run (no design needed)
43
+ npx driftx compare --baseline --format json
44
+ ```
45
+
46
+ **Flags:**
47
+ | Flag | Description |
48
+ |------|-------------|
49
+ | `--design <path>` | Path to design image (PNG). Required unless `--baseline`. |
50
+ | `--screenshot <path>` | Use existing screenshot instead of capturing from device. |
51
+ | `-d, --device <id>` | Device ID or name to capture from. |
52
+ | `--threshold <n>` | Pixel sensitivity threshold (0-1, default 0.1). |
53
+ | `--with <analyses>` | Comma-separated analyses to run (e.g., `pixel,a11y,regression`). |
54
+ | `--without <analyses>` | Analyses to exclude. |
55
+ | `--baseline` | Compare against previous run's screenshot. |
56
+ | `--format json` | **Always use this** for structured output. |
57
+
58
+ **Available analyses:**
59
+ | Analysis | What it does | Auto-enabled when |
60
+ |----------|-------------|-------------------|
61
+ | `pixel` | Pixel-level diff between screenshot and design | Design image provided |
62
+ | `a11y` | Accessibility audit — missing labels, small tap targets, images without alt text | Component tree available (device connected) |
63
+ | `regression` | Layout regression — diff against previous run | `--baseline` flag used |
64
+
65
+ **Smart defaults:** When no `--with`/`--without` is specified, analyses auto-enable based on available inputs. You don't need to specify `--with` unless you want to override.
66
+
67
+ ### `driftx inspect` — Inspect component tree
68
+
69
+ ```bash
70
+ npx driftx inspect --format json
71
+ npx driftx inspect --device "Pixel 8" --format json
72
+ ```
73
+
74
+ Returns the React Native component tree with component names, testIDs, text content, and bounds.
75
+
76
+ ### `driftx devices` — List connected devices
77
+
78
+ ```bash
79
+ npx driftx devices --format json
80
+ ```
81
+
82
+ Returns available simulators/emulators and their state (booted/offline).
83
+
84
+ ### `driftx capture` — Capture screenshot
85
+
86
+ ```bash
87
+ npx driftx capture --output screenshot.png
88
+ npx driftx capture --device "iPhone 16 Pro" --output screenshot.png
89
+ ```
90
+
91
+ Captures a screenshot from the device and saves it to the specified path.
92
+
93
+ ### `driftx doctor` — Check prerequisites
94
+
95
+ ```bash
96
+ npx driftx doctor --format json
97
+ ```
98
+
99
+ Checks that adb, xcrun, Metro, etc. are available.
100
+
101
+ ## Output Interpretation
102
+
103
+ ### JSON format (CompareReport)
104
+
105
+ When using `--format json`, `driftx compare` outputs a `CompareReport`:
106
+
107
+ ```json
108
+ {
109
+ "report": {
110
+ "runId": "abc123",
111
+ "analyses": [
112
+ {
113
+ "analysisName": "pixel",
114
+ "findings": [...],
115
+ "summary": "Pixel diff: 2.100% — 3 regions (fail)",
116
+ "metadata": {
117
+ "diffPercentage": 2.1,
118
+ "diffPixels": 5000,
119
+ "totalPixels": 238000,
120
+ "regions": [...],
121
+ "passed": false
122
+ },
123
+ "durationMs": 450
124
+ },
125
+ {
126
+ "analysisName": "a11y",
127
+ "findings": [...],
128
+ "summary": "2 accessibility issues found",
129
+ "metadata": {
130
+ "totalChecked": 15,
131
+ "issuesByType": { "label": 1, "tapTarget": 1, "image": 0, "emptyText": 0 }
132
+ },
133
+ "durationMs": 5
134
+ }
135
+ ],
136
+ "findings": [...],
137
+ "summary": "...",
138
+ "durationMs": 460
139
+ },
140
+ "artifactDir": ".driftx/runs/abc123"
141
+ }
142
+ ```
143
+
144
+ Key fields to check:
145
+ - `report.analyses[].metadata.passed` — `false` means the analysis failed its threshold
146
+ - `report.analyses[].findings` — individual issues found
147
+ - `report.findings` — all findings merged across analyses
148
+ - `artifactDir` — where screenshots, diff masks, and region crops are saved
149
+
150
+ ### Artifacts
151
+
152
+ After a compare run, artifacts are saved to `.driftx/runs/<runId>/`:
153
+
154
+ | File | Description |
155
+ |------|-------------|
156
+ | `screenshot.png` | Captured screenshot |
157
+ | `design.png` | Copy of the design image |
158
+ | `diff-mask.png` | Visual overlay showing pixel differences |
159
+ | `regions/<id>.png` | Cropped images of each diff region |
160
+ | `regression-diff-mask.png` | Diff mask for regression analysis |
161
+ | `result.json` | Full CompareReport as JSON |
162
+ | `report.md` | Human-readable markdown report |
163
+
164
+ Read `report.md` for a formatted summary. Read `result.json` for structured data. View diff mask and region crops to understand what changed visually.
165
+
166
+ ### Finding categories
167
+
168
+ | Category | Source | Meaning |
169
+ |----------|--------|---------|
170
+ | `spacing`, `color`, `font`, `alignment`, `size`, `content`, `missing`, `extra` | pixel analysis | Visual differences between design and screenshot |
171
+ | `accessibility` | a11y analysis | Missing labels, small tap targets, images without alt text |
172
+ | `regression` | regression analysis | Layout changed from previous baseline |
173
+
174
+ ### Finding severity
175
+
176
+ - `critical` — major visual breakage
177
+ - `major` — noticeable difference (missing labels, significant pixel diff)
178
+ - `minor` — small issues (slightly small tap targets)
179
+ - `info` — informational (empty text nodes)
180
+
181
+ ## Workflow Patterns
182
+
183
+ ### Compare against a Figma design
184
+
185
+ If the user has a Figma MCP server connected, use it to export the frame as an image first, then run driftx:
186
+
187
+ 1. Use Figma MCP to get the design frame → save as PNG
188
+ 2. Run `npx driftx compare --design <saved-image-path> --format json`
189
+ 3. Read the JSON output to understand differences
190
+ 4. Read artifact files (diff mask, report.md) for visual context
191
+ 5. Suggest code fixes based on the findings
192
+
193
+ If no Figma MCP, ask the user to provide the design image path.
194
+
195
+ ### Accessibility audit
196
+
197
+ ```bash
198
+ npx driftx compare --design <path> --with a11y --format json
199
+ ```
200
+
201
+ Or without a design image (a11y only needs the component tree):
202
+ ```bash
203
+ npx driftx compare --baseline --with a11y --format json
204
+ ```
205
+
206
+ Review findings with `category: 'accessibility'` and suggest fixes (add accessibilityLabel, increase tap target size, etc.).
207
+
208
+ ### Regression detection
209
+
210
+ ```bash
211
+ npx driftx compare --baseline --format json
212
+ ```
213
+
214
+ Compares current app state against the most recent previous run. No design file needed. Useful after code changes to verify nothing broke visually.
215
+
216
+ ### Full audit (all analyses)
217
+
218
+ ```bash
219
+ npx driftx compare --design <path> --with pixel,a11y --format json
220
+ ```
221
+
222
+ Runs pixel diff and accessibility audit together.
223
+
224
+ ## Device Interaction
225
+
226
+ driftx can interact with the running app — tap buttons, type text, swipe, navigate.
227
+
228
+ ### `driftx tap <target>` — Tap a component
229
+
230
+ ```bash
231
+ npx driftx tap login-btn
232
+ npx driftx tap LoginButton
233
+ npx driftx tap "Submit"
234
+ npx driftx tap 150,300 --xy
235
+ npx driftx tap login-btn --device "iPhone 16 Pro"
236
+ ```
237
+
238
+ Returns JSON with interaction result.
239
+
240
+ ### `driftx type <target> <text>` — Type text into a field
241
+
242
+ ```bash
243
+ npx driftx type email-input "user@example.com"
244
+ ```
245
+
246
+ Taps the target first to focus it, then types.
247
+
248
+ ### `driftx swipe <direction>` — Swipe gesture
249
+
250
+ ```bash
251
+ npx driftx swipe up
252
+ npx driftx swipe down
253
+ npx driftx swipe left
254
+ npx driftx swipe right
255
+ ```
256
+
257
+ ### `driftx go-back` — Press back button
258
+
259
+ ```bash
260
+ npx driftx go-back
261
+ ```
262
+
263
+ ### `driftx open-url <url>` — Open a deep link
264
+
265
+ ```bash
266
+ npx driftx open-url "myapp://profile/123"
267
+ ```
268
+
269
+ ### Interaction Workflow
270
+
271
+ 1. Write/modify code
272
+ 2. Hot reload
273
+ 3. `npx driftx tap "Login"` — navigate
274
+ 4. `npx driftx compare --design mockup.png --format json` — verify
275
+ 5. Fix issues and repeat
276
+
277
+ For form testing:
278
+ 1. `npx driftx type email-input "test@example.com"`
279
+ 2. `npx driftx type password-input "password123"`
280
+ 3. `npx driftx tap "Submit"`
281
+ 4. `npx driftx compare --baseline --format json`
282
+
283
+ ## Configuration
284
+
285
+ driftx uses `.driftxrc.json` in the project root. Run `npx driftx init` to create one. Key settings:
286
+
287
+ - `platform`: `"android"` or `"ios"`
288
+ - `metroPort`: Metro bundler port (default 8081)
289
+ - `threshold`: Pixel sensitivity (default 0.1)
290
+ - `diffThreshold`: Pass/fail percentage threshold (default 0.01)
291
+ - `analyses.default`: Default analyses to run
292
+ - `analyses.disabled`: Analyses to never run
293
+
294
+ ## Error Handling
295
+
296
+ - If no booted device is found, suggest the user start a simulator/emulator
297
+ - If Metro is not running, suggest `npx react-native start`
298
+ - If `driftx doctor` shows missing prerequisites, show the user which tools to install
299
+ - If compare fails with "Either --design or --baseline must be provided", one of those flags is required
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "driftx",
3
+ "version": "0.1.0",
4
+ "description": "Visual diff tool for React Native and Android development",
5
+ "type": "module",
6
+ "main": "./dist/bin.js",
7
+ "bin": {
8
+ "driftx": "./dist/bin.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "driftx-plugin"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsup",
16
+ "dev": "tsup --watch",
17
+ "test": "vitest run",
18
+ "test:watch": "vitest",
19
+ "test:coverage": "vitest run --coverage",
20
+ "test:device": "DRIFTX_DEVICE_TESTS=1 vitest run test/device/",
21
+ "lint": "tsc --noEmit"
22
+ },
23
+ "keywords": [
24
+ "react-native",
25
+ "visual-diff",
26
+ "screenshot",
27
+ "testing"
28
+ ],
29
+ "license": "MIT",
30
+ "engines": {
31
+ "node": ">=18"
32
+ },
33
+ "dependencies": {
34
+ "@inquirer/prompts": "^8.3.0",
35
+ "commander": "^14.0.3",
36
+ "cosmiconfig": "^9.0.1",
37
+ "nanoid": "^5.1.6",
38
+ "picocolors": "^1.1.1",
39
+ "pino": "^10.3.1",
40
+ "pino-pretty": "^13.1.3",
41
+ "pixelmatch": "^7.1.0",
42
+ "pngjs": "^7.0.0",
43
+ "sharp": "^0.34.5",
44
+ "ws": "^8.19.0",
45
+ "zod": "^4.3.6"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^25.4.0",
49
+ "@types/pngjs": "^6.0.5",
50
+ "@types/ws": "^8.18.1",
51
+ "@vitest/coverage-v8": "^4.0.18",
52
+ "tsup": "^8.5.1",
53
+ "typescript": "^5.9.3",
54
+ "vitest": "^4.0.18"
55
+ }
56
+ }