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/dist/index.cjs CHANGED
@@ -1,20 +1,24 @@
1
1
  'use strict';
2
2
 
3
- var chunkPC6LNG5Y_cjs = require('./chunk-PC6LNG5Y.cjs');
3
+ var chunk6KAXMN77_cjs = require('./chunk-6KAXMN77.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "QaStudio", {
8
8
  enumerable: true,
9
- get: function () { return chunkPC6LNG5Y_cjs.Qapture; }
9
+ get: function () { return chunk6KAXMN77_cjs.Qapture; }
10
10
  });
11
11
  Object.defineProperty(exports, "Qapture", {
12
12
  enumerable: true,
13
- get: function () { return chunkPC6LNG5Y_cjs.Qapture; }
13
+ get: function () { return chunk6KAXMN77_cjs.Qapture; }
14
+ });
15
+ Object.defineProperty(exports, "deleteQaDatabase", {
16
+ enumerable: true,
17
+ get: function () { return chunk6KAXMN77_cjs.deleteQaDatabase; }
14
18
  });
15
19
  Object.defineProperty(exports, "initQaStudio", {
16
20
  enumerable: true,
17
- get: function () { return chunkPC6LNG5Y_cjs.initQaStudio; }
21
+ get: function () { return chunk6KAXMN77_cjs.initQaStudio; }
18
22
  });
19
23
  //# sourceMappingURL=index.cjs.map
20
24
  //# sourceMappingURL=index.cjs.map
package/dist/index.d.cts CHANGED
@@ -5,15 +5,23 @@
5
5
  * or skips invalid entries, and NEVER throws. Returns a fully-resolved config
6
6
  * plus human-readable warnings.
7
7
  *
8
- * Also exports DEFAULT_THEME so that defaults.ts can import it without
9
- * creating a circular dependency (defaults.ts schema.ts, not the reverse).
8
+ * Custom themes were removed in Qapture 0.3.0 QaConfig.theme is kept only
9
+ * so older config objects still type-check; it is IGNORED by validateConfig
10
+ * (a warning is pushed) and ResolvedConfig no longer carries a theme field.
10
11
  */
11
12
  /** A bilingual string: either a plain string (language-neutral) or { en, ar? }. */
12
13
  type QaBilingual = string | {
13
14
  en: string;
14
15
  ar?: string;
15
16
  };
