qapture2 0.2.3 → 0.3.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.
- package/README.md +145 -23
- package/dist/bin/init.cjs +59 -258
- package/dist/{chunk-PC6LNG5Y.cjs → chunk-6KAXMN77.cjs} +2626 -1151
- package/dist/{chunk-BE3H3FKR.js → chunk-ESRQOU32.js} +2627 -1153
- package/dist/index.cjs +8 -4
- package/dist/index.d.cts +34 -6
- package/dist/index.d.ts +34 -6
- package/dist/index.js +1 -1
- package/dist/next.cjs +4 -4
- package/dist/next.js +1 -1
- package/dist/standalone.cjs +26 -21
- package/dist/standalone.js +25 -20
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -14,10 +14,15 @@ npm install qapture2
|
|
|
14
14
|
|
|
15
15
|
## Contents
|
|
16
16
|
|
|
17
|
+
- [Breaking Changes (v0.3.0 "Graphite")](#breaking-changes-v030-graphite)
|
|
17
18
|
- [Quick Start](#quick-start)
|
|
18
19
|
- [Config Reference](#config-reference)
|
|
19
20
|
- [Graded Risk Model](#graded-risk-model)
|
|
21
|
+
- [Guided Walkthrough (Test-Along)](#guided-walkthrough-test-along)
|
|
22
|
+
- [Severity, Status, and Copy as Agent Prompt](#severity-status-and-copy-as-agent-prompt)
|
|
20
23
|
- [Export and AI Handoff](#export-and-ai-handoff)
|
|
24
|
+
- [Runtime Context Capture](#runtime-context-capture)
|
|
25
|
+
- [Notices and Undo](#notices-and-undo)
|
|
21
26
|
- [CLI](#cli)
|
|
22
27
|
- [Launcher Gating](#launcher-gating)
|
|
23
28
|
- [Browser and SSR Support](#browser-and-ssr-support)
|
|
@@ -27,6 +32,38 @@ npm install qapture2
|
|
|
27
32
|
|
|
28
33
|
---
|
|
29
34
|
|
|
35
|
+
## Breaking Changes (v0.3.0 "Graphite")
|
|
36
|
+
|
|
37
|
+
**v0.3.0 is a breaking release.**
|
|
38
|
+
|
|
39
|
+
- **Custom themes are removed.** The widget now ships one fixed, self-contained
|
|
40
|
+
dark design ("Graphite") — there is no more per-project colour override. A
|
|
41
|
+
`theme` key left in `qa.config` is no longer read; `validateConfig` ignores
|
|
42
|
+
it and pushes this exact warning:
|
|
43
|
+
|
|
44
|
+
> theme: custom themes were removed in Qapture 0.3.0 — the widget now ships
|
|
45
|
+
> one fixed, self-contained design. The "theme" key is ignored; remove it
|
|
46
|
+
> from your qa.config to silence this warning.
|
|
47
|
+
|
|
48
|
+
Delete the `theme` block from your config — see the updated
|
|
49
|
+
[`examples/minimal.config.ts`](./examples/minimal.config.ts) and
|
|
50
|
+
[`examples/stitch-and-sell.config.ts`](./examples/stitch-and-sell.config.ts),
|
|
51
|
+
both of which had their `theme` block removed entirely. The `QaTheme` type
|
|
52
|
+
is still exported so old config objects keep type-checking, but it is
|
|
53
|
+
`@deprecated` and has no runtime effect — see [`QaTheme`](#qatheme-deprecated).
|
|
54
|
+
- **New:** a guided, step-by-step walkthrough over your journey ("test-along"),
|
|
55
|
+
severity + status on notes, a one-click "Copy as agent prompt", and an
|
|
56
|
+
undo-capable delete/clear system. See the sections below.
|
|
57
|
+
- **New, and worth reading if you care about privacy:** an (on-by-default,
|
|
58
|
+
opt-out) runtime context capture that records recent console errors and
|
|
59
|
+
failed network calls into each note. See
|
|
60
|
+
[Runtime Context Capture](#runtime-context-capture) and
|
|
61
|
+
[SECURITY.md § Runtime context capture](./SECURITY.md#runtime-context-capture).
|
|
62
|
+
|
|
63
|
+
Full details: [CHANGELOG.md](./CHANGELOG.md#030-graphite--unreleased).
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
30
67
|
## Quick Start
|
|
31
68
|
|
|
32
69
|
### React (any)
|
|
@@ -118,7 +155,7 @@ All fields are optional. Passing an empty object (or no config at all) produces
|
|
|
118
155
|
| Field | Type | Default | Description |
|
|
119
156
|
|---|---|---|---|
|
|
120
157
|
| `namespace` | `string` | `'qapture'` | Prefix for IndexedDB (`${namespace}-db`) and localStorage keys (`${namespace}:*`). Use a unique value per project to avoid storage collisions on the same origin. |
|
|
121
|
-
| `theme` | `Partial<QaTheme>`
|
|
158
|
+
| `theme` | `Partial<QaTheme>` (**deprecated, ignored**) | — | **Removed in v0.3.0.** `validateConfig` ignores this key (after pushing a warning) — the widget always renders the fixed Graphite design. Delete it from your config. See [Breaking Changes](#breaking-changes-v030-graphite). |
|
|
122
159
|
| `brand` | `{ label?: string }` | `{ label: 'Qapture' }` | Panel heading label. |
|
|
123
160
|
| `loginField` | `{ en: string; ar?: string }` | `{ en: 'Username', ar: 'اسم المستخدم' }` | Display label for the login column in the Credentials tab. |
|
|
124
161
|
| `credentials` | `QaCredential[]` | `[]` | DEV/TEST/SEED login rows shown in the Credentials tab. |
|
|
@@ -128,22 +165,18 @@ All fields are optional. Passing an empty object (or no config at all) produces
|
|
|
128
165
|
| `visible` | `boolean \| undefined` | `undefined` | `true` = always show; `false` = always hide; `undefined` = dev-only (hidden in production). |
|
|
129
166
|
| `alwaysVisible` | `boolean` | `false` | When `true`, overrides `visible` and shows the panel even in production. |
|
|
130
167
|
| `hotkey` | `string` | `'shift+alt+q'` | Keyboard shortcut that toggles the panel open/closed. |
|
|
168
|
+
| `captureContext` | `boolean` | `true` | Whether to record ambient runtime context (recent console errors/warnings, uncaught errors, failed network calls, and an environment snapshot) into each note as it's captured. Set to `false` to disable entirely. See [Runtime Context Capture](#runtime-context-capture). |
|
|
131
169
|
|
|
132
|
-
### `QaTheme`
|
|
133
|
-
|
|
134
|
-
Nine CSS custom-property tokens (`--qa-*`) that control the widget chrome. All values are CSS color strings.
|
|
170
|
+
### `QaTheme` (deprecated)
|
|
135
171
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
| `mauve` | `#a78bfa` | Soft decorative surfaces |
|
|
145
|
-
| `surface` | `#ffffff` | Cards, inputs |
|
|
146
|
-
| `ink` | `#1f2937` | Body text |
|
|
172
|
+
> **Removed in v0.3.0.** The widget no longer accepts a custom theme — it
|
|
173
|
+
> ships one fixed, self-contained dark design ("Graphite") built into the
|
|
174
|
+
> stylesheet itself. `QaTheme` and `QaConfig.theme` are still exported so
|
|
175
|
+
> pre-0.3 config objects continue to type-check without edits, but both are
|
|
176
|
+
> marked `@deprecated` and have **no effect** on the rendered UI. Nine colour
|
|
177
|
+
> tokens (`primary`, `primaryDark`, `accent`, `accentDark`, `sage`, `cream`,
|
|
178
|
+
> `mauve`, `surface`, `ink`) used to be overridable here; there is nothing to
|
|
179
|
+
> configure in their place.
|
|
147
180
|
|
|
148
181
|
### `QaCredential`
|
|
149
182
|
|
|
@@ -230,15 +263,45 @@ When there are no red steps the score is vacuously Complete. The receiving agent
|
|
|
230
263
|
|
|
231
264
|
---
|
|
232
265
|
|
|
266
|
+
## Guided Walkthrough (Test-Along)
|
|
267
|
+
|
|
268
|
+
Ticking journey steps one at a time in the Guide tab works, but on a long journey it's easy to lose your place. **Test-along** turns the same `journey` config into a guided, step-by-step mode:
|
|
269
|
+
|
|
270
|
+
1. Open the **Guide** tab and press **"Start walkthrough"** (`start_walkthrough`). The panel closes and is replaced by a compact bottom bar — the Notes/Logins/Guide panel is hidden while a walkthrough is active.
|
|
271
|
+
2. The bar shows **"Step *n* of *m*"** (`step_of`), the current step's instructions (`what`), and — when the step defines one — its `expect` text (`expected_label`): what a pass actually looks like.
|
|
272
|
+
3. **"Back" / "Next"** (`prev_step` / `next_step`) move between steps; the buttons are direction-aware (their chevrons flip in RTL).
|
|
273
|
+
4. **"Pass" / "Fail"** (`mark_pass` / `mark_fail`) grade the current step. A pass adds the step to the same `guideChecked` set the Guide tab shows; a fail records it in a parallel `guideFailed` set (persisted the same way, under `${namespace}:guideFailed`) so a step can be visibly flagged red without losing its place in the checklist.
|
|
274
|
+
5. **"Capture here"** (`capture_here`) starts a capture without leaving the walkthrough. Any note captured while test-along is active is **automatically linked** to the current step — no manual tagging, no picking a route from a dropdown.
|
|
275
|
+
6. **"Exit"** (`exit_walkthrough`) closes the walkthrough and returns to the normal panel.
|
|
276
|
+
|
|
277
|
+
Back in the Guide tab, each step shows an evidence badge — **"{n} attached"** (`evidence_n`) when notes are linked to it, or, if the step was marked Pass with nothing ever captured against it, **"ticked, no capture"** (`no_evidence`, shown in the warn tint) as a gentle nudge that a checked box isn't the same thing as an annotation the receiving agent can act on.
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Severity, Status, and Copy as Agent Prompt
|
|
282
|
+
|
|
283
|
+
Every note (quick note or captured point) can now carry:
|
|
284
|
+
|
|
285
|
+
- **Severity** — `bug` (default), `question`, or `polish` (`sev_bug` / `sev_question` / `sev_polish`), set from a chip row shown both on the quick-note form and on the capture-mode annotation card.
|
|
286
|
+
- **Status** — `open` (default) or `verified` (`status_open` / `status_verified`), toggled with a single tap directly on each note's card in the Notes tab — useful for marking a point re-checked without deleting it.
|
|
287
|
+
|
|
288
|
+
Both fields ride along into the export: each `## Point N` in `notes.md` gets a `Severity` and `Status` line (see [ZIP layout](#export-and-ai-handoff) below), and a note linked to a journey step (by test-along or by route match — see below) gets a `Journey step` line too.
|
|
289
|
+
|
|
290
|
+
**Copy as agent prompt** (`copy_prompt`) puts a *single* note on the clipboard, rendered through the exact same Markdown template used for each point in the exported ZIP (`noteToMarkdown()`), including its runtime context block. Use it to hand one finding to a terminal agent without doing a full export. A `copied` / `copy_failed` toast confirms the result.
|
|
291
|
+
|
|
292
|
+
Outside test-along, a captured note is also auto-linked to a journey step whenever the current route matches one: `matchRouteToSteps()` checks the page's route against every step's `path` (treating `:param` / `[param]` segments as wildcards), preferring an exact match over a parameterised one.
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
233
296
|
## Export and AI Handoff
|
|
234
297
|
|
|
235
298
|
### The workflow
|
|
236
299
|
|
|
237
|
-
1. **Capture** — click an element or drag a region on the live page. Qapture auto-screenshots the visible page
|
|
238
|
-
2. **Guide** — tick steps in the journey as you walk through them. The Guide tab tracks red-zone coverage and shows the current tier.
|
|
239
|
-
3. **Export** — click Export in the panel. A `qa-notes-<timestamp>.zip` downloads to your machine. Give it a meaningful name.
|
|
300
|
+
1. **Capture** — click an element or drag a region on the live page (or press "Capture here" mid-[walkthrough](#guided-walkthrough-test-along)). Qapture auto-screenshots the visible page and opens the note editor. Write a description, optionally set severity, save.
|
|
301
|
+
2. **Guide** — tick steps in the journey as you walk through them, or run the guided [Test-Along](#guided-walkthrough-test-along) walkthrough instead. The Guide tab tracks red-zone coverage and shows the current tier.
|
|
302
|
+
3. **Export** — click Export in the panel. A `qa-notes-<timestamp>.zip` downloads to your machine. Give it a meaningful name. (For a single finding, "Copy as agent prompt" on any note skips the ZIP entirely — see [above](#severity-status-and-copy-as-agent-prompt).)
|
|
240
303
|
4. **Handoff** — drop the ZIP into your terminal coding agent's context. If you use Claude Code, the `.claude/skills/qapture/SKILL.md` the CLI generated (or the `AGENTS.md` snippet) primes the agent automatically when the ZIP is attached.
|
|
241
|
-
5. **Agent acts** — the agent reads `notes.md`, internalises the preamble (project context,
|
|
304
|
+
5. **Agent acts** — the agent reads `notes.md`, internalises the preamble (project context, dev credentials, red-zone coverage, invariants), flags any uncovered RED steps, then works through each `## Point N` annotation: locates the code via the selector + screenshot, reads the severity/status/runtime-context evidence, makes the change, verifies it in the running app, and produces a graded summary.
|
|
242
305
|
|
|
243
306
|
### ZIP layout
|
|
244
307
|
|
|
@@ -260,7 +323,6 @@ qa-notes-<timestamp>.zip
|
|
|
260
323
|
> one-liner
|
|
261
324
|
|
|
262
325
|
## Project (name, stack, run commands)
|
|
263
|
-
## Theme Tokens (9-token colour table)
|
|
264
326
|
## Conventions (numbered codebase rules)
|
|
265
327
|
## Login Context (DEV/TEST/SEED credentials table + warning)
|
|
266
328
|
## Coverage Report (red/amber/green totals + uncovered RED list)
|
|
@@ -274,22 +336,82 @@ qa-notes-<timestamp>.zip
|
|
|
274
336
|
|
|
275
337
|
## Point 1
|
|
276
338
|
- **Page:** /some-route
|
|
277
|
-
- **
|
|
339
|
+
- **Full URL:** https://… (only when it differs from Page)
|
|
278
340
|
- **When:** <timestamp>
|
|
341
|
+
- **Severity:** bug (bug | question | polish)
|
|
342
|
+
- **Status:** open (open | verified)
|
|
343
|
+
- **Journey step:** buyer → /checkout (when linked — test-along or route match)
|
|
344
|
+
- **Target:** element
|
|
345
|
+
- **Selector:** `#element-id`
|
|
279
346
|
- **Screenshot:** screenshots/point-1.png
|
|
280
347
|
|
|
281
348
|
Tester's note text...
|
|
282
349
|
|
|
350
|
+
<details><summary>Runtime context at capture</summary>
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
viewport 1440×900 @2x
|
|
354
|
+
language en-US
|
|
355
|
+
timezone Asia/Baghdad
|
|
356
|
+
online true
|
|
357
|
+
pageLoad 842ms
|
|
358
|
+
userAgent Mozilla/5.0 …
|
|
359
|
+
|
|
360
|
+
events (3, most recent last):
|
|
361
|
+
[-2.1s] console.error: TypeError: Cannot read properties of undefined (reading 'total')
|
|
362
|
+
[-1.8s] POST https://example.com/api/checkout?… → 500 (340ms)
|
|
363
|
+
[-0.2s] uncaught: TypeError: Cannot read properties of undefined (reading 'total')
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
**Element forensics**
|
|
367
|
+
|
|
368
|
+
```
|
|
369
|
+
html <button class="checkout-btn" disabled>Place order</button>
|
|
370
|
+
display inline-flex
|
|
371
|
+
…
|
|
372
|
+
a11y accessibleName=true tabReachable=true contrast=ok
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
</details>
|
|
376
|
+
|
|
283
377
|
---
|
|
284
378
|
|
|
285
379
|
## Point 2
|
|
286
380
|
...
|
|
287
381
|
```
|
|
288
382
|
|
|
383
|
+
(The **Theme Tokens** section from pre-0.3.0 exports is gone — v0.3.0 has no per-project theme to embed. The runtime-context block is present only when [Runtime Context Capture](#runtime-context-capture) is enabled and something was recorded.)
|
|
384
|
+
|
|
289
385
|
The preamble degrades gracefully — sections with no data are marked `(not provided)` rather than omitted, so the agent always receives the full structure.
|
|
290
386
|
|
|
291
387
|
---
|
|
292
388
|
|
|
389
|
+
## Runtime Context Capture
|
|
390
|
+
|
|
391
|
+
Every note (unless disabled) automatically carries a small slice of what the browser was doing right before it: recent `console.error`/`console.warn` calls, uncaught errors and unhandled promise rejections, and failed or slow `fetch`/`XMLHttpRequest` calls — plus a one-time environment snapshot (viewport, language, timezone, online state, page-load time, and, where available, JS heap size). It turns "the button does nothing" into "the button does nothing, and here's the console error and the 500 that happened at that moment" — see [`src/lib/contextBuffer.ts`](./src/lib/contextBuffer.ts).
|
|
392
|
+
|
|
393
|
+
This is genuinely new privacy-relevant surface, and it is documented in full — including the exact guarantees (query strings redacted, bodies/headers/cookies/storage never touched, ring buffer capped at 75 events) — in **[SECURITY.md § Runtime context capture](./SECURITY.md#runtime-context-capture)**. Read it before shipping this to a tester on a real project.
|
|
394
|
+
|
|
395
|
+
Disable it entirely with:
|
|
396
|
+
|
|
397
|
+
```ts
|
|
398
|
+
const config: QaConfig = {
|
|
399
|
+
captureContext: false,
|
|
400
|
+
};
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
With this set, nothing is ever wrapped or recorded, and no runtime-context block appears in the export or in "Copy as agent prompt".
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Notices and Undo
|
|
408
|
+
|
|
409
|
+
Deleting a note or clearing all notes is no longer instant and irreversible. Both actions remove the item from the UI immediately, but the real IndexedDB write is deferred 5 seconds behind a toast with an **Undo** (`undo`) button — press it inside that window and the note (or the whole list) comes back at its original position. Closing the tab, or the host app unmounting `<Qapture>`, flushes any pending deletes right away, so nothing is ever silently lost or silently resurrected after the fact.
|
|
410
|
+
|
|
411
|
+
The same toast system (`notices`) reports a handful of other outcomes that previously had no UI to surface through: a full IndexedDB quota (`persist_failed`), export success/failure (`export_done` / `export_failed`), clipboard copy success/failure (`copied` / `copy_failed`), and a failed screenshot with a `retry` action. At most 3 toasts queue at once; a 4th drops the oldest.
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
293
415
|
## CLI
|
|
294
416
|
|
|
295
417
|
The CLI scaffolds `qa.config`, the agent skill, and `AGENTS.md` into any repository. It is **deterministic, AI-free, and network-free** — no model call, no network request, no `require()`-ing of target project files.
|
|
@@ -306,9 +428,8 @@ npx qapture2 version
|
|
|
306
428
|
| Step | What happens |
|
|
307
429
|
|---|---|
|
|
308
430
|
| Route detection | Scans `src/`, `app/`, `pages/` for route files; generates journey lanes with placeholder `'green'` steps for you to grade |
|
|
309
|
-
| Theme detection | Reads `tailwind.config.*` and CSS files for colour values |
|
|
310
431
|
| Credential detection | Scans `.env.example` and seeder/seed files for test logins. **Never reads `.env`, `.env.local`, `.env.production`, or any real secrets file** — enforced by a hard blocklist |
|
|
311
|
-
| `qa.config.js` / `.ts` | Generated based on detections; contains TODO comments for manual grading |
|
|
432
|
+
| `qa.config.js` / `.ts` | Generated based on detections; contains TODO comments for manual grading. No `theme` block is emitted — v0.3.0 removed custom themes entirely (see [Breaking Changes](#breaking-changes-v030-graphite)) |
|
|
312
433
|
| `qa.preamble.md` | Starter preamble file; fill with project context and paste into `config.preamble` |
|
|
313
434
|
| `.claude/skills/qapture/SKILL.md` | Claude Code agent skill (always refreshed — this is a vendor artifact) |
|
|
314
435
|
| `AGENTS.md` | Idempotent merge with sentinel guards; safe to run repeatedly |
|
|
@@ -371,6 +492,7 @@ The **hotkey** (default: `Shift+Alt+Q`) toggles the panel open/closed regardless
|
|
|
371
492
|
|
|
372
493
|
- **Zero AI, zero network, zero keys.** No model is bundled; no API calls are made; no telemetry is collected.
|
|
373
494
|
- **Data stays in the browser** until the tester explicitly exports a ZIP. Nothing is ever transmitted.
|
|
495
|
+
- **Runtime context capture** (new in v0.3.0) records recent console/network events into each note for the receiving agent — query strings are redacted, bodies/headers/cookies/storage are never touched, and it can be disabled entirely with `captureContext: false`. See [Runtime Context Capture](#runtime-context-capture) and [SECURITY.md § Runtime context capture](./SECURITY.md#runtime-context-capture).
|
|
374
496
|
- **Credentials are DEV/TEST/SEED only.** The `credentials` config field and the Login Context in the export are intended exclusively for non-production environments.
|
|
375
497
|
- **The CLI never reads real secrets.** A hard path blocklist prevents the CLI from reading `.env`, `.env.local`, `.env.production`, certificate files, or any file under `/secrets/`, `/keys/`, `/credentials/`. Only `.env.example` and seeder files are scanned.
|
|
376
498
|
|