@monoes/monobrowse 1.0.12 → 1.0.14

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 (271) hide show
  1. package/dist/src/__tests__/bridge-instruments.test.d.ts +2 -0
  2. package/dist/src/__tests__/bridge-instruments.test.d.ts.map +1 -0
  3. package/dist/src/__tests__/bridge-instruments.test.js +132 -0
  4. package/dist/src/__tests__/bridge-instruments.test.js.map +1 -0
  5. package/dist/src/__tests__/bridge-transport.test.d.ts +2 -0
  6. package/dist/src/__tests__/bridge-transport.test.d.ts.map +1 -0
  7. package/dist/src/__tests__/bridge-transport.test.js +287 -0
  8. package/dist/src/__tests__/bridge-transport.test.js.map +1 -0
  9. package/dist/src/__tests__/cdp-transport.test.d.ts +2 -0
  10. package/dist/src/__tests__/cdp-transport.test.d.ts.map +1 -0
  11. package/dist/src/__tests__/cdp-transport.test.js +167 -0
  12. package/dist/src/__tests__/cdp-transport.test.js.map +1 -0
  13. package/dist/src/__tests__/profiler-heap.test.d.ts +2 -0
  14. package/dist/src/__tests__/profiler-heap.test.d.ts.map +1 -0
  15. package/dist/src/__tests__/profiler-heap.test.js +154 -0
  16. package/dist/src/__tests__/profiler-heap.test.js.map +1 -0
  17. package/dist/src/__tests__/report-a11y.test.d.ts +2 -0
  18. package/dist/src/__tests__/report-a11y.test.d.ts.map +1 -0
  19. package/dist/src/__tests__/report-a11y.test.js +147 -0
  20. package/dist/src/__tests__/report-a11y.test.js.map +1 -0
  21. package/dist/src/__tests__/report-analyze.test.d.ts +2 -0
  22. package/dist/src/__tests__/report-analyze.test.d.ts.map +1 -0
  23. package/dist/src/__tests__/report-analyze.test.js +157 -0
  24. package/dist/src/__tests__/report-analyze.test.js.map +1 -0
  25. package/dist/src/__tests__/report-budget.test.d.ts +2 -0
  26. package/dist/src/__tests__/report-budget.test.d.ts.map +1 -0
  27. package/dist/src/__tests__/report-budget.test.js +80 -0
  28. package/dist/src/__tests__/report-budget.test.js.map +1 -0
  29. package/dist/src/__tests__/report-diff.test.d.ts +2 -0
  30. package/dist/src/__tests__/report-diff.test.d.ts.map +1 -0
  31. package/dist/src/__tests__/report-diff.test.js +231 -0
  32. package/dist/src/__tests__/report-diff.test.js.map +1 -0
  33. package/dist/src/__tests__/report-evidence.test.d.ts +2 -0
  34. package/dist/src/__tests__/report-evidence.test.d.ts.map +1 -0
  35. package/dist/src/__tests__/report-evidence.test.js +214 -0
  36. package/dist/src/__tests__/report-evidence.test.js.map +1 -0
  37. package/dist/src/__tests__/report-flake.test.d.ts +2 -0
  38. package/dist/src/__tests__/report-flake.test.d.ts.map +1 -0
  39. package/dist/src/__tests__/report-flake.test.js +182 -0
  40. package/dist/src/__tests__/report-flake.test.js.map +1 -0
  41. package/dist/src/__tests__/report-history.test.d.ts +2 -0
  42. package/dist/src/__tests__/report-history.test.d.ts.map +1 -0
  43. package/dist/src/__tests__/report-history.test.js +229 -0
  44. package/dist/src/__tests__/report-history.test.js.map +1 -0
  45. package/dist/src/__tests__/report-output.test.d.ts +2 -0
  46. package/dist/src/__tests__/report-output.test.d.ts.map +1 -0
  47. package/dist/src/__tests__/report-output.test.js +169 -0
  48. package/dist/src/__tests__/report-output.test.js.map +1 -0
  49. package/dist/src/__tests__/report-png.test.d.ts +2 -0
  50. package/dist/src/__tests__/report-png.test.d.ts.map +1 -0
  51. package/dist/src/__tests__/report-png.test.js +84 -0
  52. package/dist/src/__tests__/report-png.test.js.map +1 -0
  53. package/dist/src/__tests__/report-render-extras.test.d.ts +2 -0
  54. package/dist/src/__tests__/report-render-extras.test.d.ts.map +1 -0
  55. package/dist/src/__tests__/report-render-extras.test.js +285 -0
  56. package/dist/src/__tests__/report-render-extras.test.js.map +1 -0
  57. package/dist/src/__tests__/report-render.test.d.ts +2 -0
  58. package/dist/src/__tests__/report-render.test.d.ts.map +1 -0
  59. package/dist/src/__tests__/report-render.test.js +143 -0
  60. package/dist/src/__tests__/report-render.test.js.map +1 -0
  61. package/dist/src/__tests__/report-run.test.d.ts +2 -0
  62. package/dist/src/__tests__/report-run.test.d.ts.map +1 -0
  63. package/dist/src/__tests__/report-run.test.js +234 -0
  64. package/dist/src/__tests__/report-run.test.js.map +1 -0
  65. package/dist/src/browser/bridge.d.ts +119 -0
  66. package/dist/src/browser/bridge.d.ts.map +1 -0
  67. package/dist/src/browser/bridge.js +264 -0
  68. package/dist/src/browser/bridge.js.map +1 -0
  69. package/dist/src/browser/cdp.d.ts +11 -1
  70. package/dist/src/browser/cdp.d.ts.map +1 -1
  71. package/dist/src/browser/cdp.js +60 -56
  72. package/dist/src/browser/cdp.js.map +1 -1
  73. package/dist/src/browser/index.d.ts +3 -0
  74. package/dist/src/browser/index.d.ts.map +1 -1
  75. package/dist/src/browser/index.js +3 -0
  76. package/dist/src/browser/index.js.map +1 -1
  77. package/dist/src/browser/profiler.d.ts.map +1 -1
  78. package/dist/src/browser/profiler.js +19 -22
  79. package/dist/src/browser/profiler.js.map +1 -1
  80. package/dist/src/browser/transport.d.ts +62 -0
  81. package/dist/src/browser/transport.d.ts.map +1 -0
  82. package/dist/src/browser/transport.js +65 -0
  83. package/dist/src/browser/transport.js.map +1 -0
  84. package/dist/src/cli/commander-adapter.d.ts +16 -0
  85. package/dist/src/cli/commander-adapter.d.ts.map +1 -0
  86. package/dist/src/cli/commander-adapter.js +68 -0
  87. package/dist/src/cli/commander-adapter.js.map +1 -0
  88. package/dist/src/cli/commands-context.d.ts +14 -0
  89. package/dist/src/cli/commands-context.d.ts.map +1 -0
  90. package/dist/src/cli/commands-context.js +351 -0
  91. package/dist/src/cli/commands-context.js.map +1 -0
  92. package/dist/src/cli/commands-data.d.ts +12 -0
  93. package/dist/src/cli/commands-data.d.ts.map +1 -0
  94. package/dist/src/cli/commands-data.js +246 -0
  95. package/dist/src/cli/commands-data.js.map +1 -0
  96. package/dist/src/cli/commands-element.d.ts +15 -0
  97. package/dist/src/cli/commands-element.d.ts.map +1 -0
  98. package/dist/src/cli/commands-element.js +262 -0
  99. package/dist/src/cli/commands-element.js.map +1 -0
  100. package/dist/src/cli/commands-files.d.ts +9 -0
  101. package/dist/src/cli/commands-files.d.ts.map +1 -0
  102. package/dist/src/cli/commands-files.js +207 -0
  103. package/dist/src/cli/commands-files.js.map +1 -0
  104. package/dist/src/cli/commands-input.d.ts +26 -0
  105. package/dist/src/cli/commands-input.d.ts.map +1 -0
  106. package/dist/src/cli/commands-input.js +399 -0
  107. package/dist/src/cli/commands-input.js.map +1 -0
  108. package/dist/src/cli/commands-navigate.d.ts +12 -0
  109. package/dist/src/cli/commands-navigate.d.ts.map +1 -0
  110. package/dist/src/cli/commands-navigate.js +389 -0
  111. package/dist/src/cli/commands-navigate.js.map +1 -0
  112. package/dist/src/cli/commands-page.d.ts +25 -0
  113. package/dist/src/cli/commands-page.d.ts.map +1 -0
  114. package/dist/src/cli/commands-page.js +377 -0
  115. package/dist/src/cli/commands-page.js.map +1 -0
  116. package/dist/src/cli/commands-report.d.ts +8 -0
  117. package/dist/src/cli/commands-report.d.ts.map +1 -0
  118. package/dist/src/cli/commands-report.js +256 -0
  119. package/dist/src/cli/commands-report.js.map +1 -0
  120. package/dist/src/cli/commands-script.d.ts +43 -0
  121. package/dist/src/cli/commands-script.d.ts.map +1 -0
  122. package/dist/src/cli/commands-script.js +168 -0
  123. package/dist/src/cli/commands-script.js.map +1 -0
  124. package/dist/src/cli/commands-session.d.ts +15 -0
  125. package/dist/src/cli/commands-session.d.ts.map +1 -0
  126. package/dist/src/cli/commands-session.js +357 -0
  127. package/dist/src/cli/commands-session.js.map +1 -0
  128. package/dist/src/cli/commands-trace.d.ts +12 -0
  129. package/dist/src/cli/commands-trace.d.ts.map +1 -0
  130. package/dist/src/cli/commands-trace.js +347 -0
  131. package/dist/src/cli/commands-trace.js.map +1 -0
  132. package/dist/src/cli/commands.d.ts +22 -42
  133. package/dist/src/cli/commands.d.ts.map +1 -1
  134. package/dist/src/cli/commands.js +48 -3400
  135. package/dist/src/cli/commands.js.map +1 -1
  136. package/dist/src/cli/session.d.ts +47 -0
  137. package/dist/src/cli/session.d.ts.map +1 -0
  138. package/dist/src/cli/session.js +343 -0
  139. package/dist/src/cli/session.js.map +1 -0
  140. package/dist/src/report/a11y.d.ts +52 -0
  141. package/dist/src/report/a11y.d.ts.map +1 -0
  142. package/dist/src/report/a11y.js +231 -0
  143. package/dist/src/report/a11y.js.map +1 -0
  144. package/dist/src/report/analyze.d.ts +20 -0
  145. package/dist/src/report/analyze.d.ts.map +1 -0
  146. package/dist/src/report/analyze.js +136 -0
  147. package/dist/src/report/analyze.js.map +1 -0
  148. package/dist/src/report/budget.d.ts +27 -0
  149. package/dist/src/report/budget.d.ts.map +1 -0
  150. package/dist/src/report/budget.js +143 -0
  151. package/dist/src/report/budget.js.map +1 -0
  152. package/dist/src/report/collect-a11y.d.ts +25 -0
  153. package/dist/src/report/collect-a11y.d.ts.map +1 -0
  154. package/dist/src/report/collect-a11y.js +154 -0
  155. package/dist/src/report/collect-a11y.js.map +1 -0
  156. package/dist/src/report/collect.d.ts +45 -0
  157. package/dist/src/report/collect.d.ts.map +1 -0
  158. package/dist/src/report/collect.js +275 -0
  159. package/dist/src/report/collect.js.map +1 -0
  160. package/dist/src/report/evidence.d.ts +80 -0
  161. package/dist/src/report/evidence.d.ts.map +1 -0
  162. package/dist/src/report/evidence.js +279 -0
  163. package/dist/src/report/evidence.js.map +1 -0
  164. package/dist/src/report/flake.d.ts +88 -0
  165. package/dist/src/report/flake.d.ts.map +1 -0
  166. package/dist/src/report/flake.js +232 -0
  167. package/dist/src/report/flake.js.map +1 -0
  168. package/dist/src/report/history.d.ts +85 -0
  169. package/dist/src/report/history.d.ts.map +1 -0
  170. package/dist/src/report/history.js +176 -0
  171. package/dist/src/report/history.js.map +1 -0
  172. package/dist/src/report/index.d.ts +102 -0
  173. package/dist/src/report/index.d.ts.map +1 -0
  174. package/dist/src/report/index.js +216 -0
  175. package/dist/src/report/index.js.map +1 -0
  176. package/dist/src/report/pixel-diff.d.ts +30 -0
  177. package/dist/src/report/pixel-diff.d.ts.map +1 -0
  178. package/dist/src/report/pixel-diff.js +175 -0
  179. package/dist/src/report/pixel-diff.js.map +1 -0
  180. package/dist/src/report/png.d.ts +28 -0
  181. package/dist/src/report/png.d.ts.map +1 -0
  182. package/dist/src/report/png.js +259 -0
  183. package/dist/src/report/png.js.map +1 -0
  184. package/dist/src/report/render-evidence.d.ts +16 -0
  185. package/dist/src/report/render-evidence.d.ts.map +1 -0
  186. package/dist/src/report/render-evidence.js +174 -0
  187. package/dist/src/report/render-evidence.js.map +1 -0
  188. package/dist/src/report/render-trend.d.ts +16 -0
  189. package/dist/src/report/render-trend.d.ts.map +1 -0
  190. package/dist/src/report/render-trend.js +194 -0
  191. package/dist/src/report/render-trend.js.map +1 -0
  192. package/dist/src/report/render.d.ts +21 -0
  193. package/dist/src/report/render.d.ts.map +1 -0
  194. package/dist/src/report/render.js +286 -0
  195. package/dist/src/report/render.js.map +1 -0
  196. package/dist/src/report/run-diff.d.ts +18 -0
  197. package/dist/src/report/run-diff.d.ts.map +1 -0
  198. package/dist/src/report/run-diff.js +51 -0
  199. package/dist/src/report/run-diff.js.map +1 -0
  200. package/dist/src/report/structure.d.ts +41 -0
  201. package/dist/src/report/structure.d.ts.map +1 -0
  202. package/dist/src/report/structure.js +210 -0
  203. package/dist/src/report/structure.js.map +1 -0
  204. package/dist/src/report/trend.d.ts +26 -0
  205. package/dist/src/report/trend.d.ts.map +1 -0
  206. package/dist/src/report/trend.js +164 -0
  207. package/dist/src/report/trend.js.map +1 -0
  208. package/dist/src/report/types.d.ts +320 -0
  209. package/dist/src/report/types.d.ts.map +1 -0
  210. package/dist/src/report/types.js +11 -0
  211. package/dist/src/report/types.js.map +1 -0
  212. package/dist/src/report/util.d.ts +17 -0
  213. package/dist/src/report/util.d.ts.map +1 -0
  214. package/dist/src/report/util.js +45 -0
  215. package/dist/src/report/util.js.map +1 -0
  216. package/dist/tsconfig.tsbuildinfo +1 -1
  217. package/package.json +1 -1
  218. package/src/__tests__/bridge-instruments.test.ts +180 -0
  219. package/src/__tests__/bridge-transport.test.ts +365 -0
  220. package/src/__tests__/cdp-transport.test.ts +198 -0
  221. package/src/__tests__/profiler-heap.test.ts +191 -0
  222. package/src/__tests__/report-a11y.test.ts +180 -0
  223. package/src/__tests__/report-analyze.test.ts +202 -0
  224. package/src/__tests__/report-budget.test.ts +92 -0
  225. package/src/__tests__/report-diff.test.ts +272 -0
  226. package/src/__tests__/report-evidence.test.ts +276 -0
  227. package/src/__tests__/report-flake.test.ts +214 -0
  228. package/src/__tests__/report-history.test.ts +293 -0
  229. package/src/__tests__/report-output.test.ts +210 -0
  230. package/src/__tests__/report-png.test.ts +95 -0
  231. package/src/__tests__/report-render-extras.test.ts +315 -0
  232. package/src/__tests__/report-render.test.ts +175 -0
  233. package/src/__tests__/report-run.test.ts +264 -0
  234. package/src/browser/bridge.ts +354 -0
  235. package/src/browser/cdp.ts +57 -52
  236. package/src/browser/index.ts +3 -0
  237. package/src/browser/profiler.ts +28 -21
  238. package/src/browser/transport.ts +111 -0
  239. package/src/cli/commander-adapter.ts +65 -0
  240. package/src/cli/commands-context.ts +367 -0
  241. package/src/cli/commands-data.ts +248 -0
  242. package/src/cli/commands-element.ts +305 -0
  243. package/src/cli/commands-files.ts +248 -0
  244. package/src/cli/commands-input.ts +434 -0
  245. package/src/cli/commands-navigate.ts +442 -0
  246. package/src/cli/commands-page.ts +420 -0
  247. package/src/cli/commands-report.ts +275 -0
  248. package/src/cli/commands-script.ts +183 -0
  249. package/src/cli/commands-session.ts +376 -0
  250. package/src/cli/commands-trace.ts +349 -0
  251. package/src/cli/commands.ts +101 -3677
  252. package/src/cli/session.ts +412 -0
  253. package/src/report/a11y.ts +242 -0
  254. package/src/report/analyze.ts +181 -0
  255. package/src/report/budget.ts +155 -0
  256. package/src/report/collect-a11y.ts +200 -0
  257. package/src/report/collect.ts +408 -0
  258. package/src/report/evidence.ts +379 -0
  259. package/src/report/flake.ts +303 -0
  260. package/src/report/history.ts +219 -0
  261. package/src/report/index.ts +307 -0
  262. package/src/report/pixel-diff.ts +197 -0
  263. package/src/report/png.ts +290 -0
  264. package/src/report/render-evidence.ts +194 -0
  265. package/src/report/render-trend.ts +225 -0
  266. package/src/report/render.ts +314 -0
  267. package/src/report/run-diff.ts +63 -0
  268. package/src/report/structure.ts +212 -0
  269. package/src/report/trend.ts +189 -0
  270. package/src/report/types.ts +356 -0
  271. package/src/report/util.ts +48 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../../src/report/evidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Flake detection across repeated runs of the same URL (RIG-14).