16
- /** Brand colour palette for the QA panel. All fields optional on input. */
17
+ /**
18
+ * Brand colour palette for the QA panel.
19
+ *
20
+ * @deprecated Custom themes were removed in Qapture 0.3.0 — the widget now
21
+ * ships one fixed, self-contained design. This type is kept only so that
22
+ * existing `theme?: Partial<QaTheme>` config objects still type-check; it has
23
+ * no effect on the rendered UI.
24
+ */
17
25
  type QaTheme = {
18
26
  primary: string;
19
27
  primaryDark: string;
@@ -43,6 +51,8 @@ type QaRisk = 'red' | 'amber' | 'green';
43
51
  type QaJourneyStep = {
44
52
  path: string;
45
53
  what: QaBilingual;
54
+ /** Optional "what pass looks like" — shown alongside `what` when present. */
55
+ expect?: QaBilingual;
46
56
  risk?: QaRisk;
47
57
  riskWhy?: string;
48
58
  };
@@ -78,7 +88,13 @@ type QaPreamble = {
78
88
  type QaConfig = {
79
89
  /** Storage + DB namespace. Defaults to 'qapture'. */
80
90
  namespace?: string;
81
- /** Override any subset of the colour palette. */
91
+ /**
92
+ * Override any subset of the colour palette.
93
+ *
94
+ * @deprecated Custom themes were removed in Qapture 0.3.0 — the widget now
95
+ * ships one fixed, self-contained design. This key is IGNORED (a warning is
96
+ * pushed by validateConfig); remove it from your qa.config to silence it.
97
+ */
82
98
  theme?: Partial<QaTheme>;
83
99
  /** Panel brand label. */
84
100
  brand?: {
@@ -108,10 +124,15 @@ type QaConfig = {
108
124
  alwaysVisible?: boolean;
109
125
  /** Keyboard shortcut to toggle the panel. Default: 'shift+alt+q'. */
110
126
  hotkey?: string;
127
+ /**
128
+ * Whether to capture ambient runtime context (console errors/warnings,
129
+ * uncaught errors, network failures, env snapshot) alongside new notes.
130
+ * Default: true.
131
+ */
132
+ captureContext?: boolean;
111
133
  };
112
134
  type ResolvedConfig = {
113
135
  namespace: string;
114
- theme: QaTheme;
115
136
  brand: {
116
137
  label: string;
117
138
  };
@@ -134,8 +155,15 @@ type ResolvedConfig = {
134
155
  visible: boolean | undefined;
135
156
  alwaysVisible: boolean;
136
157
  hotkey: string;
158
+ captureContext: boolean;
137
159
  };
138
160
 
161
+ /**
162
+ * Full uninstall helper — wipes the entire DB for the given namespace.
163
+ * Call from the browser console: `import('qapture2').then(m => m.deleteQaDatabase('qapture'))`.
164
+ */
165
+ declare function deleteQaDatabase(namespace: string): Promise<void>;
166
+
139
167
  /**
140
168
  * qapture — public API.
141
169
  *
@@ -176,4 +204,4 @@ declare function Qapture({ config }: {
176
204
  config?: QaConfig;
177
205
  }): null;
178
206
 
179
- export { type QaBilingual, type QaConfig, type QaCredential, type QaJourneyLane, type QaJourneyStep, type QaPreamble, type QaRisk, Qapture as QaStudio, type QaTheme, Qapture, type ResolvedConfig, initQaStudio };
207
+ export { type QaBilingual, type QaConfig, type QaCredential, type QaJourneyLane, type QaJourneyStep, type QaPreamble, type QaRisk, Qapture as QaStudio, type QaTheme, Qapture, type ResolvedConfig, deleteQaDatabase, initQaStudio };
package/dist/index.d.ts CHANGED
@@ -5,15 +5,23 @@
5
5
  * or skips invalid entries, and NEVER throws. Returns a fully-resolved config
6
6
  * plus human-readable warnings.
7
7
  *
8
- * Also exports DEFAULT_THEME so that defaults.ts can import it without
9
- * creating a circular dependency (defaults.ts schema.ts, not the reverse).
8
+ * Custom themes were removed in Qapture 0.3.0 QaConfig.theme is kept only
9
+ * so older config objects still type-check; it is IGNORED by validateConfig
10
+ * (a warning is pushed) and ResolvedConfig no longer carries a theme field.
10
11
  */
11
12
  /** A bilingual string: either a plain string (language-neutral) or { en, ar? }. */
12
13
  type QaBilingual = string | {
13
14
  en: string;
14
15
  ar?: string;
15
16
  };
16
- /** Brand colour palette for the QA panel. All fields optional on input. */
17
+ /**
18
+ * Brand colour palette for the QA panel.
19
+ *
20
+ * @deprecated Custom themes were removed in Qapture 0.3.0 — the widget now
21
+ * ships one fixed, self-contained design. This type is kept only so that
22
+ * existing `theme?: Partial<QaTheme>` config objects still type-check; it has
23
+ * no effect on the rendered UI.
24
+ */
17
25
  type QaTheme = {
18
26
  primary: string;
19
27
  primaryDark: string;
@@ -43,6 +51,8 @@ type QaRisk = 'red' | 'amber' | 'green';
43
51
  type QaJourneyStep = {
44
52
  path: string;
45
53
  what: QaBilingual;
54
+ /** Optional "what pass looks like" — shown alongside `what` when present. */
55
+ expect?: QaBilingual;
46
56
  risk?: QaRisk;
47
57
  riskWhy?: string;
48
58
  };
@@ -78,7 +88,13 @@ type QaPreamble = {
78
88
  type QaConfig = {
79
89
  /** Storage + DB namespace. Defaults to 'qapture'. */
80
90
  namespace?: string;
81
- /** Override any subset of the colour palette. */
91
+ /**
92
+ * Override any subset of the colour palette.
93
+ *
94
+ * @deprecated Custom themes were removed in Qapture 0.3.0 — the widget now
95
+ * ships one fixed, self-contained design. This key is IGNORED (a warning is
96
+ * pushed by validateConfig); remove it from your qa.config to silence it.
97
+ */
82
98
  theme?: Partial<QaTheme>;
83
99
  /** Panel brand label. */
84
100
  brand?: {
@@ -108,10 +124,15 @@ type QaConfig = {
108
124
  alwaysVisible?: boolean;
109
125
  /** Keyboard shortcut to toggle the panel. Default: 'shift+alt+q'. */
110
126
  hotkey?: string;
127
+ /**
128
+ * Whether to capture ambient runtime context (console errors/warnings,
129
+ * uncaught errors, network failures, env snapshot) alongside new notes.
130
+ * Default: true.
131
+ */
132
+ captureContext?: boolean;
111
133
  };
112
134
  type ResolvedConfig = {
113
135
  namespace: string;
114
- theme: QaTheme;
115
136
  brand: {
116
137
  label: string;
117
138
  };
@@ -134,8 +155,15 @@ type ResolvedConfig = {
134
155
  visible: boolean | undefined;
135
156
  alwaysVisible: boolean;
136
157
  hotkey: string;
158
+ captureContext: boolean;
137
159
  };
138
160
 
161
+ /**
162
+ * Full uninstall helper — wipes the entire DB for the given namespace.
163
+ * Call from the browser console: `import('qapture2').then(m => m.deleteQaDatabase('qapture'))`.
164
+ */
165
+ declare function deleteQaDatabase(namespace: string): Promise<void>;
166
+
139
167
  /**
140
168
  * qapture — public API.
141
169
  *
@@ -176,4 +204,4 @@ declare function Qapture({ config }: {
176
204
  config?: QaConfig;
177
205
  }): null;
178
206
 
179
- export { type QaBilingual, type QaConfig, type QaCredential, type QaJourneyLane, type QaJourneyStep, type QaPreamble, type QaRisk, Qapture as QaStudio, type QaTheme, Qapture, type ResolvedConfig, initQaStudio };
207
+ export { type QaBilingual, type QaConfig, type QaCredential, type QaJourneyLane, type QaJourneyStep, type QaPreamble, type QaRisk, Qapture as QaStudio, type QaTheme, Qapture, type ResolvedConfig, deleteQaDatabase, initQaStudio };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { Qapture as QaStudio, Qapture, initQaStudio } from './chunk-BE3H3FKR.js';
1
+ export { Qapture as QaStudio, Qapture, deleteQaDatabase, initQaStudio } from './chunk-ESRQOU32.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/dist/next.cjs CHANGED
@@ -1,21 +1,21 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkPC6LNG5Y_cjs = require('./chunk-PC6LNG5Y.cjs');
4
+ var chunk6KAXMN77_cjs = require('./chunk-6KAXMN77.cjs');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "QaStudio", {
9
9
  enumerable: true,
10
- get: function () { return chunkPC6LNG5Y_cjs.Qapture; }
10
+ get: function () { return chunk6KAXMN77_cjs.Qapture; }
11
11
  });
12
12
  Object.defineProperty(exports, "Qapture", {
13
13
  enumerable: true,
14
- get: function () { return chunkPC6LNG5Y_cjs.Qapture; }
14
+ get: function () { return chunk6KAXMN77_cjs.Qapture; }
15
15
  });
16
16
  Object.defineProperty(exports, "initQaStudio", {
17
17
  enumerable: true,
18
- get: function () { return chunkPC6LNG5Y_cjs.initQaStudio; }
18
+ get: function () { return chunk6KAXMN77_cjs.initQaStudio; }
19
19
  });
20
20
  //# sourceMappingURL=next.cjs.map
21
21
  //# sourceMappingURL=next.cjs.map
package/dist/next.js CHANGED
@@ -1,4 +1,4 @@
1
1
  "use client";
2
- export { Qapture as QaStudio, Qapture, initQaStudio } from './chunk-BE3H3FKR.js';
2
+ export { Qapture as QaStudio, Qapture, initQaStudio } from './chunk-ESRQOU32.js';
3
3
  //# sourceMappingURL=next.js.map
4
4
  //# sourceMappingURL=next.js.map
@@ -1,39 +1,44 @@
1
1
  'use strict';
2
2
 
3
- var chunkPC6LNG5Y_cjs = require('./chunk-PC6LNG5Y.cjs');
3
+ var chunk6KAXMN77_cjs = require('./chunk-6KAXMN77.cjs');
4
4
 
5
5
  // src/standalone.ts
6
6
  if (typeof window !== "undefined" && typeof customElements !== "undefined" && !customElements.get("qapture-widget")) {
7
7
  import('./index.cjs').then(({ initQaStudio: init }) => {
8
- customElements.define(
9
- "qapture-widget",
10
- class QaStudioWidget extends HTMLElement {
11
- connectedCallback() {
12
- let cfg = {};
13
- try {
14
- const attr = this.getAttribute("config");
15
- if (attr) cfg = JSON.parse(attr);
16
- } catch {
17
- }
18
- const propCfg = this["config"];
19
- if (propCfg && typeof propCfg === "object" && !Array.isArray(propCfg)) {
20
- cfg = propCfg;
21
- }
22
- const instance = init(cfg);
23
- this._destroy = instance.destroy;
8
+ class QaStudioWidget extends HTMLElement {
9
+ connectedCallback() {
10
+ if (this._destroy) return;
11
+ let cfg = {};
12
+ try {
13
+ const attr = this.getAttribute("config");
14
+ if (attr) cfg = JSON.parse(attr);
15
+ } catch {
24
16
  }
25
- disconnectedCallback() {
26
- this._destroy?.();
17
+ const propCfg = this["config"];
18
+ if (propCfg && typeof propCfg === "object" && !Array.isArray(propCfg)) {
19
+ cfg = propCfg;
27
20
  }
21
+ const instance = init(cfg);
22
+ this._destroy = instance.destroy;
28
23
  }
29
- );
24
+ disconnectedCallback() {
25
+ this._destroy?.();
26
+ this._destroy = void 0;
27
+ }
28
+ }
29
+ customElements.define("qapture-widget", QaStudioWidget);
30
+ document.querySelectorAll("qapture-widget").forEach((el) => {
31
+ if (el instanceof QaStudioWidget && el.isConnected) {
32
+ el.connectedCallback();
33
+ }
34
+ });
30
35
  }).catch(() => {
31
36
  });
32
37
  }
33
38
 
34
39
  Object.defineProperty(exports, "initQaStudio", {
35
40
  enumerable: true,
36
- get: function () { return chunkPC6LNG5Y_cjs.initQaStudio; }
41
+ get: function () { return chunk6KAXMN77_cjs.initQaStudio; }
37
42
  });
38
43
  //# sourceMappingURL=standalone.cjs.map
39
44
  //# sourceMappingURL=standalone.cjs.map
@@ -1,30 +1,35 @@
1
- export { initQaStudio } from './chunk-BE3H3FKR.js';
1
+ export { initQaStudio } from './chunk-ESRQOU32.js';
2
2
 
3
3
  // src/standalone.ts
4
4
  if (typeof window !== "undefined" && typeof customElements !== "undefined" && !customElements.get("qapture-widget")) {
5
5
  import('./index.js').then(({ initQaStudio: init }) => {
6
- customElements.define(
7
- "qapture-widget",
8
- class QaStudioWidget extends HTMLElement {
9
- connectedCallback() {
10
- let cfg = {};
11
- try {
12
- const attr = this.getAttribute("config");
13
- if (attr) cfg = JSON.parse(attr);
14
- } catch {
15
- }
16
- const propCfg = this["config"];
17
- if (propCfg && typeof propCfg === "object" && !Array.isArray(propCfg)) {
18
- cfg = propCfg;
19
- }
20
- const instance = init(cfg);
21
- this._destroy = instance.destroy;
6
+ class QaStudioWidget extends HTMLElement {
7
+ connectedCallback() {
8
+ if (this._destroy) return;
9
+ let cfg = {};
10
+ try {
11
+ const attr = this.getAttribute("config");
12
+ if (attr) cfg = JSON.parse(attr);
13
+ } catch {
22
14
  }
23
- disconnectedCallback() {
24
- this._destroy?.();
15
+ const propCfg = this["config"];
16
+ if (propCfg && typeof propCfg === "object" && !Array.isArray(propCfg)) {
17
+ cfg = propCfg;
25
18
  }
19
+ const instance = init(cfg);
20
+ this._destroy = instance.destroy;
26
21
  }
27
- );
22
+ disconnectedCallback() {
23
+ this._destroy?.();
24
+ this._destroy = void 0;
25
+ }
26
+ }
27
+ customElements.define("qapture-widget", QaStudioWidget);
28
+ document.querySelectorAll("qapture-widget").forEach((el) => {
29
+ if (el instanceof QaStudioWidget && el.isConnected) {
30
+ el.connectedCallback();
31
+ }
32
+ });
28
33
  }).catch(() => {
29
34
  });
30
35
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qapture2",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "Drop-in, AI-aware in-browser QA capture widget. A tester annotates the live app (element/region + auto-screenshot + note), tracks a graded testing journey, and exports a ZIP your own coding agent reads. Ships zero AI.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -78,10 +78,16 @@
78
78
  "prepublishOnly": "npm run build",
79
79
  "dev": "tsup --watch",
80
80
  "typecheck": "tsc --noEmit",
81
+ "typecheck:bin": "tsc --noEmit -p tsconfig.bin.json",
81
82
  "smoke": "node scripts/smoke.mjs",
82
83
  "export-smoke": "esbuild src/lib/exportZip.ts --bundle --format=esm --platform=node --outfile=dist/_export-test.mjs --log-level=error && node scripts/export-smoke.mjs dist/_export-test.mjs",
84
+ "cli-smoke": "node scripts/cli-smoke.mjs",
85
+ "cli-detectors-smoke": "node scripts/cli-detectors-smoke.mjs",
86
+ "selector-smoke": "node scripts/selector-smoke.mjs",
87
+ "capture-timeout-smoke": "node scripts/capture-timeout-smoke.mjs",
88
+ "standalone-smoke": "node scripts/standalone-smoke.mjs",
83
89
  "browser-test": "node scripts/browser-test.mjs",
84
- "verify": "npm run typecheck && npm run build && npm run smoke && npm run export-smoke",
90
+ "verify": "npm run typecheck && npm run typecheck:bin && npm run build && npm run smoke && npm run export-smoke && npm run cli-smoke && npm run cli-detectors-smoke && npm run selector-smoke && npm run capture-timeout-smoke && npm run standalone-smoke",
85
91
  "play": "npm --prefix playground run dev"
86
92
  },
87
93
  "engines": {
@@ -104,6 +110,7 @@
104
110
  "jszip": "^3.10.1"
105
111
  },
106
112
  "devDependencies": {
113
+ "@types/node": "^20.19.43",
107
114
  "@types/react": "^18.3.12",
108
115
  "@types/react-dom": "^18.3.1",
109
116
  "jsdom": "^29.1.1",