3
+ *
4
+ * The failure mode this exists to stop: a check that fails two runs in five
5
+ * gets re-run until it is green and shipped as "passing". So the aggregate
6
+ * verdict has a third value — `flaky` — and a check that both passed and
7
+ * failed within the window can only produce that verdict. It is never
8
+ * rounded down to `pass`.
9
+ *
10
+ * The other half is honesty about what N runs can prove. `confidenceNote`
11
+ * states the failure rate the window actually rules out, because "5 runs
12
+ * passed" and "this is reliable" are very different claims.
13
+ *
14
+ * Pure: the tests feed arrays of Reports.
15
+ */
16
+ import type { Budget, Report } from './types.js';
17
+ export type FlakeVerdict = 'pass' | 'fail' | 'flaky';
18
+ export interface FlakeCheck {
19
+ key: keyof Budget;
20
+ label: string;
21
+ runs: number;
22
+ passed: number;
23
+ failed: number;
24
+ /** Fraction of runs that failed, 0..1. */
25
+ flakeRate: number;
26
+ /** True when the check did the same thing every run. */
27
+ stable: boolean;
28
+ /** The measured value for each run, in run order. */
29
+ actuals: string[];
30
+ }
31
+ export interface FlakeSignal {
32
+ kind: 'console' | 'pageError' | 'request' | 'a11y';
33
+ signature: string;
34
+ /** Runs this signal appeared in. */
35
+ runs: number;
36
+ total: number;
37
+ }
38
+ export interface FlakeMetric {
39
+ key: string;
40
+ label: string;
41
+ unit: 'ms' | 'score';
42
+ /** Runs that reported the metric at all. */
43
+ measured: number;
44
+ total: number;
45
+ min: number;
46
+ max: number;
47
+ median: number;
48
+ spread: number;
49
+ /** Spread as a fraction of the median. */
50
+ spreadRatio: number;
51
+ unstable: boolean;
52
+ }
53
+ export interface FlakeReport {
54
+ runs: number;
55
+ verdict: FlakeVerdict;
56
+ checks: FlakeCheck[];
57
+ /** Errors and failed requests that did not appear in every run. */
58
+ signals: FlakeSignal[];
59
+ metrics: FlakeMetric[];
60
+ confidence: 'low' | 'moderate' | 'high';
61
+ confidenceNote: string;
62
+ headline: string;
63
+ }
64
+ /**
65
+ * Normalise a message so the same error reported with a different id, line or
66
+ * timestamp still counts as the same signal. Without this, a flaky error
67
+ * carrying a request id looks like N distinct one-off errors.
68
+ */
69
+ export declare function signalSignature(text: string): string;
70
+ /**
71
+ * What a window of all-passing runs actually rules out.
72
+ *
73
+ * If a check truly fails with probability p, N independent passing runs have
74
+ * probability (1-p)^N. Solving (1-p)^N = 0.05 gives the largest failure rate
75
+ * consistent with what we saw at 95% confidence — which is a far less
76
+ * flattering number than "N runs passed" sounds.
77
+ */
78
+ export declare function ruledOutFailureRate(runs: number): number;
79
+ /**
80
+ * Aggregate N runs of the same URL.
81
+ *
82
+ * `budget` comes from the runs themselves (they all share one), and only
83
+ * enforced keys become checks: an unenforced budget cannot be flaky.
84
+ */
85
+ export declare function analyzeFlake(reports: Report[]): FlakeReport;
86
+ /** One line for a CI log / agent transcript. */
87
+ export declare function summarizeFlake(flake: FlakeReport): string;
88
+ //# sourceMappingURL=flake.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flake.d.ts","sourceRoot":"","sources":["../../../src/report/flake.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAErD,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,MAAM,EAAE,OAAO,CAAC;IAChB,qDAAqD;IACrD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,CAAC;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;IACrB,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,mEAAmE;IACnE,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,UAAU,EAAE,KAAK,GAAG,UAAU,GAAG,MAAM,CAAC;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAwCD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAUpD;AA0ED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGxD;AAwBD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,CA0D3D;AAED,gDAAgD;AAChD,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEzD"}
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Flake detection across repeated runs of the same URL (RIG-14).
3
+ *
4
+ * The failure mode this exists to stop: a check that fails two runs in five
5
+ * gets re-run until it is green and shipped as "passing". So the aggregate
6
+ * verdict has a third value — `flaky` — and a check that both passed and
7
+ * failed within the window can only produce that verdict. It is never
8
+ * rounded down to `pass`.
9
+ *
10
+ * The other half is honesty about what N runs can prove. `confidenceNote`
11
+ * states the failure rate the window actually rules out, because "5 runs
12
+ * passed" and "this is reliable" are very different claims.
13
+ *
14
+ * Pure: the tests feed arrays of Reports.
15
+ */
16
+ import { budgetLabel } from './budget.js';
17
+ /** Spread beyond this fraction of the median is worth flagging as unstable. */
18
+ const UNSTABLE_SPREAD_RATIO = 0.3;
19
+ const COUNT_READERS = {
20
+ maxConsoleErrors: (r) => r.counts.consoleErrors,
21
+ maxPageErrors: (r) => r.counts.pageErrors,
22
+ maxFailedRequests: (r) => r.counts.failedRequests,
23
+ maxA11yErrors: (r) => r.counts.a11yErrors,
24
+ };
25
+ const METRIC_READERS = {
26
+ lcpMs: (r) => r.vitals.lcp,
27
+ clsScore: (r) => r.vitals.cls,
28
+ inpMs: (r) => r.vitals.inp,
29
+ fcpMs: (r) => r.vitals.fcp,
30
+ ttfbMs: (r) => r.vitals.ttfb,
31
+ };
32
+ function actualFor(key, report) {
33
+ const count = COUNT_READERS[key];
34
+ if (count)
35
+ return String(count(report));
36
+ const metric = METRIC_READERS[key];
37
+ const raw = metric?.(report);
38
+ if (raw === undefined || !Number.isFinite(raw))
39
+ return 'not measured';
40
+ return key === 'clsScore' ? raw.toFixed(3) : `${Math.round(raw)}ms`;
41
+ }
42
+ function median(values) {
43
+ const sorted = [...values].sort((a, b) => a - b);
44
+ const mid = Math.floor(sorted.length / 2);
45
+ return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
46
+ }
47
+ function truncate(text, max = 140) {
48
+ const flat = text.replace(/\s+/g, ' ').trim();
49
+ return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
50
+ }
51
+ /**
52
+ * Normalise a message so the same error reported with a different id, line or
53
+ * timestamp still counts as the same signal. Without this, a flaky error
54
+ * carrying a request id looks like N distinct one-off errors.
55
+ */
56
+ export function signalSignature(text) {
57
+ return truncate(text
58
+ .replace(/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi, '<uuid>')
59
+ .replace(/\b0x[0-9a-f]+\b/gi, '<hex>')
60
+ // 5 digits and up, not 3: request ids, timestamps and byte offsets are
61
+ // long, while an HTTP status code is part of what makes two errors
62
+ // different and must survive normalisation.
63
+ .replace(/\b\d{5,}\b/g, '<n>'));
64
+ }
65
+ function collectSignals(reports) {
66
+ const total = reports.length;
67
+ const seen = new Map();
68
+ const add = (kind, signature, runIndex) => {
69
+ const id = `${kind}\n${signature}`;
70
+ let entry = seen.get(id);
71
+ if (!entry) {
72
+ entry = { kind, signature, runs: new Set() };
73
+ seen.set(id, entry);
74
+ }
75
+ entry.runs.add(runIndex);
76
+ };
77
+ reports.forEach((report, i) => {
78
+ for (const e of report.console) {
79
+ if (e.type === 'error')
80
+ add('console', signalSignature(e.text), i);
81
+ }
82
+ for (const e of report.pageErrors)
83
+ add('pageError', signalSignature(e.text), i);
84
+ for (const r of report.requests) {
85
+ if (r.failed)
86
+ add('request', `${r.status ?? r.errorText ?? 'no response'} ${r.url}`, i);
87
+ }
88
+ for (const f of report.a11y) {
89
+ if (f.impact === 'error')
90
+ add('a11y', `${f.rule} at ${f.locator}`, i);
91
+ }
92
+ });
93
+ return [...seen.values()]
94
+ .filter((e) => e.runs.size < total) // present in every run is a bug, not a flake
95
+ .map((e) => ({ kind: e.kind, signature: e.signature, runs: e.runs.size, total }))
96
+ .sort((a, b) => b.runs - a.runs || a.signature.localeCompare(b.signature));
97
+ }
98
+ function collectMetrics(reports) {
99
+ const defs = [
100
+ ['lcp', 'LCP', 'ms', (r) => r.vitals.lcp],
101
+ ['fcp', 'FCP', 'ms', (r) => r.vitals.fcp],
102
+ ['cls', 'CLS', 'score', (r) => r.vitals.cls],
103
+ ['inp', 'INP', 'ms', (r) => r.vitals.inp],
104
+ ['ttfb', 'TTFB', 'ms', (r) => r.vitals.ttfb],
105
+ ];
106
+ const out = [];
107
+ for (const [key, label, unit, read] of defs) {
108
+ const values = reports
109
+ .map(read)
110
+ .filter((v) => typeof v === 'number' && Number.isFinite(v));
111
+ if (!values.length)
112
+ continue;
113
+ const min = Math.min(...values);
114
+ const max = Math.max(...values);
115
+ const mid = median(values);
116
+ const spread = max - min;
117
+ const spreadRatio = mid > 0 ? spread / mid : spread > 0 ? Infinity : 0;
118
+ out.push({
119
+ key,
120
+ label,
121
+ unit,
122
+ measured: values.length,
123
+ total: reports.length,
124
+ min,
125
+ max,
126
+ median: mid,
127
+ spread,
128
+ spreadRatio,
129
+ unstable: values.length > 1 && spreadRatio > UNSTABLE_SPREAD_RATIO,
130
+ });
131
+ }
132
+ return out;
133
+ }
134
+ /**
135
+ * What a window of all-passing runs actually rules out.
136
+ *
137
+ * If a check truly fails with probability p, N independent passing runs have
138
+ * probability (1-p)^N. Solving (1-p)^N = 0.05 gives the largest failure rate
139
+ * consistent with what we saw at 95% confidence — which is a far less
140
+ * flattering number than "N runs passed" sounds.
141
+ */
142
+ export function ruledOutFailureRate(runs) {
143
+ if (runs <= 0)
144
+ return 1;
145
+ return 1 - 0.05 ** (1 / runs);
146
+ }
147
+ function confidenceFor(runs, verdict) {
148
+ if (verdict === 'flaky') {
149
+ return {
150
+ confidence: 'high',
151
+ note: `Flakiness is observed, not inferred: both outcomes occurred within ${runs} runs.`,
152
+ };
153
+ }
154
+ const bound = Math.round(ruledOutFailureRate(runs) * 100);
155
+ const level = runs >= 5 ? 'high' : runs >= 3 ? 'moderate' : 'low';
156
+ const outcome = verdict === 'pass' ? 'passed' : 'failed';
157
+ return {
158
+ confidence: level,
159
+ note: `${runs} run${runs === 1 ? '' : 's'}, all ${outcome} consistently. That only rules out ` +
160
+ `intermittent behaviour more frequent than about 1 run in ${Math.max(2, Math.round(100 / bound))} ` +
161
+ `(${bound}%) at 95% confidence — re-run with a larger --repeat to tighten it.`,
162
+ };
163
+ }
164
+ /**
165
+ * Aggregate N runs of the same URL.
166
+ *
167
+ * `budget` comes from the runs themselves (they all share one), and only
168
+ * enforced keys become checks: an unenforced budget cannot be flaky.
169
+ */
170
+ export function analyzeFlake(reports) {
171
+ if (!reports.length)
172
+ throw new Error('analyzeFlake: needs at least one run');
173
+ const runs = reports.length;
174
+ const budget = reports[0].budget;
175
+ const checks = [];
176
+ for (const key of Object.keys(budget)) {
177
+ if (budget[key] === null)
178
+ continue;
179
+ const failed = reports.filter((r) => r.failures.some((f) => f.budget === key)).length;
180
+ checks.push({
181
+ key,
182
+ label: budgetLabel(key),
183
+ runs,
184
+ passed: runs - failed,
185
+ failed,
186
+ flakeRate: failed / runs,
187
+ stable: failed === 0 || failed === runs,
188
+ actuals: reports.map((r) => actualFor(key, r)),
189
+ });
190
+ }
191
+ const unstableChecks = checks.filter((c) => !c.stable);
192
+ const alwaysFailing = checks.filter((c) => c.failed === runs);
193
+ const verdict = unstableChecks.length
194
+ ? 'flaky'
195
+ : alwaysFailing.length
196
+ ? 'fail'
197
+ : 'pass';
198
+ const signals = collectSignals(reports);
199
+ const metrics = collectMetrics(reports);
200
+ const { confidence, note } = confidenceFor(runs, verdict);
201
+ let headline;
202
+ if (verdict === 'flaky') {
203
+ const worst = [...unstableChecks].sort((a, b) => b.failed - a.failed)[0];
204
+ headline =
205
+ `FLAKY — ${unstableChecks.length} check${unstableChecks.length === 1 ? '' : 's'} ` +
206
+ `changed outcome across ${runs} runs (e.g. ${worst.label} failed ${worst.failed} of ${runs}).`;
207
+ }
208
+ else if (verdict === 'fail') {
209
+ headline = `FAIL — ${alwaysFailing.length} check(s) failed in all ${runs} runs.`;
210
+ }
211
+ else {
212
+ const unstableMetrics = metrics.filter((m) => m.unstable).length;
213
+ headline =
214
+ `PASS — every check held across all ${runs} runs` +
215
+ (unstableMetrics ? `, though ${unstableMetrics} metric(s) varied widely.` : '.');
216
+ }
217
+ return {
218
+ runs,
219
+ verdict,
220
+ checks,
221
+ signals,
222
+ metrics,
223
+ confidence,
224
+ confidenceNote: note,
225
+ headline,
226
+ };
227
+ }
228
+ /** One line for a CI log / agent transcript. */
229
+ export function summarizeFlake(flake) {
230
+ return `${flake.headline} Confidence: ${flake.confidence}.`;
231
+ }
232
+ //# sourceMappingURL=flake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flake.js","sourceRoot":"","sources":["../../../src/report/flake.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Persistent run history for `monobrowse report` (RIG-13).
3
+ *
4
+ * Every run is appended to a per-URL directory under the monomind data dir,
5
+ * so the next run can say "LCP has crept up 400ms over nine runs" instead of
6
+ * reporting a number with no context. Deliberately not a database: one JSON
7
+ * file per run plus its screenshot is greppable, diffable, rsync-able, and
8
+ * survives this tool being uninstalled.
9
+ *
10
+ * ~/.monomind/browser-reports/
11
+ * shop.test-checkout-1f4c9a2b/
12
+ * url.txt <- the full URL, for humans
13
+ * 20260921T100000Z-8f2a1c4d.json <- HistoryRun
14
+ * 20260921T100000Z-8f2a1c4d.png <- main screenshot, for the diff
15
+ *
16
+ * Set `MONOBROWSE_HISTORY_DIR` to relocate the root (the tests do).
17
+ */
18
+ import type { ImageSize, Report, StructureNode, VerdictValue, VitalsData } from './types.js';
19
+ /** Runs kept per URL before the oldest are pruned. Override with --history-max. */
20
+ export declare const DEFAULT_HISTORY_MAX = 20;
21
+ export interface HistoryRun {
22
+ /** `<compact ISO timestamp>-<8 hex>`, also the basename of its files. */
23
+ id: string;
24
+ url: string;
25
+ finalUrl: string;
26
+ title: string;
27
+ capturedAt: string;
28
+ durationMs: number;
29
+ verdict: VerdictValue;
30
+ counts: Report['counts'];
31
+ vitals: VitalsData;
32
+ failures: Array<{
33
+ budget: string;
34
+ expected: string;
35
+ actual: string;
36
+ }>;
37
+ /** `<rule>@<locator>` per finding, so a11y regressions are attributable. */
38
+ a11ySignatures: string[];
39
+ structure: StructureNode[];
40
+ /** Basename of the sibling PNG, when one was archived. */
41
+ screenshotFile?: string;
42
+ screenshotSize?: ImageSize;
43
+ }
44
+ export declare function historyRoot(): string;
45
+ /**
46
+ * Directory name for a URL: readable prefix plus a hash of the full URL.
47
+ *
48
+ * The hash is what makes it correct — `?page=2` and `?page=3` must not share
49
+ * a history — and the prefix is what makes `ls` useful.
50
+ */
51
+ export declare function historyKey(url: string): string;
52
+ export declare function historyDirFor(url: string, root?: string): string;
53
+ export declare function compactTimestamp(iso: string): string;
54
+ export declare function newRunId(capturedAt: string): string;
55
+ /** The record we persist — a Report minus the megabytes of inline base64. */
56
+ export declare function toHistoryRun(report: Report, id: string): HistoryRun;
57
+ /**
58
+ * Every run for a URL, oldest first.
59
+ *
60
+ * A file that will not parse is skipped rather than thrown: a half-written
61
+ * record from a killed process must not permanently break the next report.
62
+ */
63
+ export declare function listRuns(dir: string): Promise<HistoryRun[]>;
64
+ /** Delete all but the newest `max` runs, taking each one's PNG with it. */
65
+ export declare function pruneHistory(dir: string, max: number): Promise<string[]>;
66
+ export interface SaveRunOptions {
67
+ root?: string;
68
+ max?: number;
69
+ /** Fixed id, for deterministic tests. */
70
+ id?: string;
71
+ }
72
+ export interface SaveRunResult {
73
+ dir: string;
74
+ file: string;
75
+ run: HistoryRun;
76
+ pruned: string[];
77
+ }
78
+ /**
79
+ * Append this run to its URL's history and prune the tail. Callers treat a
80
+ * rejection as non-fatal — a read-only home directory should cost you the
81
+ * trend section, not the report.
82
+ */
83
+ export declare function saveRun(report: Report, options?: SaveRunOptions): Promise<SaveRunResult>;
84
+ export declare function loadRunScreenshot(dir: string, run: HistoryRun): Promise<Uint8Array | null>;
85
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../../src/report/history.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7F,mFAAmF;AACnF,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAStC,MAAM,WAAW,UAAU;IACzB,yEAAyE;IACzE,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtE,4EAA4E;IAC5E,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED,wBAAgB,WAAW,IAAI,MAAM,CAIpC;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAY9C;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAgB,GAAG,MAAM,CAEvE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU,CAmBnE;AAID;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAiBjE;AAED,2EAA2E;AAC3E,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAc9E;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,UAAU,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CA4BxB;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAOhG"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Persistent run history for `monobrowse report` (RIG-13).
3
+ *
4
+ * Every run is appended to a per-URL directory under the monomind data dir,
5
+ * so the next run can say "LCP has crept up 400ms over nine runs" instead of
6
+ * reporting a number with no context. Deliberately not a database: one JSON
7
+ * file per run plus its screenshot is greppable, diffable, rsync-able, and
8
+ * survives this tool being uninstalled.
9
+ *
10
+ * ~/.monomind/browser-reports/
11
+ * shop.test-checkout-1f4c9a2b/
12
+ * url.txt <- the full URL, for humans
13
+ * 20260921T100000Z-8f2a1c4d.json <- HistoryRun
14
+ * 20260921T100000Z-8f2a1c4d.png <- main screenshot, for the diff
15
+ *
16
+ * Set `MONOBROWSE_HISTORY_DIR` to relocate the root (the tests do).
17
+ */
18
+ import { createHash, randomBytes } from 'node:crypto';
19
+ import { mkdir, readdir, readFile, rm, writeFile } from 'node:fs/promises';
20
+ import { homedir } from 'node:os';
21
+ import { join } from 'node:path';
22
+ import { pngFromDataUrl } from './png.js';
23
+ /** Runs kept per URL before the oldest are pruned. Override with --history-max. */
24
+ export const DEFAULT_HISTORY_MAX = 20;
25
+ /**
26
+ * Screenshots above this are not archived for the diff. A 30MB full-page PNG
27
+ * per run would turn a 20-run history into 600MB on someone's laptop, and the
28
+ * pixel diff is the only consumer.
29
+ */
30
+ const MAX_ARCHIVED_SCREENSHOT_BYTES = 8 * 1024 * 1024;
31
+ export function historyRoot() {
32
+ const override = process.env.MONOBROWSE_HISTORY_DIR;
33
+ if (override?.trim())
34
+ return override.trim();
35
+ return join(homedir(), '.monomind', 'browser-reports');
36
+ }
37
+ /**
38
+ * Directory name for a URL: readable prefix plus a hash of the full URL.
39
+ *
40
+ * The hash is what makes it correct — `?page=2` and `?page=3` must not share
41
+ * a history — and the prefix is what makes `ls` useful.
42
+ */
43
+ export function historyKey(url) {
44
+ const hash = createHash('sha256').update(url).digest('hex').slice(0, 8);
45
+ let readable;
46
+ try {
47
+ const parsed = new URL(url);
48
+ const path = parsed.pathname.replace(/\/+$/, '').replace(/[^a-z0-9]+/gi, '-');
49
+ readable = `${parsed.hostname}${path}`;
50
+ }
51
+ catch {
52
+ readable = url.replace(/[^a-z0-9]+/gi, '-');
53
+ }
54
+ readable = readable.replace(/-+/g, '-').replace(/^-|-$/g, '').toLowerCase().slice(0, 60);
55
+ return `${readable || 'page'}-${hash}`;
56
+ }
57
+ export function historyDirFor(url, root = historyRoot()) {
58
+ return join(root, historyKey(url));
59
+ }
60
+ export function compactTimestamp(iso) {
61
+ return iso.replace(/[-:]/g, '').replace(/\.\d+Z$/, 'Z');
62
+ }
63
+ export function newRunId(capturedAt) {
64
+ return `${compactTimestamp(capturedAt)}-${randomBytes(4).toString('hex')}`;
65
+ }
66
+ /** The record we persist — a Report minus the megabytes of inline base64. */
67
+ export function toHistoryRun(report, id) {
68
+ return {
69
+ id,
70
+ url: report.url,
71
+ finalUrl: report.finalUrl,
72
+ title: report.title,
73
+ capturedAt: report.capturedAt,
74
+ durationMs: report.durationMs,
75
+ verdict: report.verdict,
76
+ counts: report.counts,
77
+ vitals: report.vitals,
78
+ failures: report.failures.map((f) => ({
79
+ budget: String(f.budget),
80
+ expected: f.expected,
81
+ actual: f.actual,
82
+ })),
83
+ a11ySignatures: report.a11y.map((f) => `${f.rule}@${f.locator}`),
84
+ structure: report.structure ?? [],
85
+ };
86
+ }
87
+ const RUN_FILE = /^(\d{8}T\d{6}Z)-([0-9a-f]{8})\.json$/;
88
+ /**
89
+ * Every run for a URL, oldest first.
90
+ *
91
+ * A file that will not parse is skipped rather than thrown: a half-written
92
+ * record from a killed process must not permanently break the next report.
93
+ */
94
+ export async function listRuns(dir) {
95
+ let names;
96
+ try {
97
+ names = await readdir(dir);
98
+ }
99
+ catch {
100
+ return [];
101
+ }
102
+ const runs = [];
103
+ for (const name of names.filter((n) => RUN_FILE.test(n)).sort()) {
104
+ try {
105
+ const parsed = JSON.parse(await readFile(join(dir, name), 'utf8'));
106
+ if (parsed && typeof parsed.capturedAt === 'string')
107
+ runs.push(parsed);
108
+ }
109
+ catch {
110
+ // Unreadable record — ignore it and carry on.
111
+ }
112
+ }
113
+ return runs.sort((a, b) => a.capturedAt.localeCompare(b.capturedAt));
114
+ }
115
+ /** Delete all but the newest `max` runs, taking each one's PNG with it. */
116
+ export async function pruneHistory(dir, max) {
117
+ if (!Number.isFinite(max) || max <= 0)
118
+ return [];
119
+ const runs = await listRuns(dir);
120
+ if (runs.length <= max)
121
+ return [];
122
+ const doomed = runs.slice(0, runs.length - max);
123
+ const removed = [];
124
+ for (const run of doomed) {
125
+ for (const file of [`${run.id}.json`, run.screenshotFile]) {
126
+ if (!file)
127
+ continue;
128
+ await rm(join(dir, file), { force: true }).catch(() => { });
129
+ removed.push(file);
130
+ }
131
+ }
132
+ return removed;
133
+ }
134
+ /**
135
+ * Append this run to its URL's history and prune the tail. Callers treat a
136
+ * rejection as non-fatal — a read-only home directory should cost you the
137
+ * trend section, not the report.
138
+ */
139
+ export async function saveRun(report, options = {}) {
140
+ const root = options.root ?? historyRoot();
141
+ const dir = join(root, historyKey(report.url));
142
+ await mkdir(dir, { recursive: true });
143
+ await writeFile(join(dir, 'url.txt'), `${report.url}\n`, 'utf8').catch(() => { });
144
+ const id = options.id ?? newRunId(report.capturedAt);
145
+ const run = toHistoryRun(report, id);
146
+ const main = report.screenshots.find((s) => s.label === 'page') ?? report.screenshots[0];
147
+ if (main?.dataUrl) {
148
+ try {
149
+ const bytes = pngFromDataUrl(main.dataUrl);
150
+ if (bytes.length <= MAX_ARCHIVED_SCREENSHOT_BYTES) {
151
+ const file = `${id}.png`;
152
+ await writeFile(join(dir, file), bytes);
153
+ run.screenshotFile = file;
154
+ run.screenshotSize = { width: main.width, height: main.height };
155
+ }
156
+ }
157
+ catch {
158
+ // No archived screenshot means no pixel diff next run. Not fatal.
159
+ }
160
+ }
161
+ const file = join(dir, `${id}.json`);
162
+ await writeFile(file, `${JSON.stringify(run, null, 2)}\n`, 'utf8');
163
+ const pruned = await pruneHistory(dir, options.max ?? DEFAULT_HISTORY_MAX);
164
+ return { dir, file, run, pruned };
165
+ }
166
+ export async function loadRunScreenshot(dir, run) {
167
+ if (!run.screenshotFile)
168
+ return null;
169
+ try {
170
+ return new Uint8Array(await readFile(join(dir, run.screenshotFile)));
171
+ }
172
+ catch {
173
+ return null;
174
+ }
175
+ }
176
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../../src/report/history.ts"],"names":[],"mappings":"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"}